diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..fdd3f45e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.cr text eol=lf
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cdae9ab7..a8b4f2d0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -8,60 +8,194 @@ on:
env:
FORCE_COLOR: 1
- EARTHLY_CI: 'true'
- EARTHLY_ALLOW_PRIVILEGED: 'true'
+ LUCKY_ENV: test
jobs:
- specs:
+ check_format:
+ strategy:
+ fail-fast: false
runs-on: ubuntu-latest
+ continue-on-error: false
steps:
- - uses: earthly/actions-setup@v1
+ - uses: actions/checkout@v6
+ - uses: crystal-lang/install-crystal@v1
with:
- version: v0.8.0
- - uses: actions/checkout@v5
- - name: Run build
- run: |
- earthly +gh-action-essential
+ crystal: latest
+ - name: Install shards
+ run: shards install
+ - name: Format
+ run: crystal tool format --check
- platform-specs:
- needs: specs
+ platform_specs:
+ needs: check_format
strategy:
fail-fast: false
matrix:
include:
- - {os: macos-latest}
- - {os: windows-latest}
+ - { os: ubuntu-latest }
+ - { os: macos-latest }
+ - { os: windows-latest }
runs-on: ${{matrix.os}}
+ continue-on-error: false
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: crystal-lang/install-crystal@v1
with:
crystal: latest
- name: Install shards
run: shards install
- - name: Run specs
- run: crystal spec --tag "~integration"
+ - name: Run unit and integration specs
+ run: crystal spec spec/integration/ spec/unit/
- integration-specs:
- needs: specs
- runs-on: ubuntu-latest
+ # NOTE: These e2e specs will take a while to run
+ browser_with_auth:
+ needs: [check_format, platform_specs]
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - { os: ubuntu-latest }
+ - { os: macos-latest }
+ # - { os: windows-latest }
+ runs-on: ${{matrix.os}}
+ continue-on-error: false
steps:
- - uses: earthly/actions-setup@v1
+ - uses: actions/checkout@v6
+ - name: Setup PostgreSQL
+ uses: ikalnytskyi/action-setup-postgres@v8
+ with:
+ username: postgres
+ password: postgres
+ port: 5432
+ postgres-version: 18
+ - uses: actions/setup-node@v6
with:
- version: v0.8.0
- - uses: actions/checkout@v5
- - name: Run build
+ node-version: 24
+ - name: Enable Corepack (for yarn)
run: |
- earthly +gh-action-integration
+ corepack enable
+ corepack prepare yarn@1.22.22 --activate
+ yarn --version
+ - uses: crystal-lang/install-crystal@v1
+ with:
+ crystal: latest
+ - name: Install shards
+ run: shards install --skip-postinstall --skip-executables
+ - name: Install LuckyCLI
+ run: crystal build src/lucky.cr
+ - name: Add current directory to PATH
+ run: echo "$PWD" >> "$GITHUB_PATH"
+ - name: Set SHARDS_OVERRIDE
+ run: echo "SHARDS_OVERRIDE=${GITHUB_WORKSPACE}/shard.override.yml" >> "$GITHUB_ENV"
+ - name: Run e2e Browser app with authentication flow
+ run: crystal spec spec/end_to_end/browser_with_auth_spec.cr
- e2e-specs:
- needs: integration-specs
- runs-on: ubuntu-latest
+ browser_without_auth:
+ needs: [check_format, platform_specs]
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - { os: ubuntu-latest }
+ - { os: macos-latest }
+ # - { os: windows-latest }
+ runs-on: ${{matrix.os}}
+ continue-on-error: false
steps:
- - uses: earthly/actions-setup@v1
+ - uses: actions/checkout@v6
+ - name: Setup PostgreSQL
+ uses: ikalnytskyi/action-setup-postgres@v8
with:
- version: v0.8.0
- - uses: actions/checkout@v5
- - name: Run build
+ username: postgres
+ password: postgres
+ port: 5432
+ postgres-version: 18
+ - uses: actions/setup-node@v6
+ with:
+ node-version: 24
+ - name: Enable Corepack (for yarn)
run: |
- earthly +gh-action-e2e
+ corepack enable
+ corepack prepare yarn@1.22.22 --activate
+ yarn --version
+ - uses: crystal-lang/install-crystal@v1
+ with:
+ crystal: latest
+ - name: Install shards
+ run: shards install --skip-postinstall --skip-executables
+ - name: Install LuckyCLI
+ run: crystal build src/lucky.cr
+ - name: Add current directory to PATH
+ run: echo "$PWD" >> "$GITHUB_PATH"
+ - name: Set SHARDS_OVERRIDE
+ run: echo "SHARDS_OVERRIDE=${GITHUB_WORKSPACE}/shard.override.yml" >> "$GITHUB_ENV"
+ - name: Run e2e Browser app without authentication flow
+ run: crystal spec spec/end_to_end/browser_no_auth_spec.cr
+
+ api_with_auth:
+ needs: [check_format, platform_specs]
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - { os: ubuntu-latest }
+ - { os: macos-latest }
+ # - { os: windows-latest }
+ runs-on: ${{matrix.os}}
+ continue-on-error: false
+ steps:
+ - uses: actions/checkout@v6
+ - name: Setup PostgreSQL
+ uses: ikalnytskyi/action-setup-postgres@v8
+ with:
+ username: postgres
+ password: postgres
+ port: 5432
+ postgres-version: 18
+ - uses: crystal-lang/install-crystal@v1
+ with:
+ crystal: latest
+ - name: Install shards
+ run: shards install --skip-postinstall --skip-executables
+ - name: Install LuckyCLI
+ run: crystal build src/lucky.cr
+ - name: Add current directory to PATH
+ run: echo "$PWD" >> "$GITHUB_PATH"
+ - name: Set SHARDS_OVERRIDE
+ run: echo "SHARDS_OVERRIDE=${GITHUB_WORKSPACE}/shard.override.yml" >> "$GITHUB_ENV"
+ - name: Run e2e API app with authentication flow
+ run: crystal spec spec/end_to_end/api_with_auth_spec.cr
+
+ api_without_auth:
+ needs: [check_format, platform_specs]
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - { os: ubuntu-latest }
+ - { os: macos-latest }
+ # - { os: windows-latest }
+ runs-on: ${{matrix.os}}
+ continue-on-error: false
+ steps:
+ - uses: actions/checkout@v6
+ - name: Setup PostgreSQL
+ uses: ikalnytskyi/action-setup-postgres@v8
+ with:
+ username: postgres
+ password: postgres
+ port: 5432
+ postgres-version: 18
+ - uses: crystal-lang/install-crystal@v1
+ with:
+ crystal: latest
+ - name: Install shards
+ run: shards install --skip-postinstall --skip-executables
+ - name: Install LuckyCLI
+ run: crystal build src/lucky.cr -o lucky
+ - name: Add current directory to PATH
+ run: echo "$PWD" >> "$GITHUB_PATH"
+ - name: Set SHARDS_OVERRIDE
+ run: echo "SHARDS_OVERRIDE=${GITHUB_WORKSPACE}/shard.override.yml" >> "$GITHUB_ENV"
+ - name: Run e2e API app without authentication flow
+ run: crystal spec spec/end_to_end/api_no_auth_spec.cr
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index baad9eb9..e5f89e15 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -17,16 +17,12 @@ jobs:
runs-on: ubuntu-latest
env:
FORCE_COLOR: 1
- EARTHLY_CI: 'true'
steps:
- - uses: earthly/actions-setup@v1
- with:
- version: v0.8.0
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Build and package
run: |
mkdir -p bin
- earthly --artifact +release-static/lucky ./bin/lucky
+ # TODO: needs build step
sha256sum bin/lucky | awk '{print $1}' > ./bin/checksums.txt
tar -czvf lucky-$GITHUB_REF_NAME-linux-amd64.tar.gz -C ./bin .
- uses: actions/upload-artifact@v4
@@ -38,7 +34,7 @@ jobs:
build-windows-amd64:
runs-on: windows-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: crystal-lang/install-crystal@v1
- uses: ilammy/msvc-dev-cmd@v1
- name: Build and package
@@ -58,7 +54,7 @@ jobs:
- build-windows-amd64
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- uses: actions/download-artifact@v4
with:
path: artifacts
@@ -82,7 +78,7 @@ jobs:
needs: release
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Generate app token
id: generate-token
uses: actions/create-github-app-token@v2
@@ -108,7 +104,7 @@ jobs:
needs: release
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v5
+ - uses: actions/checkout@v6
- name: Generate app token
id: generate-token
uses: actions/create-github-app-token@v2
diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml
deleted file mode 100644
index ecf22998..00000000
--- a/.github/workflows/weekly.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: Lucky CLI Weekly CI
-
-on:
- schedule:
- - cron: "0 1 * * MON"
- workflow_dispatch:
-
-env:
- FORCE_COLOR: 1
- EARTHLY_CI: 'true'
- EARTHLY_ALLOW_PRIVILEGED: 'true'
-
-jobs:
- integration-specs:
- runs-on: ubuntu-latest
- steps:
- - uses: earthly/actions-setup@v1
- with:
- version: v0.8.0
- - uses: actions/checkout@v5
- - name: Run build
- run: |
- earthly +gh-action-weekly
-
- e2e-security-specs:
- runs-on: ubuntu-latest
- steps:
- - uses: earthly/actions-setup@v1
- with:
- version: v0.8.0
- - uses: actions/checkout@v5
- - name: Run build
- run: |
- earthly +gh-action-e2e-security
- env:
- EARTHLY_SECRETS: "BRIGHT_TOKEN=${{ secrets.BRIGHT_API_KEY }},BRIGHT_PROJECT_ID=${{ secrets.BRIGHT_PROJECT_ID }}"
- EARTHLY_BUILD_ARGS: "github_ref=${{ github.ref }},github_sha=${{ github.sha }},github_run_id=${{ github.run_id }}"
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..8e78515a
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,94 @@
+FROM crystallang/crystal:latest AS base
+WORKDIR /app
+
+RUN apt-get update \
+ && apt-get install -y postgresql-client ca-certificates curl gnupg libnss3 libnss3-dev wget \
+ && mkdir -p /etc/apt/keyrings \
+ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
+ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
+ && apt-get update \
+ && apt-get install -y nodejs \
+ && npm install --global yarn \
+ && wget -O /tmp/google-chrome-stable_current_amd64.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
+ && apt-get install -y /tmp/google-chrome-stable_current_amd64.deb
+
+ENV CHROME_BIN=/usr/bin/google-chrome
+ENV SHARDS_OVERRIDE=$(pwd)/shard.override.yml
+
+COPY shard.yml shard.lock ./
+RUN shards install --production
+
+COPY . .
+
+FROM base AS build
+RUN shards build lucky --without-development
+
+
+FROM build AS e2e_full_web
+RUN lucky init.custom test-project
+WORKDIR /workdir/test-project
+RUN crystal tool format --check src spec config
+RUN yarn install --no-progress \
+ && yarn dev \
+ && shards install
+RUN crystal build src/start_server.cr
+RUN crystal build src/test_project.cr
+RUN crystal run src/app.cr
+
+
+FROM build AS e2e_web_noauth
+RUN lucky init.custom test-project --no-auth
+WORKDIR /workdir/test-project
+RUN yarn install --no-progress \
+ && yarn dev \
+ && shards install
+RUN lucky gen.action.api Api::Users::Show \
+ && lucky gen.action.browser Users::Show \
+ && lucky gen.migration CreateThings \
+ && lucky gen.model User \
+ && lucky gen.page Users::IndexPage \
+ && lucky gen.component Users::Header \
+ && lucky gen.resource.browser Comment title:String \
+ && lucky gen.task email.monthly_update \
+ && lucky gen.secret_key
+RUN crystal tool format --check src spec config
+RUN crystal build src/start_server.cr
+RUN crystal build src/test_project.cr
+RUN crystal run src/app.cr
+
+
+FROM build AS e2e_full_api
+RUN lucky init.custom test-project --api
+WORKDIR /workdir/test-project
+RUN crystal tool format --check src spec config
+RUN shards install
+RUN crystal build src/start_server.cr
+RUN crystal build src/test_project.cr
+RUN crystal run src/app.cr
+
+
+FROM build AS e2e_api_noauth
+RUN lucky init.custom test-project --api --no-auth
+WORKDIR /workdir/test-project
+RUN crystal tool format --check src spec config
+RUN shards install
+RUN crystal build src/start_server.cr
+RUN crystal build src/test_project.cr
+RUN crystal run src/app.cr
+
+
+FROM build AS e2e_security
+ARG github_ref
+ARG github_sha
+ARG github_run_id
+RUN lucky init.custom test-project --with-sec-test
+WORKDIR /workdir/test-project
+RUN crystal tool format --check src spec config
+RUN yarn install --no-progress \
+ && yarn dev \
+ && shards install
+ENV LUCKY_ENV=test
+ENV RUN_SEC_TESTER_SPECS=1
+ENV GITHUB_REF=$github_ref
+ENV GITHUB_SHA=$github_sha
+ENV GITHUB_RUN_ID=$github_run_id
diff --git a/Earthfile b/Earthfile
deleted file mode 100644
index 928da24d..00000000
--- a/Earthfile
+++ /dev/null
@@ -1,301 +0,0 @@
-VERSION 0.8
-FROM 84codes/crystal:latest-ubuntu-24.04
-WORKDIR /workdir
-
-# gh-action-essential runs only the necessary recipes
-gh-action-essential:
- BUILD +format-check
- BUILD +specs
-
-# gh-action-integration runs all integration specs
-gh-action-integration:
- BUILD +integration-specs
-
-# gh-action-e2e runs all end-to-end specs
-gh-action-e2e:
- BUILD +e2e-full-web-app
- BUILD +e2e-full-web-app-noauth
- BUILD +e2e-full-web-app-api
- BUILD +e2e-full-web-app-api-noauth
-
-# gh-action-e2e-security runs all security tests (requires secrets)
-gh-action-e2e-security:
- BUILD +e2e-sec-tester
-
-# gh-action-weekly runs all weekly tests
-gh-action-weekly:
- BUILD +weekly-latest-full-web-app
- BUILD +weekly-nightly-full-web-app
-
-# format-check checks the format of source files
-format-check:
- FROM +base-image
- RUN crystal tool format --check src spec
-
-# specs runs unit tests
-specs:
- FROM +base-specs-image
- RUN crystal spec --tag "~integration"
-
-# update-snapshot updates spec fixtures
-update-snapshot:
- FROM +base-specs-image
- ARG spec
- ENV SPEC_UPDATE_SNAPSHOT=1
- RUN crystal spec --tag "~integration" $spec
- SAVE ARTIFACT ./fixtures AS LOCAL ./fixtures
-
-# lint runs ameba code linter
-# lint:
-# FROM ghcr.io/crystal-ameba/ameba:1.5.0
-# COPY --dir src ./
-# COPY --dir spec ./
-# RUN ameba
-
-# integration-specs runs integration tests
-integration-specs:
- FROM +base-image
- COPY +build-lucky/lucky /usr/bin/lucky
- COPY fixtures/hello_world.cr fixtures/
- COPY fixtures/hello_crystal.cr bin/lucky.hello_crystal.cr
- COPY fixtures/tasks.cr fixtures/
- RUN shards build lucky.hello_world --without-development
- RUN crystal spec --tag integration
-
-# e2e-full-web-app tests lucky full web app
-e2e-full-web-app:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+e2e-image
- RUN docker run --network=host lucky-image:latest
- END
-
-# e2e-full-web-app-noauth tests lucky full web app with no auth
-e2e-full-web-app-noauth:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+e2e-image-noauth
- RUN docker run --network=host lucky-image:latest
- END
-
-# e2e-full-web-app-api tests lucky full web app with api
-e2e-full-web-app-api:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+e2e-image-api
- RUN docker run --network=host lucky-image:latest
- END
-
-# e2e-full-web-app-api-noauth tests lucky full web app with api and no auth
-e2e-full-web-app-api-noauth:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+e2e-image-api-noauth
- RUN docker run --network=host lucky-image:latest
- END
-
-# e2e-sec-tester tests lucky full app with security tester enabled
-e2e-sec-tester:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+e2e-image-security
- RUN --secret BRIGHT_TOKEN --secret BRIGHT_PROJECT_ID -- \
- docker run \
- --network=host \
- -e BRIGHT_TOKEN \
- -e BRIGHT_PROJECT_ID \
- lucky-image:latest
- END
-
-# weekly-latest-full-web-app tests lucky full web app (crystal: latest) for catching potential issues on newer versions of packages
-weekly-latest-full-web-app:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+weekly-latest-image
- RUN docker run --network=host lucky-image:latest
- END
-
-# weekly-nightly-full-web-app tests lucky full web app (crystal: nightly) for more insight into upcoming crystal versions
-weekly-nightly-full-web-app:
- FROM earthly/dind:alpine
- COPY docker-compose.yml ./
- WITH DOCKER \
- --compose docker-compose.yml \
- --load lucky-image:latest=+weekly-nightly-image
- RUN docker run --network=host lucky-image:latest
- END
-
-# release-static builds an executable statically linked
-release-static:
- FROM 84codes/crystal:latest-alpine
- WORKDIR /workdir
- COPY --dir src ./
- COPY shard.yml ./
- RUN apk add yaml-static
- RUN shards build lucky --without-development --no-debug --release --static
- SAVE ARTIFACT ./bin/lucky
-
-build-lucky:
- WORKDIR /lucky_cli
- COPY --dir src ./
- COPY fixtures/hello_world.cr fixtures/
- COPY shard.yml ./
- RUN shards build lucky --without-development
- SAVE ARTIFACT ./bin/lucky
-
-base-image:
- COPY --dir src ./
- COPY --dir spec ./
- COPY shard.yml ./
-
-base-specs-image:
- FROM +base-image
- COPY --dir fixtures ./
- RUN shards install
-
-e2e-base-image:
- COPY shard.override.yml ./
- RUN apt-get update \
- && apt-get install -y postgresql-client ca-certificates curl gnupg libnss3 libnss3-dev wget \
- && mkdir -p /etc/apt/keyrings \
- && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
- && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
- && apt-get update \
- && apt-get install -y nodejs \
- && npm install --global yarn \
- && wget -O /tmp/google-chrome-stable_current_amd64.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
- && apt-get install -y /tmp/google-chrome-stable_current_amd64.deb
- ENV CHROME_BIN=/usr/bin/google-chrome
- ENV SHARDS_OVERRIDE=$(pwd)/shard.override.yml
- COPY +build-lucky/lucky /usr/bin/lucky
-
-e2e-image:
- FROM +e2e-base-image
- RUN lucky init.custom test-project
- WORKDIR /workdir/test-project
- RUN crystal tool format --check src spec config
- RUN yarn install --no-progress \
- && yarn dev \
- && shards install
- RUN crystal build src/start_server.cr
- RUN crystal build src/test_project.cr
- RUN crystal run src/app.cr
- ENTRYPOINT ["crystal", "spec"]
- SAVE IMAGE lucky-image:base
-
-e2e-image-noauth:
- FROM +e2e-base-image
- RUN lucky init.custom test-project --no-auth
- WORKDIR /workdir/test-project
- RUN yarn install --no-progress \
- && yarn dev \
- && shards install
- RUN lucky gen.action.api Api::Users::Show \
- && lucky gen.action.browser Users::Show \
- && lucky gen.migration CreateThings \
- && lucky gen.model User \
- && lucky gen.page Users::IndexPage \
- && lucky gen.component Users::Header \
- && lucky gen.resource.browser Comment title:String \
- && lucky gen.task email.monthly_update \
- && lucky gen.secret_key
- RUN crystal tool format --check src spec config
- RUN crystal build src/start_server.cr
- RUN crystal build src/test_project.cr
- RUN crystal run src/app.cr
- ENTRYPOINT ["crystal", "spec"]
- SAVE IMAGE lucky-image:noauth
-
-e2e-image-api:
- FROM +e2e-base-image
- RUN lucky init.custom test-project --api
- WORKDIR /workdir/test-project
- RUN crystal tool format --check src spec config
- RUN shards install
- RUN crystal build src/start_server.cr
- RUN crystal build src/test_project.cr
- RUN crystal run src/app.cr
- ENTRYPOINT ["crystal", "spec"]
- SAVE IMAGE lucky-image:api
-
-e2e-image-api-noauth:
- FROM +e2e-base-image
- RUN lucky init.custom test-project --api --no-auth
- WORKDIR /workdir/test-project
- RUN crystal tool format --check src spec config
- RUN shards install
- RUN crystal build src/start_server.cr
- RUN crystal build src/test_project.cr
- RUN crystal run src/app.cr
- ENTRYPOINT ["crystal", "spec"]
- SAVE IMAGE lucky-image:api-noauth
-
-e2e-image-security:
- FROM +e2e-base-image
- ARG github_ref
- ARG github_sha
- ARG github_run_id
- RUN lucky init.custom test-project --with-sec-test
- WORKDIR /workdir/test-project
- RUN crystal tool format --check src spec config
- RUN yarn install --no-progress \
- && yarn dev \
- && shards install
- ENV LUCKY_ENV=test
- ENV RUN_SEC_TESTER_SPECS=1
- ENV GITHUB_REF=$github_ref
- ENV GITHUB_SHA=$github_sha
- ENV GITHUB_RUN_ID=$github_run_id
- ENTRYPOINT ["crystal", "spec", "-Dwith_sec_tests"]
- SAVE IMAGE lucky-image:security
-
-weekly-latest-image:
- FROM 84codes/crystal:latest-ubuntu-24.04
- DO +WEEKLY_IMAGE --shard_file=shard.edge.yml
- SAVE IMAGE lucky-image:weekly-latest
-
-weekly-nightly-image:
- FROM 84codes/crystal:master-ubuntu-24.04
- DO +WEEKLY_IMAGE --shard_file=shard.override.yml
- SAVE IMAGE lucky-image:weekly-nightly
-
-WEEKLY_IMAGE:
- COMMAND
- ARG shard_file
- WORKDIR /workdir
- RUN apt-get update \
- && apt-get install -y postgresql-client ca-certificates curl gnupg libnss3 libnss3-dev wget \
- && mkdir -p /etc/apt/keyrings \
- && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
- && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list \
- && apt-get update \
- && apt-get install -y nodejs \
- && npm install --global yarn \
- && wget -O /tmp/google-chrome-stable_current_amd64.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \
- && apt-get install -y /tmp/google-chrome-stable_current_amd64.deb
- ENV CHROME_BIN=/usr/bin/google-chrome
- COPY +build-lucky/lucky /usr/bin/lucky
- RUN lucky init.custom test-project
- WORKDIR /workdir/test-project
- COPY $shard_file ./
- ENV SHARDS_OVERRIDE=/workdir/test-project/$shard_file
- RUN crystal tool format --check src spec config
- RUN yarn install --no-progress \
- && yarn dev \
- && shards install
- RUN crystal build src/start_server.cr
- RUN crystal build src/test_project.cr
- RUN crystal run src/app.cr
- ENTRYPOINT ["crystal", "spec"]
diff --git a/docker-compose.yml b/docker-compose.yml
index d919ffca..19844c51 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,18 +1,40 @@
-version: '3'
-
services:
- postgres:
- image: postgres:16
- restart: always
+ db:
+ image: postgres:16-alpine
environment:
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- TZ: "UTC"
+ POSTGRES_USER: lucky
+ POSTGRES_PASSWORD: developer
+ volumes:
+ - db:/var/lib/postgresql
+ networks:
+ - internal
ports:
- - 5432:5432
- hostname: postgres
+ - 5432
healthcheck:
test: ["CMD", "pg_isready"]
interval: 10s
timeout: 5s
retries: 5
+
+ app:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ environment:
+ SHARDS_CACHE_PATH: /data/.shards
+ DB_HOST: db
+ DB_USERNAME: lucky
+ DB_PASSWORD: developer
+ volumes:
+ - .:/data
+ command: sleep infinity
+ depends_on:
+ - db
+ networks:
+ - internal
+
+volumes:
+ db:
+
+networks:
+ internal:
diff --git a/fixtures/api_authentication_template/expected/spec/requests/api/me/show_spec.cr b/fixtures/api_authentication_template/expected/spec/requests/api/me/show_spec.cr
deleted file mode 100644
index 0e1f91fe..00000000
--- a/fixtures/api_authentication_template/expected/spec/requests/api/me/show_spec.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-require "../../../spec_helper"
-
-describe Api::Me::Show do
- it "returns the signed in user" do
- user = UserFactory.create
-
- response = ApiClient.auth(user).exec(Api::Me::Show)
-
- response.should send_json(200, email: user.email)
- end
-
- it "fails if not authenticated" do
- response = ApiClient.exec(Api::Me::Show)
-
- response.status_code.should eq(401)
- end
-end
diff --git a/fixtures/api_authentication_template/expected/spec/requests/api/sign_ins/create_spec.cr b/fixtures/api_authentication_template/expected/spec/requests/api/sign_ins/create_spec.cr
deleted file mode 100644
index 520c2dff..00000000
--- a/fixtures/api_authentication_template/expected/spec/requests/api/sign_ins/create_spec.cr
+++ /dev/null
@@ -1,33 +0,0 @@
-require "../../../spec_helper"
-
-describe Api::SignIns::Create do
- it "returns a token" do
- UserToken.stub_token("fake-token") do
- user = UserFactory.create
-
- response = ApiClient.exec(Api::SignIns::Create, user: valid_params(user))
-
- response.should send_json(200, token: "fake-token")
- end
- end
-
- it "returns an error if credentials are invalid" do
- user = UserFactory.create
- invalid_params = valid_params(user).merge(password: "incorrect")
-
- response = ApiClient.exec(Api::SignIns::Create, user: invalid_params)
-
- response.should send_json(
- 400,
- param: "password",
- details: "password is wrong"
- )
- end
-end
-
-private def valid_params(user : User)
- {
- email: user.email,
- password: "password",
- }
-end
diff --git a/fixtures/api_authentication_template/expected/spec/requests/api/sign_ups/create_spec.cr b/fixtures/api_authentication_template/expected/spec/requests/api/sign_ups/create_spec.cr
deleted file mode 100644
index 2a23542e..00000000
--- a/fixtures/api_authentication_template/expected/spec/requests/api/sign_ups/create_spec.cr
+++ /dev/null
@@ -1,34 +0,0 @@
-require "../../../spec_helper"
-
-describe Api::SignUps::Create do
- it "creates user on sign up" do
- UserToken.stub_token("fake-token") do
- response = ApiClient.exec(Api::SignUps::Create, user: valid_params)
-
- response.should send_json(200, token: "fake-token")
- new_user = UserQuery.first
- new_user.email.should eq(valid_params[:email])
- end
- end
-
- it "returns error for invalid params" do
- invalid_params = valid_params.merge(password_confirmation: "wrong")
-
- response = ApiClient.exec(Api::SignUps::Create, user: invalid_params)
-
- UserQuery.new.select_count.should eq(0)
- response.should send_json(
- 400,
- param: "password_confirmation",
- details: "password_confirmation must match"
- )
- end
-end
-
-private def valid_params
- {
- email: "test@email.com",
- password: "password",
- password_confirmation: "password",
- }
-end
diff --git a/fixtures/api_authentication_template/expected/src/actions/api/me/show.cr b/fixtures/api_authentication_template/expected/src/actions/api/me/show.cr
deleted file mode 100644
index 00602713..00000000
--- a/fixtures/api_authentication_template/expected/src/actions/api/me/show.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-class Api::Me::Show < ApiAction
- get "/api/me" do
- json UserSerializer.new(current_user)
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/actions/api/sign_ins/create.cr b/fixtures/api_authentication_template/expected/src/actions/api/sign_ins/create.cr
deleted file mode 100644
index 3670356c..00000000
--- a/fixtures/api_authentication_template/expected/src/actions/api/sign_ins/create.cr
+++ /dev/null
@@ -1,13 +0,0 @@
-class Api::SignIns::Create < ApiAction
- include Api::Auth::SkipRequireAuthToken
-
- post "/api/sign_ins" do
- SignInUser.run(params) do |operation, user|
- if user
- json({token: UserToken.generate(user)})
- else
- raise Avram::InvalidOperationError.new(operation)
- end
- end
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/actions/api/sign_ups/create.cr b/fixtures/api_authentication_template/expected/src/actions/api/sign_ups/create.cr
deleted file mode 100644
index 15bbd04b..00000000
--- a/fixtures/api_authentication_template/expected/src/actions/api/sign_ups/create.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-class Api::SignUps::Create < ApiAction
- include Api::Auth::SkipRequireAuthToken
-
- post "/api/sign_ups" do
- user = SignUpUser.create!(params)
- json({token: UserToken.generate(user)})
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/helpers.cr b/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/helpers.cr
deleted file mode 100644
index 6b51cb5a..00000000
--- a/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/helpers.cr
+++ /dev/null
@@ -1,28 +0,0 @@
-module Api::Auth::Helpers
- # The 'memoize' macro makes sure only one query is issued to find the user
- memoize def current_user? : User?
- auth_token.try do |value|
- user_from_auth_token(value)
- end
- end
-
- private def auth_token : String?
- bearer_token || token_param
- end
-
- private def bearer_token : String?
- context.request.headers["Authorization"]?
- .try(&.gsub("Bearer", ""))
- .try(&.strip)
- end
-
- private def token_param : String?
- params.get?(:auth_token)
- end
-
- private def user_from_auth_token(token : String) : User?
- UserToken.decode_user_id(token).try do |user_id|
- UserQuery.new.id(user_id).first?
- end
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/require_auth_token.cr b/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/require_auth_token.cr
deleted file mode 100644
index e018638f..00000000
--- a/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/require_auth_token.cr
+++ /dev/null
@@ -1,34 +0,0 @@
-module Api::Auth::RequireAuthToken
- macro included
- before require_auth_token
- end
-
- private def require_auth_token
- if current_user?
- continue
- else
- json auth_error_json, 401
- end
- end
-
- private def auth_error_json
- ErrorSerializer.new(
- message: "Not authenticated.",
- details: auth_error_details
- )
- end
-
- private def auth_error_details : String
- if auth_token
- "The provided authentication token was incorrect."
- else
- "An authentication token is required. Please include a token in an 'auth_token' param or 'Authorization' header."
- end
- end
-
- # Tells the compiler that the current_user is not nil since we have checked
- # that the user is signed in
- private def current_user : User
- current_user?.as(User)
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/skip_require_auth_token.cr b/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/skip_require_auth_token.cr
deleted file mode 100644
index 68098cf5..00000000
--- a/fixtures/api_authentication_template/expected/src/actions/mixins/api/auth/skip_require_auth_token.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-module Api::Auth::SkipRequireAuthToken
- macro included
- skip require_auth_token
- end
-
- # Since sign in is not required, current_user might be nil
- def current_user : User?
- current_user?
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/models/user_token.cr b/fixtures/api_authentication_template/expected/src/models/user_token.cr
deleted file mode 100644
index 65863032..00000000
--- a/fixtures/api_authentication_template/expected/src/models/user_token.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-# Generates and decodes JSON Web Tokens for Authenticating users.
-class UserToken
- Habitat.create { setting stubbed_token : String? }
- ALGORITHM = JWT::Algorithm::HS256
-
- def self.generate(user : User) : String
- payload = {"user_id" => user.id}
-
- settings.stubbed_token || create_token(payload)
- end
-
- def self.create_token(payload)
- JWT.encode(payload, Lucky::Server.settings.secret_key_base, ALGORITHM)
- end
-
- def self.decode_user_id(token : String) : Int64?
- payload, _header = JWT.decode(token, Lucky::Server.settings.secret_key_base, ALGORITHM)
- payload["user_id"].to_s.to_i64
- rescue e : JWT::Error
- Lucky::Log.dexter.error { {jwt_decode_error: e.message} }
- nil
- end
-
- # Used in tests to return a fake token to test against.
- def self.stub_token(token : String, &)
- temp_config(stubbed_token: token) do
- yield
- end
- end
-end
diff --git a/fixtures/api_authentication_template/expected/src/serializers/user_serializer.cr b/fixtures/api_authentication_template/expected/src/serializers/user_serializer.cr
deleted file mode 100644
index 1a86f14a..00000000
--- a/fixtures/api_authentication_template/expected/src/serializers/user_serializer.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-class UserSerializer < BaseSerializer
- def initialize(@user : User)
- end
-
- def render
- {email: @user.email}
- end
-end
diff --git a/fixtures/app_sec_tester_template/expected/spec/flows/security_spec.cr b/fixtures/app_sec_tester_template/expected/spec/flows/security_spec.cr
deleted file mode 100644
index 386a7d8c..00000000
--- a/fixtures/app_sec_tester_template/expected/spec/flows/security_spec.cr
+++ /dev/null
@@ -1,80 +0,0 @@
-{% skip_file unless flag?(:with_sec_tests) %}
-# Run these specs with `crystal spec -Dwith_sec_tests`
-
-require "../spec_helper"
-
-describe "SecTester" do
- it "tests the sign_in" do
- scanner = LuckySecTester.new
- target = scanner.build_target(SignIns::New)
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- tests: [
- "xss", # Testing for XSS Injection issues (https://docs.brightsec.com/docs/reflective-cross-site-scripting-rxss)
- "brute_force_login", # Testing for Brute Force on the Login (https://docs.brightsec.com/docs/brute-force-login)
- ],
- target: target
- )
- end
-
- it "tests the sign_in action with params" do
- scanner = LuckySecTester.new
- target = scanner.build_target(SignIns::Create) do |request|
- request.body = "user%3Aemail=test%40test.com&user%3Apassword=1234"
- end
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- tests: [
- "sqli", # Testing for SQL Injection issues (https://docs.brightsec.com/docs/sql-injection)
- "xss", # Testing for XSS Injection issues (https://docs.brightsec.com/docs/reflective-cross-site-scripting-rxss)
- "mass_assignment", # Testing for Mass Assignment (https://docs.brightsec.com/docs/mass-assignment)
- ],
- target: target
- )
- end
-
- it "tests the sign_up action" do
- scanner = LuckySecTester.new
- target = scanner.build_target(SignUps::Create) do |request|
- request.body = "user%3Aemail=aa%40aa.com&user%3Apassword=123456789&user%3Apassword_confirmation=123456789"
- end
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- tests: [
- "sqli", # Testing for SQL Injection issues (https://docs.brightsec.com/docs/sql-injection)
- "xss", # Testing for XSS Injection issues (https://docs.brightsec.com/docs/reflective-cross-site-scripting-rxss)
- "mass_assignment", # Testing for Mass Assignment issues (https://docs.brightsec.com/docs/mass-assignment)
- "full_path_disclosure", # Testing for full path disclourse on api error (https://docs.brightsec.com/docs/full-path-disclosure)
- ],
- target: target
- )
- end
- it "tests the home page general infra issues" do
- scanner = LuckySecTester.new
- target = scanner.build_target(Home::Index)
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- severity_threshold: SecTester::Severity::Medium,
- tests: [
- "header_security", # Testing for header security issues (https://docs.brightsec.com/docs/misconfigured-security-headers)
- "cookie_security", # Testing for Cookie Security issues (https://docs.brightsec.com/docs/sensitive-cookie-in-https-session-without-secure-attribute)
- "proto_pollution", # Testing for proto pollution based vulnerabilities (https://docs.brightsec.com/docs/prototype-pollution)
- "open_buckets", # Testing for open buckets (https://docs.brightsec.com/docs/open-bucket)
- ],
- target: target
- )
- end
-
- it "tests app.js for 3rd party issues" do
- scanner = LuckySecTester.new
- target = SecTester::Target.new(Lucky::RouteHelper.settings.base_uri + Lucky::AssetHelpers.asset("js/app.js"))
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- tests: [
- "retire_js", # Testing for 3rd party issues (https://docs.brightsec.com/docs/javascript-component-with-known-vulnerabilities)
- "cve_test", # Testing for known CVEs (https://docs.brightsec.com/docs/cves)
- ],
- target: target
- )
- end
-end
diff --git a/fixtures/app_sec_tester_template/expected/spec/setup/sec_tester.cr b/fixtures/app_sec_tester_template/expected/spec/setup/sec_tester.cr
deleted file mode 100644
index 850a1291..00000000
--- a/fixtures/app_sec_tester_template/expected/spec/setup/sec_tester.cr
+++ /dev/null
@@ -1,9 +0,0 @@
-require "lucky_sec_tester"
-
-# Signup for a `BRIGHT_TOKEN` at
-# [Bright Security](https://app.neuralegion.com/signup)
-# Read more about the SecTester on https://github.com/luckyframework/lucky_sec_tester
-LuckySecTester.configure do |setting|
- setting.bright_token = ENV["BRIGHT_TOKEN"]
- setting.project_id = ENV["BRIGHT_PROJECT_ID"]
-end
diff --git a/fixtures/app_sec_tester_template__browser/expected/spec/flows/security_spec.cr b/fixtures/app_sec_tester_template__browser/expected/spec/flows/security_spec.cr
deleted file mode 100644
index 6447f45d..00000000
--- a/fixtures/app_sec_tester_template__browser/expected/spec/flows/security_spec.cr
+++ /dev/null
@@ -1,35 +0,0 @@
-{% skip_file unless flag?(:with_sec_tests) %}
-# Run these specs with `crystal spec -Dwith_sec_tests`
-
-require "../spec_helper"
-
-describe "SecTester" do
- it "tests the home page general infra issues" do
- scanner = LuckySecTester.new
- target = scanner.build_target(Home::Index)
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- severity_threshold: SecTester::Severity::Medium,
- tests: [
- "header_security", # Testing for header security issues (https://docs.brightsec.com/docs/misconfigured-security-headers)
- "cookie_security", # Testing for Cookie Security issues (https://docs.brightsec.com/docs/sensitive-cookie-in-https-session-without-secure-attribute)
- "proto_pollution", # Testing for proto pollution based vulnerabilities (https://docs.brightsec.com/docs/prototype-pollution)
- "open_buckets", # Testing for open buckets (https://docs.brightsec.com/docs/open-bucket)
- ],
- target: target
- )
- end
-
- it "tests app.js for 3rd party issues" do
- scanner = LuckySecTester.new
- target = SecTester::Target.new(Lucky::RouteHelper.settings.base_uri + Lucky::AssetHelpers.asset("js/app.js"))
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- tests: [
- "retire_js", # Testing for 3rd party issues (https://docs.brightsec.com/docs/javascript-component-with-known-vulnerabilities)
- "cve_test", # Testing for known CVEs (https://docs.brightsec.com/docs/cves)
- ],
- target: target
- )
- end
-end
diff --git a/fixtures/app_sec_tester_template__browser/expected/spec/setup/sec_tester.cr b/fixtures/app_sec_tester_template__browser/expected/spec/setup/sec_tester.cr
deleted file mode 100644
index 850a1291..00000000
--- a/fixtures/app_sec_tester_template__browser/expected/spec/setup/sec_tester.cr
+++ /dev/null
@@ -1,9 +0,0 @@
-require "lucky_sec_tester"
-
-# Signup for a `BRIGHT_TOKEN` at
-# [Bright Security](https://app.neuralegion.com/signup)
-# Read more about the SecTester on https://github.com/luckyframework/lucky_sec_tester
-LuckySecTester.configure do |setting|
- setting.bright_token = ENV["BRIGHT_TOKEN"]
- setting.project_id = ENV["BRIGHT_PROJECT_ID"]
-end
diff --git a/fixtures/app_sec_tester_template__generate_auth/expected/spec/flows/security_spec.cr b/fixtures/app_sec_tester_template__generate_auth/expected/spec/flows/security_spec.cr
deleted file mode 100644
index 76dcf49c..00000000
--- a/fixtures/app_sec_tester_template__generate_auth/expected/spec/flows/security_spec.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-{% skip_file unless flag?(:with_sec_tests) %}
-# Run these specs with `crystal spec -Dwith_sec_tests`
-
-require "../spec_helper"
-
-describe "SecTester" do
- it "tests the sign_in API for SQLi, and JWT attacks" do
- scanner = LuckySecTester.new
- api_headers = HTTP::Headers{"Content-Type" => "application/json", "Accept" => "application/json"}
- target = scanner.build_target(Api::SignIns::Create, headers: api_headers) do |request|
- request.body = {"user" => {"email" => "aa@aa.com", "password" => "123456789"}}.to_json
- end
- scanner.run_check(
- scan_name: "ref: #{ENV["GITHUB_REF"]?} commit: #{ENV["GITHUB_SHA"]?} run id: #{ENV["GITHUB_RUN_ID"]?}",
- tests: [
- "sqli", # Testing for SQL Injection issues (https://docs.brightsec.com/docs/sql-injection)
- "jwt", # Testing JWT usage (https://docs.brightsec.com/docs/broken-jwt-authentication)
- "xss", # Testing for Cross Site Scripting attacks (https://docs.brightsec.com/docs/reflective-cross-site-scripting-rxss)
- "ssrf", # Testing for SSRF (https://docs.brightsec.com/docs/server-side-request-forgery-ssrf)
- "mass_assignment", # Testing for Mass Assignment issues (https://docs.brightsec.com/docs/mass-assignment)
- "full_path_disclosure", # Testing for full path disclourse on api error (https://docs.brightsec.com/docs/full-path-disclosure)
- ],
- target: target
- )
- end
-end
diff --git a/fixtures/app_sec_tester_template__generate_auth/expected/spec/setup/sec_tester.cr b/fixtures/app_sec_tester_template__generate_auth/expected/spec/setup/sec_tester.cr
deleted file mode 100644
index 850a1291..00000000
--- a/fixtures/app_sec_tester_template__generate_auth/expected/spec/setup/sec_tester.cr
+++ /dev/null
@@ -1,9 +0,0 @@
-require "lucky_sec_tester"
-
-# Signup for a `BRIGHT_TOKEN` at
-# [Bright Security](https://app.neuralegion.com/signup)
-# Read more about the SecTester on https://github.com/luckyframework/lucky_sec_tester
-LuckySecTester.configure do |setting|
- setting.bright_token = ENV["BRIGHT_TOKEN"]
- setting.project_id = ENV["BRIGHT_PROJECT_ID"]
-end
diff --git a/fixtures/app_sec_tester_template__no_browser_auth/expected/spec/flows/security_spec.cr b/fixtures/app_sec_tester_template__no_browser_auth/expected/spec/flows/security_spec.cr
deleted file mode 100644
index e5a8aace..00000000
--- a/fixtures/app_sec_tester_template__no_browser_auth/expected/spec/flows/security_spec.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-{% skip_file unless flag?(:with_sec_tests) %}
-# Run these specs with `crystal spec -Dwith_sec_tests`
-
-require "../spec_helper"
-
-describe "SecTester" do
-end
diff --git a/fixtures/app_sec_tester_template__no_browser_auth/expected/spec/setup/sec_tester.cr b/fixtures/app_sec_tester_template__no_browser_auth/expected/spec/setup/sec_tester.cr
deleted file mode 100644
index 850a1291..00000000
--- a/fixtures/app_sec_tester_template__no_browser_auth/expected/spec/setup/sec_tester.cr
+++ /dev/null
@@ -1,9 +0,0 @@
-require "lucky_sec_tester"
-
-# Signup for a `BRIGHT_TOKEN` at
-# [Bright Security](https://app.neuralegion.com/signup)
-# Read more about the SecTester on https://github.com/luckyframework/lucky_sec_tester
-LuckySecTester.configure do |setting|
- setting.bright_token = ENV["BRIGHT_TOKEN"]
- setting.project_id = ENV["BRIGHT_PROJECT_ID"]
-end
diff --git a/fixtures/base_authentication_src_template/expected/config/authentic.cr b/fixtures/base_authentication_src_template/expected/config/authentic.cr
deleted file mode 100644
index b9efc318..00000000
--- a/fixtures/base_authentication_src_template/expected/config/authentic.cr
+++ /dev/null
@@ -1,11 +0,0 @@
-require "./server"
-
-Authentic.configure do |settings|
- settings.secret_key = Lucky::Server.settings.secret_key_base
-
- unless LuckyEnv.production?
- # This value can be between 4 and 31
- fastest_encryption_possible = 4
- settings.encryption_cost = fastest_encryption_possible
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/db/migrations/.keep b/fixtures/base_authentication_src_template/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/base_authentication_src_template/expected/db/migrations/00000000000001_create_users.cr b/fixtures/base_authentication_src_template/expected/db/migrations/00000000000001_create_users.cr
deleted file mode 100644
index 96283bfa..00000000
--- a/fixtures/base_authentication_src_template/expected/db/migrations/00000000000001_create_users.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-class CreateUsers::V00000000000001 < Avram::Migrator::Migration::V1
- def migrate
- enable_extension "citext"
-
- create table_for(User) do
- primary_key id : Int64
- add_timestamps
- add email : String, unique: true, case_sensitive: false
- add encrypted_password : String
- end
- end
-
- def rollback
- drop table_for(User)
- disable_extension "citext"
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/spec/support/.keep b/fixtures/base_authentication_src_template/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/base_authentication_src_template/expected/spec/support/factories/user_factory.cr b/fixtures/base_authentication_src_template/expected/spec/support/factories/user_factory.cr
deleted file mode 100644
index bb837ee1..00000000
--- a/fixtures/base_authentication_src_template/expected/spec/support/factories/user_factory.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-class UserFactory < Avram::Factory
- def initialize
- email "#{sequence("test-email")}@example.com"
- encrypted_password Authentic.generate_encrypted_password("password")
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/models/user.cr b/fixtures/base_authentication_src_template/expected/src/models/user.cr
deleted file mode 100644
index 39729bb2..00000000
--- a/fixtures/base_authentication_src_template/expected/src/models/user.cr
+++ /dev/null
@@ -1,13 +0,0 @@
-class User < BaseModel
- include Carbon::Emailable
- include Authentic::PasswordAuthenticatable
-
- table do
- column email : String
- column encrypted_password : String
- end
-
- def emailable : Carbon::Address
- Carbon::Address.new(email)
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/.keep b/fixtures/base_authentication_src_template/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/mixins/.keep b/fixtures/base_authentication_src_template/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/mixins/password_validations.cr b/fixtures/base_authentication_src_template/expected/src/operations/mixins/password_validations.cr
deleted file mode 100644
index c56b9750..00000000
--- a/fixtures/base_authentication_src_template/expected/src/operations/mixins/password_validations.cr
+++ /dev/null
@@ -1,12 +0,0 @@
-module PasswordValidations
- macro included
- before_save run_password_validations
- end
-
- private def run_password_validations
- validate_required password, password_confirmation
- validate_confirmation_of password, with: password_confirmation
- # 72 is a limitation of BCrypt
- validate_size_of password, min: 6, max: 72
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/mixins/user_from_email.cr b/fixtures/base_authentication_src_template/expected/src/operations/mixins/user_from_email.cr
deleted file mode 100644
index 862fa9ac..00000000
--- a/fixtures/base_authentication_src_template/expected/src/operations/mixins/user_from_email.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-module UserFromEmail
- private def user_from_email : User?
- email.value.try do |value|
- UserQuery.new.email(value).first?
- end
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/request_password_reset.cr b/fixtures/base_authentication_src_template/expected/src/operations/request_password_reset.cr
deleted file mode 100644
index 4941aa7f..00000000
--- a/fixtures/base_authentication_src_template/expected/src/operations/request_password_reset.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-class RequestPasswordReset < Avram::Operation
- # You can modify this in src/operations/mixins/user_from_email.cr
- include UserFromEmail
-
- attribute email : String
-
- # Run validations and yield the operation and the user if valid
- def run
- user = user_from_email
- validate(user)
-
- if valid?
- user
- else
- nil
- end
- end
-
- def validate(user : User?)
- validate_required email
- if user.nil?
- email.add_error "is not in our system"
- end
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/reset_password.cr b/fixtures/base_authentication_src_template/expected/src/operations/reset_password.cr
deleted file mode 100644
index 3bdd3c89..00000000
--- a/fixtures/base_authentication_src_template/expected/src/operations/reset_password.cr
+++ /dev/null
@@ -1,11 +0,0 @@
-class ResetPassword < User::SaveOperation
- # Change password validations in src/operations/mixins/password_validations.cr
- include PasswordValidations
-
- attribute password : String
- attribute password_confirmation : String
-
- before_save do
- Authentic.copy_and_encrypt password, to: encrypted_password
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/sign_in_user.cr b/fixtures/base_authentication_src_template/expected/src/operations/sign_in_user.cr
deleted file mode 100644
index de80342e..00000000
--- a/fixtures/base_authentication_src_template/expected/src/operations/sign_in_user.cr
+++ /dev/null
@@ -1,40 +0,0 @@
-class SignInUser < Avram::Operation
- param_key :user
- # You can modify this in src/operations/mixins/user_from_email.cr
- include UserFromEmail
-
- attribute email : String
- attribute password : String
-
- # Run validations and yields the operation and the user if valid
- def run
- user = user_from_email
- validate_credentials(user)
-
- if valid?
- user
- else
- nil
- end
- end
-
- # `validate_credentials` determines if a user can sign in.
- #
- # If desired, you can add additional checks in this method, e.g.
- #
- # if user.locked?
- # email.add_error "is locked out"
- # end
- private def validate_credentials(user)
- if user
- unless Authentic.correct_password?(user, password.value.to_s)
- password.add_error "is wrong"
- end
- else
- # Usually ok to say that an email is not in the system:
- # https://kev.inburke.com/kevin/invalid-username-or-password-useless/
- # https://github.com/luckyframework/lucky_cli/issues/192
- email.add_error "is not in our system"
- end
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/operations/sign_up_user.cr b/fixtures/base_authentication_src_template/expected/src/operations/sign_up_user.cr
deleted file mode 100644
index 8c46fadc..00000000
--- a/fixtures/base_authentication_src_template/expected/src/operations/sign_up_user.cr
+++ /dev/null
@@ -1,14 +0,0 @@
-class SignUpUser < User::SaveOperation
- param_key :user
- # Change password validations in src/operations/mixins/password_validations.cr
- include PasswordValidations
-
- permit_columns email
- attribute password : String
- attribute password_confirmation : String
-
- before_save do
- validate_uniqueness_of email
- Authentic.copy_and_encrypt(password, to: encrypted_password) if password.valid?
- end
-end
diff --git a/fixtures/base_authentication_src_template/expected/src/queries/user_query.cr b/fixtures/base_authentication_src_template/expected/src/queries/user_query.cr
deleted file mode 100644
index 8a7e9a7f..00000000
--- a/fixtures/base_authentication_src_template/expected/src/queries/user_query.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-class UserQuery < User::BaseQuery
-end
diff --git a/fixtures/browser_authentication_src_template/expected/spec/flows/authentication_spec.cr b/fixtures/browser_authentication_src_template/expected/spec/flows/authentication_spec.cr
deleted file mode 100644
index cee71bcd..00000000
--- a/fixtures/browser_authentication_src_template/expected/spec/flows/authentication_spec.cr
+++ /dev/null
@@ -1,34 +0,0 @@
-require "../spec_helper"
-
-# NOTE: LuckyFlow specs are temporarily set to pending as of Lucky v1.4.0
-# This is due to race conditions in LuckyFlow.
-# Ref: https://github.com/luckyframework/lucky_cli/issues/883
-describe "Authentication flow", tags: "flow" do
- pending "works" do
- flow = AuthenticationFlow.new("test@example.com")
-
- flow.sign_up "password"
- flow.should_be_signed_in
- flow.sign_out
- flow.sign_in "wrong-password"
- flow.should_have_password_error
- flow.sign_in "password"
- flow.should_be_signed_in
- end
-
- # This is to show you how to sign in as a user during tests.
- # Use the `visit` method's `as` option in your tests to sign in as that user.
- #
- # Feel free to delete this once you have other tests using the 'as' option.
- pending "allows sign in through backdoor when testing" do
- user = UserFactory.create
- flow = BaseFlow.new
-
- flow.visit Me::Show, as: user
- should_be_signed_in(flow)
- end
-end
-
-private def should_be_signed_in(flow)
- flow.should have_element("@sign-out-button")
-end
diff --git a/fixtures/browser_authentication_src_template/expected/spec/flows/reset_password_spec.cr b/fixtures/browser_authentication_src_template/expected/spec/flows/reset_password_spec.cr
deleted file mode 100644
index 809a0322..00000000
--- a/fixtures/browser_authentication_src_template/expected/spec/flows/reset_password_spec.cr
+++ /dev/null
@@ -1,21 +0,0 @@
-require "../spec_helper"
-
-# NOTE: LuckyFlow specs are temporarily set to pending as of Lucky v1.4.0
-# This is due to race conditions in LuckyFlow.
-# Ref: https://github.com/luckyframework/lucky_cli/issues/883
-describe "Reset password flow", tags: "flow" do
- pending "works" do
- user = UserFactory.create
- flow = ResetPasswordFlow.new(user)
-
- flow.request_password_reset
- flow.should_have_sent_reset_email
- flow.reset_password "new-password"
- flow.should_be_signed_in
- flow.sign_out
- flow.sign_in "wrong-password"
- flow.should_have_password_error
- flow.sign_in "new-password"
- flow.should_be_signed_in
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/spec/support/.keep b/fixtures/browser_authentication_src_template/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_authentication_src_template/expected/spec/support/flows/authentication_flow.cr b/fixtures/browser_authentication_src_template/expected/spec/support/flows/authentication_flow.cr
deleted file mode 100644
index 183697f9..00000000
--- a/fixtures/browser_authentication_src_template/expected/spec/support/flows/authentication_flow.cr
+++ /dev/null
@@ -1,45 +0,0 @@
-class AuthenticationFlow < BaseFlow
- private getter email
-
- def initialize(@email : String)
- end
-
- def sign_up(password)
- visit SignUps::New
- fill_form SignUpUser,
- email: email,
- password: password,
- password_confirmation: password
- click "@sign-up-button"
- end
-
- def sign_out
- visit Me::Show
- sign_out_button.click
- end
-
- def sign_in(password)
- visit SignIns::New
- fill_form SignInUser,
- email: email,
- password: password
- click "@sign-in-button"
- end
-
- def should_be_signed_in
- current_page.should have_element("@sign-out-button")
- end
-
- def should_have_password_error
- current_page.should have_element("body", text: "Password is wrong")
- end
-
- private def sign_out_button
- el("@sign-out-button")
- end
-
- # NOTE: this is a shim for readability
- private def current_page
- self
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/spec/support/flows/reset_password_flow.cr b/fixtures/browser_authentication_src_template/expected/spec/support/flows/reset_password_flow.cr
deleted file mode 100644
index b1df7104..00000000
--- a/fixtures/browser_authentication_src_template/expected/spec/support/flows/reset_password_flow.cr
+++ /dev/null
@@ -1,42 +0,0 @@
-class ResetPasswordFlow < BaseFlow
- private getter user, authentication_flow
- delegate sign_in, sign_out, should_have_password_error, should_be_signed_in,
- to: authentication_flow
- delegate email, to: user
-
- def initialize(@user : User)
- @authentication_flow = AuthenticationFlow.new(user.email)
- end
-
- def request_password_reset
- with_fake_token do
- visit PasswordResetRequests::New
- fill_form RequestPasswordReset,
- email: email
- click "@request-password-reset-button"
- end
- end
-
- def should_have_sent_reset_email
- with_fake_token do
- user = UserQuery.new.email(email).first
- PasswordResetRequestEmail.new(user).should be_delivered
- end
- end
-
- def reset_password(password)
- user = UserQuery.new.email(email).first
- token = Authentic.generate_password_reset_token(user)
- visit PasswordResets::New.with(user.id, token)
- fill_form ResetPassword,
- password: password,
- password_confirmation: password
- click "@update-password-button"
- end
-
- private def with_fake_token(&)
- PasswordResetRequestEmail.temp_config(stubbed_token: "fake") do
- yield
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/me/show.cr b/fixtures/browser_authentication_src_template/expected/src/actions/me/show.cr
deleted file mode 100644
index 5e35848e..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/me/show.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-class Me::Show < BrowserAction
- get "/me" do
- html ShowPage
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/.keep b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/allow_guests.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/allow_guests.cr
deleted file mode 100644
index 3961399b..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/allow_guests.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-module Auth::AllowGuests
- macro included
- skip require_sign_in
- end
-
- # Since sign in is not required, current_user might be nil
- def current_user : User?
- current_user?
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/base.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/base.cr
deleted file mode 100644
index 77166a97..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/base.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-module Auth::PasswordResets::Base
- macro included
- include Auth::RedirectSignedInUsers
- include Auth::PasswordResets::FindUser
- include Auth::PasswordResets::RequireToken
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/find_user.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/find_user.cr
deleted file mode 100644
index cab02d5c..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/find_user.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-module Auth::PasswordResets::FindUser
- private def user : User
- UserQuery.find(user_id)
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/require_token.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/require_token.cr
deleted file mode 100644
index 15da4238..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/require_token.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-module Auth::PasswordResets::RequireToken
- macro included
- before require_valid_password_reset_token
- end
-
- abstract def token : String
- abstract def user : User
-
- private def require_valid_password_reset_token
- if Authentic.valid_password_reset_token?(user, token)
- continue
- else
- flash.failure = "The password reset link is incorrect or expired. Please try again."
- redirect to: PasswordResetRequests::New
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/token_from_session.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/token_from_session.cr
deleted file mode 100644
index 820b91bc..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/password_resets/token_from_session.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-module Auth::PasswordResets::TokenFromSession
- private def token : String
- session.get?(:password_reset_token) || raise "Password reset token not found in session"
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/redirect_signed_in_users.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/redirect_signed_in_users.cr
deleted file mode 100644
index 546bf7bb..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/redirect_signed_in_users.cr
+++ /dev/null
@@ -1,19 +0,0 @@
-module Auth::RedirectSignedInUsers
- macro included
- include Auth::AllowGuests
- before redirect_signed_in_users
- end
-
- private def redirect_signed_in_users
- if current_user?
- flash.success = "You are already signed in"
- redirect to: Home::Index
- else
- continue
- end
- end
-
- # current_user returns nil because signed in users are redirected.
- def current_user
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/require_sign_in.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/require_sign_in.cr
deleted file mode 100644
index 27a6f5ea..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/require_sign_in.cr
+++ /dev/null
@@ -1,21 +0,0 @@
-module Auth::RequireSignIn
- macro included
- before require_sign_in
- end
-
- private def require_sign_in
- if current_user?
- continue
- else
- Authentic.remember_requested_path(self)
- flash.info = "Please sign in first"
- redirect to: SignIns::New
- end
- end
-
- # Tells the compiler that the current_user is not nil since we have checked
- # that the user is signed in
- private def current_user : User
- current_user?.as(User)
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/test_backdoor.cr b/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/test_backdoor.cr
deleted file mode 100644
index 68c9d91a..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/mixins/auth/test_backdoor.cr
+++ /dev/null
@@ -1,13 +0,0 @@
-module Auth::TestBackdoor
- macro included
- before test_backdoor
- end
-
- private def test_backdoor
- if LuckyEnv.test? && (user_id = params.get?(:backdoor_user_id))
- user = UserQuery.find(user_id)
- sign_in user
- end
- continue
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/password_reset_requests/create.cr b/fixtures/browser_authentication_src_template/expected/src/actions/password_reset_requests/create.cr
deleted file mode 100644
index 8f3c5130..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/password_reset_requests/create.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-class PasswordResetRequests::Create < BrowserAction
- include Auth::RedirectSignedInUsers
-
- post "/password_reset_requests" do
- RequestPasswordReset.run(params) do |operation, user|
- if user
- PasswordResetRequestEmail.new(user).deliver
- flash.success = "You should receive an email on how to reset your password shortly"
- redirect SignIns::New
- else
- html NewPage, operation: operation
- end
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/password_reset_requests/new.cr b/fixtures/browser_authentication_src_template/expected/src/actions/password_reset_requests/new.cr
deleted file mode 100644
index 7d16a7dd..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/password_reset_requests/new.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-class PasswordResetRequests::New < BrowserAction
- include Auth::RedirectSignedInUsers
-
- get "/password_reset_requests/new" do
- html NewPage, operation: RequestPasswordReset.new
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/create.cr b/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/create.cr
deleted file mode 100644
index da1e711b..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/create.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-class PasswordResets::Create < BrowserAction
- include Auth::PasswordResets::Base
- include Auth::PasswordResets::TokenFromSession
-
- post "/password_resets/:user_id" do
- ResetPassword.update(user, params) do |operation, user|
- if operation.saved?
- session.delete(:password_reset_token)
- sign_in user
- flash.success = "Your password has been reset"
- redirect to: Home::Index
- else
- html NewPage, operation: operation, user_id: user_id.to_i64
- end
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/edit.cr b/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/edit.cr
deleted file mode 100644
index 9408109c..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/edit.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-class PasswordResets::Edit < BrowserAction
- include Auth::PasswordResets::Base
- include Auth::PasswordResets::TokenFromSession
-
- get "/password_resets/:user_id/edit" do
- html NewPage, operation: ResetPassword.new, user_id: user_id.to_i64
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/new.cr b/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/new.cr
deleted file mode 100644
index 55034686..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/password_resets/new.cr
+++ /dev/null
@@ -1,20 +0,0 @@
-class PasswordResets::New < BrowserAction
- include Auth::PasswordResets::Base
-
- param token : String
-
- get "/password_resets/:user_id" do
- redirect_to_edit_form_without_token_param
- end
-
- # This is to prevent password reset tokens from being scraped in the HTTP Referer header
- # See more info here: https://github.com/thoughtbot/clearance/pull/707
- private def redirect_to_edit_form_without_token_param
- make_token_available_to_future_actions
- redirect to: PasswordResets::Edit.with(user_id)
- end
-
- private def make_token_available_to_future_actions
- session.set(:password_reset_token, token)
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/create.cr b/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/create.cr
deleted file mode 100644
index af225888..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/create.cr
+++ /dev/null
@@ -1,16 +0,0 @@
-class SignIns::Create < BrowserAction
- include Auth::RedirectSignedInUsers
-
- post "/sign_in" do
- SignInUser.run(params) do |operation, authenticated_user|
- if authenticated_user
- sign_in(authenticated_user)
- flash.success = "You're now signed in"
- Authentic.redirect_to_originally_requested_path(self, fallback: Home::Index)
- else
- flash.failure = "Sign in failed"
- html NewPage, operation: operation
- end
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/delete.cr b/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/delete.cr
deleted file mode 100644
index 8d34612f..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/delete.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-class SignIns::Delete < BrowserAction
- delete "/sign_out" do
- sign_out
- flash.info = "You have been signed out"
- redirect to: SignIns::New
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/new.cr b/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/new.cr
deleted file mode 100644
index 3275b40f..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ins/new.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-class SignIns::New < BrowserAction
- include Auth::RedirectSignedInUsers
-
- get "/sign_in" do
- html NewPage, operation: SignInUser.new
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ups/create.cr b/fixtures/browser_authentication_src_template/expected/src/actions/sign_ups/create.cr
deleted file mode 100644
index a291ca68..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ups/create.cr
+++ /dev/null
@@ -1,16 +0,0 @@
-class SignUps::Create < BrowserAction
- include Auth::RedirectSignedInUsers
-
- post "/sign_up" do
- SignUpUser.create(params) do |operation, user|
- if user
- flash.info = "Thanks for signing up"
- sign_in(user)
- redirect to: Home::Index
- else
- flash.info = "Couldn't sign you up"
- html NewPage, operation: operation
- end
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ups/new.cr b/fixtures/browser_authentication_src_template/expected/src/actions/sign_ups/new.cr
deleted file mode 100644
index 2299df6e..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/actions/sign_ups/new.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-class SignUps::New < BrowserAction
- include Auth::RedirectSignedInUsers
-
- get "/sign_up" do
- html NewPage, operation: SignUpUser.new
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/emails/password_reset_request_email.cr b/fixtures/browser_authentication_src_template/expected/src/emails/password_reset_request_email.cr
deleted file mode 100644
index a41c8ba1..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/emails/password_reset_request_email.cr
+++ /dev/null
@@ -1,13 +0,0 @@
-class PasswordResetRequestEmail < BaseEmail
- Habitat.create { setting stubbed_token : String? }
- delegate stubbed_token, to: :settings
-
- def initialize(@user : User)
- @token = stubbed_token || Authentic.generate_password_reset_token(@user)
- end
-
- to @user
- from "myapp@support.com" # or set a default in src/emails/base_email.cr
- subject "Reset your password"
- templates html, text
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/emails/templates/password_reset_request_email/html.ecr b/fixtures/browser_authentication_src_template/expected/src/emails/templates/password_reset_request_email/html.ecr
deleted file mode 100644
index 00c24fc9..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/emails/templates/password_reset_request_email/html.ecr
+++ /dev/null
@@ -1,3 +0,0 @@
-
Please reset your password
-
-Reset password
diff --git a/fixtures/browser_authentication_src_template/expected/src/emails/templates/password_reset_request_email/text.ecr b/fixtures/browser_authentication_src_template/expected/src/emails/templates/password_reset_request_email/text.ecr
deleted file mode 100644
index 7a7a0ab7..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/emails/templates/password_reset_request_email/text.ecr
+++ /dev/null
@@ -1,3 +0,0 @@
-Please reset your password:
-
-<%= PasswordResets::New.url(@user.id, @token) %>
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/auth_layout.cr b/fixtures/browser_authentication_src_template/expected/src/pages/auth_layout.cr
deleted file mode 100644
index c2ac1b09..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/auth_layout.cr
+++ /dev/null
@@ -1,27 +0,0 @@
-abstract class AuthLayout
- include Lucky::HTMLPage
-
- abstract def content
- abstract def page_title
-
- # The default page title. It is passed to `Shared::LayoutHead`.
- #
- # Add a `page_title` method to pages to override it. You can also remove
- # This method so every page is required to have its own page title.
- def page_title
- "Welcome"
- end
-
- def render
- html_doctype
-
- html lang: "en" do
- mount Shared::LayoutHead, page_title: page_title
-
- body do
- mount Shared::FlashMessages, context.flash
- content
- end
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/main_layout.cr b/fixtures/browser_authentication_src_template/expected/src/pages/main_layout.cr
deleted file mode 100644
index 06a1ed7a..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/main_layout.cr
+++ /dev/null
@@ -1,45 +0,0 @@
-abstract class MainLayout
- include Lucky::HTMLPage
-
- # 'needs current_user : User' makes it so that the current_user
- # is always required for pages using MainLayout
- needs current_user : User
-
- abstract def content
- abstract def page_title
-
- # MainLayout defines a default 'page_title'.
- #
- # Add a 'page_title' method to your indivual pages to customize each page's
- # title.
- #
- # Or, if you want to require every page to set a title, change the
- # 'page_title' method in this layout to:
- #
- # abstract def page_title : String
- #
- # This will force pages to define their own 'page_title' method.
- def page_title
- "Welcome"
- end
-
- def render
- html_doctype
-
- html lang: "en" do
- mount Shared::LayoutHead, page_title: page_title
-
- body do
- mount Shared::FlashMessages, context.flash
- render_signed_in_user
- content
- end
- end
- end
-
- private def render_signed_in_user
- text current_user.email
- text " - "
- link "Sign out", to: SignIns::Delete, flow_id: "sign-out-button"
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/me/show_page.cr b/fixtures/browser_authentication_src_template/expected/src/pages/me/show_page.cr
deleted file mode 100644
index 6a6bd879..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/me/show_page.cr
+++ /dev/null
@@ -1,21 +0,0 @@
-class Me::ShowPage < MainLayout
- def content
- h1 "This is your profile"
- h3 "Email: #{@current_user.email}"
- helpful_tips
- end
-
- private def helpful_tips
- h3 "Next, you may want to:"
- ul do
- li { link_to_authentication_guides }
- li "Modify this page: src/pages/me/show_page.cr"
- li "Change where you go after sign in: src/actions/home/index.cr"
- end
- end
-
- private def link_to_authentication_guides
- a "Check out the authentication guides",
- href: "https://luckyframework.org/guides/authentication"
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/password_reset_requests/new_page.cr b/fixtures/browser_authentication_src_template/expected/src/pages/password_reset_requests/new_page.cr
deleted file mode 100644
index 368784c9..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/password_reset_requests/new_page.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-class PasswordResetRequests::NewPage < AuthLayout
- needs operation : RequestPasswordReset
-
- def content
- h1 "Reset your password"
- render_form(@operation)
- end
-
- private def render_form(op)
- form_for PasswordResetRequests::Create do
- mount Shared::Field, attribute: op.email, label_text: "Email", &.email_input
- submit "Reset Password", flow_id: "request-password-reset-button"
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/password_resets/new_page.cr b/fixtures/browser_authentication_src_template/expected/src/pages/password_resets/new_page.cr
deleted file mode 100644
index 16a6635e..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/password_resets/new_page.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-class PasswordResets::NewPage < AuthLayout
- needs operation : ResetPassword
- needs user_id : Int64
-
- def content
- h1 "Reset your password"
- render_password_reset_form(@operation)
- end
-
- private def render_password_reset_form(op)
- form_for PasswordResets::Create.with(@user_id) do
- mount Shared::Field, attribute: op.password, label_text: "Password", &.password_input(autofocus: "true")
- mount Shared::Field, attribute: op.password_confirmation, label_text: "Confirm Password", &.password_input
-
- submit "Update Password", flow_id: "update-password-button"
- end
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/sign_ins/new_page.cr b/fixtures/browser_authentication_src_template/expected/src/pages/sign_ins/new_page.cr
deleted file mode 100644
index 10188135..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/sign_ins/new_page.cr
+++ /dev/null
@@ -1,23 +0,0 @@
-class SignIns::NewPage < AuthLayout
- needs operation : SignInUser
-
- def content
- h1 "Sign In"
- render_sign_in_form(@operation)
- end
-
- private def render_sign_in_form(op)
- form_for SignIns::Create do
- sign_in_fields(op)
- submit "Sign In", flow_id: "sign-in-button"
- end
- link "Reset password", to: PasswordResetRequests::New
- text " | "
- link "Sign up", to: SignUps::New
- end
-
- private def sign_in_fields(op)
- mount Shared::Field, attribute: op.email, label_text: "Email", &.email_input(autofocus: "true")
- mount Shared::Field, attribute: op.password, label_text: "Password", &.password_input
- end
-end
diff --git a/fixtures/browser_authentication_src_template/expected/src/pages/sign_ups/new_page.cr b/fixtures/browser_authentication_src_template/expected/src/pages/sign_ups/new_page.cr
deleted file mode 100644
index 24f6cb25..00000000
--- a/fixtures/browser_authentication_src_template/expected/src/pages/sign_ups/new_page.cr
+++ /dev/null
@@ -1,22 +0,0 @@
-class SignUps::NewPage < AuthLayout
- needs operation : SignUpUser
-
- def content
- h1 "Sign Up"
- render_sign_up_form(@operation)
- end
-
- private def render_sign_up_form(op)
- form_for SignUps::Create do
- sign_up_fields(op)
- submit "Sign Up", flow_id: "sign-up-button"
- end
- link "Sign in instead", to: SignIns::New
- end
-
- private def sign_up_fields(op)
- mount Shared::Field, attribute: op.email, label_text: "Email", &.email_input(autofocus: "true")
- mount Shared::Field, attribute: op.password, label_text: "Password", &.password_input
- mount Shared::Field, attribute: op.password_confirmation, label_text: "Confirm Password", &.password_input
- end
-end
diff --git a/fixtures/browser_src_template/expected/config/html_page.cr b/fixtures/browser_src_template/expected/config/html_page.cr
deleted file mode 100644
index dca168e5..00000000
--- a/fixtures/browser_src_template/expected/config/html_page.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Lucky::HTMLPage.configure do |settings|
- settings.render_component_comments = !LuckyEnv.production?
-end
diff --git a/fixtures/browser_src_template/expected/db/migrations/.keep b/fixtures/browser_src_template/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/package.json b/fixtures/browser_src_template/expected/package.json
deleted file mode 100644
index 3a64c995..00000000
--- a/fixtures/browser_src_template/expected/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "license": "UNLICENSED",
- "private": true,
- "type": "module",
- "dependencies": {
- "@rails/ujs": "^7.1.0",
- "modern-normalize": "^2.0.0"
- },
- "scripts": {
- "heroku-postbuild": "yarn build",
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview",
- "watch": "vite build --watch"
- },
- "devDependencies": {
- "sass": "^1.69.5",
- "vite": "^5.0.0",
- "vite-plugin-compression": "^0.5.1",
- "vite-plugin-dev-manifest": "^1.2.1"
- }
-}
\ No newline at end of file
diff --git a/fixtures/browser_src_template/expected/public/assets/images/.keep b/fixtures/browser_src_template/expected/public/assets/images/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/public/favicon.ico b/fixtures/browser_src_template/expected/public/favicon.ico
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/public/robots.txt b/fixtures/browser_src_template/expected/public/robots.txt
deleted file mode 100644
index 12009050..00000000
--- a/fixtures/browser_src_template/expected/public/robots.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# Learn more about robots.txt: https://www.robotstxt.org/robotstxt.html
-User-agent: *
-# 'Disallow' with an empty value allows all paths to be crawled
-Disallow:
diff --git a/fixtures/browser_src_template/expected/spec/flows/.keep b/fixtures/browser_src_template/expected/spec/flows/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/spec/setup/.keep b/fixtures/browser_src_template/expected/spec/setup/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/spec/setup/configure_lucky_flow.cr b/fixtures/browser_src_template/expected/spec/setup/configure_lucky_flow.cr
deleted file mode 100644
index 504a3d34..00000000
--- a/fixtures/browser_src_template/expected/spec/setup/configure_lucky_flow.cr
+++ /dev/null
@@ -1,37 +0,0 @@
-# For more detailed documentation, visit
-# https://luckyframework.org/guides/testing/html-and-interactivity
-
-LuckyFlow.configure do |settings|
- settings.stop_retrying_after = 200.milliseconds
- settings.base_uri = Lucky::RouteHelper.settings.base_uri
-
- # LuckyFlow will install the chromedriver for you located in
- # ~./webdrivers/. Uncomment this to point to a specific driver
- # settings.driver_path = "/path/to/specific/chromedriver"
-end
-
-# By default, LuckyFlow is set in "headless" mode (no browser window shown).
-# Uncomment this to enable running `LuckyFlow` in a Google Chrome window instead.
-# Be sure to disable for CI.
-#
-# LuckyFlow.default_driver = "chrome"
-
-# LuckyFlow uses a registry for each driver. By default, chrome, and headless_chrome
-# are available. If you'd like to register your own custom driver, you can register
-# it here.
-#
-# LuckyFlow::Registry.register :firefox do
-# # add your custom driver here
-# end
-
-# Setup specs to allow you to change the driver on the fly
-# per spec by setting a tag on specific specs. Requires the
-# driver to be registered through `LuckyFlow::Registry` first.
-#
-# ```
-# it "uses headless_chrome" do
-# end
-# it "uses webless", tags: "webless" do
-# end
-# ```
-LuckyFlow::Spec.setup
diff --git a/fixtures/browser_src_template/expected/spec/support/.keep b/fixtures/browser_src_template/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/spec/support/factories/.keep b/fixtures/browser_src_template/expected/spec/support/factories/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/spec/support/flows/base_flow.cr b/fixtures/browser_src_template/expected/spec/support/flows/base_flow.cr
deleted file mode 100644
index 93709b25..00000000
--- a/fixtures/browser_src_template/expected/spec/support/flows/base_flow.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-# Add methods that all or most Flows need to share
-class BaseFlow < LuckyFlow
-end
diff --git a/fixtures/browser_src_template/expected/src/actions/browser_action.cr b/fixtures/browser_src_template/expected/src/actions/browser_action.cr
deleted file mode 100644
index 674f2088..00000000
--- a/fixtures/browser_src_template/expected/src/actions/browser_action.cr
+++ /dev/null
@@ -1,45 +0,0 @@
-abstract class BrowserAction < Lucky::Action
- include Lucky::ProtectFromForgery
-
- # By default all actions are required to use underscores.
- # Add `include Lucky::SkipRouteStyleCheck` to your actions if you wish to ignore this check for specific routes.
- include Lucky::EnforceUnderscoredRoute
-
- # This module disables Google FLoC by setting the
- # [Permissions-Policy](https://github.com/WICG/floc) HTTP header to `interest-cohort=()`.
- #
- # This header is a part of Google's Federated Learning of Cohorts (FLoC) which is used
- # to track browsing history instead of using 3rd-party cookies.
- #
- # Remove this include if you want to use the FLoC tracking.
- include Lucky::SecureHeaders::DisableFLoC
-
- accepted_formats [:html, :json], default: :html
-
- # This module provides current_user, sign_in, and sign_out methods
- include Authentic::ActionHelpers(User)
-
- # When testing you can skip normal sign in by using `visit` with the `as` param
- #
- # flow.visit Me::Show, as: UserFactory.create
- include Auth::TestBackdoor
-
- # By default all actions that inherit 'BrowserAction' require sign in.
- #
- # You can remove the 'include Auth::RequireSignIn' below to allow anyone to
- # access actions that inherit from 'BrowserAction' or you can
- # 'include Auth::AllowGuests' in individual actions to skip sign in.
- include Auth::RequireSignIn
-
- # `expose` means that `current_user` will be passed to pages automatically.
- #
- # In default Lucky apps, the `MainLayout` declares it `needs current_user : User`
- # so that any page that inherits from MainLayout can use the `current_user`
- expose current_user
-
- # This method tells Authentic how to find the current user
- # The 'memoize' macro makes sure only one query is issued to find the user
- private memoize def find_current_user(id : String | User::PrimaryKeyType) : User?
- UserQuery.new.id(id).first?
- end
-end
diff --git a/fixtures/browser_src_template/expected/src/components/.keep b/fixtures/browser_src_template/expected/src/components/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/src/components/base_component.cr b/fixtures/browser_src_template/expected/src/components/base_component.cr
deleted file mode 100644
index c9829b48..00000000
--- a/fixtures/browser_src_template/expected/src/components/base_component.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-abstract class BaseComponent < Lucky::BaseComponent
-end
diff --git a/fixtures/browser_src_template/expected/src/components/shared/field.cr b/fixtures/browser_src_template/expected/src/components/shared/field.cr
deleted file mode 100644
index 5c32e8a8..00000000
--- a/fixtures/browser_src_template/expected/src/components/shared/field.cr
+++ /dev/null
@@ -1,57 +0,0 @@
-# This component is used to make it easier to render the same fields styles
-# throughout your app.
-#
-# Extensive documentation at: https://luckyframework.org/guides/frontend/html-forms#shared-components
-#
-# ## Basic usage:
-#
-# # Renders a text input by default and will guess the label name "Name"
-# mount Shared::Field, op.name
-# # Call any of the input methods on the block
-# mount Shared::Field, op.email, &.email_input
-# # Add other HTML attributes
-# mount Shared::Field, op.email, &.email_input(autofocus: "true")
-# # Pass an explicit label name
-# mount Shared::Field, attribute: op.username, label_text: "Your username"
-#
-# ## Customization
-#
-# You can customize this component so that fields render like you expect.
-# For example, you might wrap it in a div with a "field-wrapper" class.
-#
-# div class: "field-wrapper"
-# label_for field
-# yield field
-# mount Shared::FieldErrors, field
-# end
-#
-# You may also want to have more components if your fields look
-# different in different parts of your app, e.g. `CompactField` or
-# `InlineTextField`
-class Shared::Field(T) < BaseComponent
- # Raises a helpful error if component receives an unpermitted attribute
- include Lucky::CatchUnpermittedAttribute
-
- needs attribute : Avram::PermittedAttribute(T)
- needs label_text : String?
-
- def render(&)
- label_for attribute, label_text
-
- # You can add more default options here. For example:
- #
- # tag_defaults field: attribute, class: "input"
- #
- # Will add the class "input" to the generated HTML.
- tag_defaults field: attribute do |tag_builder|
- yield tag_builder
- end
-
- mount Shared::FieldErrors, attribute
- end
-
- # Use a text_input by default
- def render
- render &.text_input
- end
-end
diff --git a/fixtures/browser_src_template/expected/src/components/shared/field_errors.cr b/fixtures/browser_src_template/expected/src/components/shared/field_errors.cr
deleted file mode 100644
index 3f2937a0..00000000
--- a/fixtures/browser_src_template/expected/src/components/shared/field_errors.cr
+++ /dev/null
@@ -1,16 +0,0 @@
-class Shared::FieldErrors(T) < BaseComponent
- needs attribute : Avram::PermittedAttribute(T)
-
- # Customize the markup and styles to match your application
- def render
- unless attribute.valid?
- div class: "error" do
- text "#{label_text} #{attribute.errors.first}"
- end
- end
- end
-
- def label_text : String
- Wordsmith::Inflector.humanize(attribute.name.to_s)
- end
-end
diff --git a/fixtures/browser_src_template/expected/src/components/shared/flash_messages.cr b/fixtures/browser_src_template/expected/src/components/shared/flash_messages.cr
deleted file mode 100644
index bc44440d..00000000
--- a/fixtures/browser_src_template/expected/src/components/shared/flash_messages.cr
+++ /dev/null
@@ -1,11 +0,0 @@
-class Shared::FlashMessages < BaseComponent
- needs flash : Lucky::FlashStore
-
- def render
- flash.each do |flash_type, flash_message|
- div class: "flash-#{flash_type}", flow_id: "flash" do
- text flash_message
- end
- end
- end
-end
diff --git a/fixtures/browser_src_template/expected/src/components/shared/layout_head.cr b/fixtures/browser_src_template/expected/src/components/shared/layout_head.cr
deleted file mode 100644
index 5a053315..00000000
--- a/fixtures/browser_src_template/expected/src/components/shared/layout_head.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-class Shared::LayoutHead < BaseComponent
- needs page_title : String
-
- def render
- head do
- utf8_charset
- title "My App - #{@page_title}"
- css_link asset("css/app.css")
- js_link asset("js/app.js"), defer: "true"
- csrf_meta_tags
- responsive_meta_tag
-
- # Development helper used with the `lucky watch` command.
- # Reloads the browser when files are updated.
- live_reload_connect_tag if LuckyEnv.development?
- end
- end
-end
diff --git a/fixtures/browser_src_template/expected/src/css/app.scss b/fixtures/browser_src_template/expected/src/css/app.scss
deleted file mode 100644
index 48d219d7..00000000
--- a/fixtures/browser_src_template/expected/src/css/app.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-// Lucky generates 3 folders to help you organize your CSS:
-//
-// - src/css/variables # Files for colors, spacing, etc.
-// - src/css/mixins # Put your mixin functions in files here
-// - src/css/components # CSS for your components
-//
-// Remember to import your new CSS files or they won't be loaded:
-//
-// @import "./variables/colors" # Imports the file in src/css/variables/_colors.scss
-//
-// Note: Vite automatically resolves imports from node_modules
-// https://stackoverflow.com/questions/39535760/what-does-a-tilde-in-a-css-url-do
-
-@import 'modern-normalize/modern-normalize.css';
-// Add your own components and import them like this:
-//
-// @import "components/my_new_component";
-
-// Default Lucky styles.
-// Delete these when you're ready to bring in your own CSS.
-body {
- font-family: system-ui, BlinkMacSystemFont, -apple-system, Segoe UI,
- Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
- sans-serif;
- margin: 0 auto;
- max-width: 800px;
- padding: 20px 40px;
-}
-
-label, input {
- display: flex;
-}
-
-label {
- font-weight: 500;
-}
-
-[type='color'],
-[type='date'],
-[type='datetime'],
-[type='datetime-local'],
-[type='email'],
-[type='month'],
-[type='number'],
-[type='password'],
-[type='search'],
-[type='tel'],
-[type='text'],
-[type='time'],
-[type='url'],
-[type='week'],
-input:not([type]),
-textarea {
- border-radius: 3px;
- border: 1px solid #bbb;
- margin: 7px 0 14px 0;
- max-width: 400px;
- padding: 8px 6px;
- width: 100%;
-}
-
-[type='submit'] {
- font-weight: 900;
- margin: 9px 0;
- padding: 6px 9px;
-}
diff --git a/fixtures/browser_src_template/expected/src/emails/.keep b/fixtures/browser_src_template/expected/src/emails/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/src/js/app.js b/fixtures/browser_src_template/expected/src/js/app.js
deleted file mode 100644
index cca98fa2..00000000
--- a/fixtures/browser_src_template/expected/src/js/app.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* eslint no-console:0 */
-
-// Rails Unobtrusive JavaScript (UJS) is *required* for links in Lucky that use DELETE, POST and PUT.
-// Though it says "Rails" it actually works with any framework.
-import Rails from "@rails/ujs";
-Rails.start();
-
diff --git a/fixtures/browser_src_template/expected/src/models/mixins/.keep b/fixtures/browser_src_template/expected/src/models/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/src/operations/.keep b/fixtures/browser_src_template/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/src/operations/mixins/.keep b/fixtures/browser_src_template/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template/expected/src/pages/errors/show_page.cr b/fixtures/browser_src_template/expected/src/pages/errors/show_page.cr
deleted file mode 100644
index e7636de9..00000000
--- a/fixtures/browser_src_template/expected/src/pages/errors/show_page.cr
+++ /dev/null
@@ -1,93 +0,0 @@
-class Errors::ShowPage
- include Lucky::HTMLPage
-
- needs message : String
- needs status_code : Int32
-
- def render
- html_doctype
- html lang: "en" do
- head do
- utf8_charset
- title "Something went wrong"
- load_lato_font
- normalize_styles
- error_page_styles
- end
-
- body do
- div class: "container" do
- h2 status_code, class: "status-code"
- h1 message, class: "message"
-
- ul class: "helpful-links" do
- li do
- a "Try heading back to home", href: "/", class: "helpful-link"
- end
- end
- end
- end
- end
- end
-
- def load_lato_font
- css_link "https://fonts.googleapis.com/css?family=Lato"
- end
-
- def normalize_styles
- style <<-CSS
- /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}
- CSS
- end
-
- def error_page_styles
- style <<-CSS
- body {
- background-color: #f5f5f5;
- color: #000;
- font-family: 'Lato', sans-serif;
- padding-top: 100px;
- }
-
- .helpful-links {
- list-style-type: none;
- margin: 0;
- padding: 0;
- }
-
- .helpful-link {
- color: #15A38B;
- }
-
- .status-code {
- opacity: 0.4;
- font-size: 26px;
- font-weight: normal;
- }
-
- .message {
- font-size: 34px;
- line-height: 56px;
- font-weight: normal;
- }
-
- .container {
- margin: 0 auto;
- max-width: 450px;
- padding: 55px;
- }
-
- @media only screen and (max-width: 500px) {
- .status-code {
- font-size: 18px;
- }
-
- .message {
- font-size: 26px;
- line-height: 40px;
- margin: 20px 0 35px 0;
- }
- }
- CSS
- end
-end
diff --git a/fixtures/browser_src_template/expected/src/pages/main_layout.cr b/fixtures/browser_src_template/expected/src/pages/main_layout.cr
deleted file mode 100644
index 40f7c5ce..00000000
--- a/fixtures/browser_src_template/expected/src/pages/main_layout.cr
+++ /dev/null
@@ -1,27 +0,0 @@
-abstract class MainLayout
- include Lucky::HTMLPage
-
- abstract def content
- abstract def page_title
-
- # The default page title. It is passed to `Shared::LayoutHead`.
- #
- # Add a `page_title` method to pages to override it. You can also remove
- # This method so every page is required to have its own page title.
- def page_title
- "Welcome"
- end
-
- def render
- html_doctype
-
- html lang: "en" do
- mount Shared::LayoutHead, page_title: page_title
-
- body do
- mount Shared::FlashMessages, context.flash
- content
- end
- end
- end
-end
diff --git a/fixtures/browser_src_template/expected/vite.config.js b/fixtures/browser_src_template/expected/vite.config.js
deleted file mode 100644
index 2076b094..00000000
--- a/fixtures/browser_src_template/expected/vite.config.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import { defineConfig } from 'vite'
-import { resolve } from 'path'
-import compression from 'vite-plugin-compression'
-import devManifest from 'vite-plugin-dev-manifest'
-
-// https://vitejs.dev/config/
-export default defineConfig({
- // Root directory is project root (where vite.config.js is)
- root: '.',
-
- // Public directory for static assets
- publicDir: 'public/assets',
-
- // Build configuration
- build: {
- // Output directory
- outDir: 'public',
- // Don't empty the output directory (Lucky serves from public/)
- emptyOutDir: false,
- // Generate manifest for Lucky asset helpers
- manifest: true,
- // Define entry points
- rollupOptions: {
- input: {
- // These entry names map to asset paths in Lucky:
- // "app" -> asset("js/app.js")
- // "styles" -> asset("css/app.scss")
- app: resolve(__dirname, 'src/js/app.js'),
- styles: resolve(__dirname, 'src/css/app.scss')
- }
- },
- // Asset output configuration
- assetsDir: 'assets',
- // Source maps for production
- sourcemap: process.env.NODE_ENV === 'production' ? false : 'inline'
- },
-
- // CSS configuration
- css: {
- devSourcemap: true
- },
-
- // Server configuration for development
- server: {
- // This allows Vite to be accessed from Lucky's dev server
- origin: 'http://localhost:3001',
- port: 3001,
- strictPort: true,
- // Enable HMR
- hmr: {
- host: 'localhost'
- }
- },
-
- // Preview server configuration (for testing production builds)
- preview: {
- port: 3001
- },
-
- // Plugins
- plugins: [
- // Generate dev manifest for Lucky's compile-time asset validation
- devManifest({
- manifestName: 'manifest.dev',
- clearOnClose: false
- }),
- // Gzip compression for production builds
- process.env.NODE_ENV === 'production' && compression({
- algorithm: 'gzip',
- ext: '.gz',
- threshold: 1024,
- }),
- // Add Brotli compression if desired
- // process.env.NODE_ENV === 'production' && compression({
- // algorithm: 'brotliCompress',
- // ext: '.br',
- // threshold: 1024,
- // }),
- ].filter(Boolean),
-
- // Resolve configuration
- resolve: {
- alias: {
- '@': resolve(__dirname, 'src')
- }
- }
-})
\ No newline at end of file
diff --git a/fixtures/browser_src_template__generate_auth/expected/config/html_page.cr b/fixtures/browser_src_template__generate_auth/expected/config/html_page.cr
deleted file mode 100644
index dca168e5..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/config/html_page.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Lucky::HTMLPage.configure do |settings|
- settings.render_component_comments = !LuckyEnv.production?
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/db/migrations/.keep b/fixtures/browser_src_template__generate_auth/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/package.json b/fixtures/browser_src_template__generate_auth/expected/package.json
deleted file mode 100644
index 3a64c995..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/package.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "license": "UNLICENSED",
- "private": true,
- "type": "module",
- "dependencies": {
- "@rails/ujs": "^7.1.0",
- "modern-normalize": "^2.0.0"
- },
- "scripts": {
- "heroku-postbuild": "yarn build",
- "dev": "vite",
- "build": "vite build",
- "preview": "vite preview",
- "watch": "vite build --watch"
- },
- "devDependencies": {
- "sass": "^1.69.5",
- "vite": "^5.0.0",
- "vite-plugin-compression": "^0.5.1",
- "vite-plugin-dev-manifest": "^1.2.1"
- }
-}
\ No newline at end of file
diff --git a/fixtures/browser_src_template__generate_auth/expected/public/assets/images/.keep b/fixtures/browser_src_template__generate_auth/expected/public/assets/images/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/public/favicon.ico b/fixtures/browser_src_template__generate_auth/expected/public/favicon.ico
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/public/robots.txt b/fixtures/browser_src_template__generate_auth/expected/public/robots.txt
deleted file mode 100644
index 12009050..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/public/robots.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# Learn more about robots.txt: https://www.robotstxt.org/robotstxt.html
-User-agent: *
-# 'Disallow' with an empty value allows all paths to be crawled
-Disallow:
diff --git a/fixtures/browser_src_template__generate_auth/expected/spec/flows/.keep b/fixtures/browser_src_template__generate_auth/expected/spec/flows/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/spec/setup/.keep b/fixtures/browser_src_template__generate_auth/expected/spec/setup/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/spec/setup/configure_lucky_flow.cr b/fixtures/browser_src_template__generate_auth/expected/spec/setup/configure_lucky_flow.cr
deleted file mode 100644
index 504a3d34..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/spec/setup/configure_lucky_flow.cr
+++ /dev/null
@@ -1,37 +0,0 @@
-# For more detailed documentation, visit
-# https://luckyframework.org/guides/testing/html-and-interactivity
-
-LuckyFlow.configure do |settings|
- settings.stop_retrying_after = 200.milliseconds
- settings.base_uri = Lucky::RouteHelper.settings.base_uri
-
- # LuckyFlow will install the chromedriver for you located in
- # ~./webdrivers/. Uncomment this to point to a specific driver
- # settings.driver_path = "/path/to/specific/chromedriver"
-end
-
-# By default, LuckyFlow is set in "headless" mode (no browser window shown).
-# Uncomment this to enable running `LuckyFlow` in a Google Chrome window instead.
-# Be sure to disable for CI.
-#
-# LuckyFlow.default_driver = "chrome"
-
-# LuckyFlow uses a registry for each driver. By default, chrome, and headless_chrome
-# are available. If you'd like to register your own custom driver, you can register
-# it here.
-#
-# LuckyFlow::Registry.register :firefox do
-# # add your custom driver here
-# end
-
-# Setup specs to allow you to change the driver on the fly
-# per spec by setting a tag on specific specs. Requires the
-# driver to be registered through `LuckyFlow::Registry` first.
-#
-# ```
-# it "uses headless_chrome" do
-# end
-# it "uses webless", tags: "webless" do
-# end
-# ```
-LuckyFlow::Spec.setup
diff --git a/fixtures/browser_src_template__generate_auth/expected/spec/support/.keep b/fixtures/browser_src_template__generate_auth/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/spec/support/factories/.keep b/fixtures/browser_src_template__generate_auth/expected/spec/support/factories/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/spec/support/flows/base_flow.cr b/fixtures/browser_src_template__generate_auth/expected/spec/support/flows/base_flow.cr
deleted file mode 100644
index 93709b25..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/spec/support/flows/base_flow.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-# Add methods that all or most Flows need to share
-class BaseFlow < LuckyFlow
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/actions/browser_action.cr b/fixtures/browser_src_template__generate_auth/expected/src/actions/browser_action.cr
deleted file mode 100644
index a72377f4..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/actions/browser_action.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-abstract class BrowserAction < Lucky::Action
- include Lucky::ProtectFromForgery
-
- # By default all actions are required to use underscores.
- # Add `include Lucky::SkipRouteStyleCheck` to your actions if you wish to ignore this check for specific routes.
- include Lucky::EnforceUnderscoredRoute
-
- # This module disables Google FLoC by setting the
- # [Permissions-Policy](https://github.com/WICG/floc) HTTP header to `interest-cohort=()`.
- #
- # This header is a part of Google's Federated Learning of Cohorts (FLoC) which is used
- # to track browsing history instead of using 3rd-party cookies.
- #
- # Remove this include if you want to use the FLoC tracking.
- include Lucky::SecureHeaders::DisableFLoC
-
- accepted_formats [:html, :json], default: :html
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/components/.keep b/fixtures/browser_src_template__generate_auth/expected/src/components/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/components/base_component.cr b/fixtures/browser_src_template__generate_auth/expected/src/components/base_component.cr
deleted file mode 100644
index c9829b48..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/components/base_component.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-abstract class BaseComponent < Lucky::BaseComponent
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/field.cr b/fixtures/browser_src_template__generate_auth/expected/src/components/shared/field.cr
deleted file mode 100644
index 5c32e8a8..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/field.cr
+++ /dev/null
@@ -1,57 +0,0 @@
-# This component is used to make it easier to render the same fields styles
-# throughout your app.
-#
-# Extensive documentation at: https://luckyframework.org/guides/frontend/html-forms#shared-components
-#
-# ## Basic usage:
-#
-# # Renders a text input by default and will guess the label name "Name"
-# mount Shared::Field, op.name
-# # Call any of the input methods on the block
-# mount Shared::Field, op.email, &.email_input
-# # Add other HTML attributes
-# mount Shared::Field, op.email, &.email_input(autofocus: "true")
-# # Pass an explicit label name
-# mount Shared::Field, attribute: op.username, label_text: "Your username"
-#
-# ## Customization
-#
-# You can customize this component so that fields render like you expect.
-# For example, you might wrap it in a div with a "field-wrapper" class.
-#
-# div class: "field-wrapper"
-# label_for field
-# yield field
-# mount Shared::FieldErrors, field
-# end
-#
-# You may also want to have more components if your fields look
-# different in different parts of your app, e.g. `CompactField` or
-# `InlineTextField`
-class Shared::Field(T) < BaseComponent
- # Raises a helpful error if component receives an unpermitted attribute
- include Lucky::CatchUnpermittedAttribute
-
- needs attribute : Avram::PermittedAttribute(T)
- needs label_text : String?
-
- def render(&)
- label_for attribute, label_text
-
- # You can add more default options here. For example:
- #
- # tag_defaults field: attribute, class: "input"
- #
- # Will add the class "input" to the generated HTML.
- tag_defaults field: attribute do |tag_builder|
- yield tag_builder
- end
-
- mount Shared::FieldErrors, attribute
- end
-
- # Use a text_input by default
- def render
- render &.text_input
- end
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/field_errors.cr b/fixtures/browser_src_template__generate_auth/expected/src/components/shared/field_errors.cr
deleted file mode 100644
index 3f2937a0..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/field_errors.cr
+++ /dev/null
@@ -1,16 +0,0 @@
-class Shared::FieldErrors(T) < BaseComponent
- needs attribute : Avram::PermittedAttribute(T)
-
- # Customize the markup and styles to match your application
- def render
- unless attribute.valid?
- div class: "error" do
- text "#{label_text} #{attribute.errors.first}"
- end
- end
- end
-
- def label_text : String
- Wordsmith::Inflector.humanize(attribute.name.to_s)
- end
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/flash_messages.cr b/fixtures/browser_src_template__generate_auth/expected/src/components/shared/flash_messages.cr
deleted file mode 100644
index bc44440d..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/flash_messages.cr
+++ /dev/null
@@ -1,11 +0,0 @@
-class Shared::FlashMessages < BaseComponent
- needs flash : Lucky::FlashStore
-
- def render
- flash.each do |flash_type, flash_message|
- div class: "flash-#{flash_type}", flow_id: "flash" do
- text flash_message
- end
- end
- end
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/layout_head.cr b/fixtures/browser_src_template__generate_auth/expected/src/components/shared/layout_head.cr
deleted file mode 100644
index 5a053315..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/components/shared/layout_head.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-class Shared::LayoutHead < BaseComponent
- needs page_title : String
-
- def render
- head do
- utf8_charset
- title "My App - #{@page_title}"
- css_link asset("css/app.css")
- js_link asset("js/app.js"), defer: "true"
- csrf_meta_tags
- responsive_meta_tag
-
- # Development helper used with the `lucky watch` command.
- # Reloads the browser when files are updated.
- live_reload_connect_tag if LuckyEnv.development?
- end
- end
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/css/app.scss b/fixtures/browser_src_template__generate_auth/expected/src/css/app.scss
deleted file mode 100644
index 48d219d7..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/css/app.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-// Lucky generates 3 folders to help you organize your CSS:
-//
-// - src/css/variables # Files for colors, spacing, etc.
-// - src/css/mixins # Put your mixin functions in files here
-// - src/css/components # CSS for your components
-//
-// Remember to import your new CSS files or they won't be loaded:
-//
-// @import "./variables/colors" # Imports the file in src/css/variables/_colors.scss
-//
-// Note: Vite automatically resolves imports from node_modules
-// https://stackoverflow.com/questions/39535760/what-does-a-tilde-in-a-css-url-do
-
-@import 'modern-normalize/modern-normalize.css';
-// Add your own components and import them like this:
-//
-// @import "components/my_new_component";
-
-// Default Lucky styles.
-// Delete these when you're ready to bring in your own CSS.
-body {
- font-family: system-ui, BlinkMacSystemFont, -apple-system, Segoe UI,
- Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
- sans-serif;
- margin: 0 auto;
- max-width: 800px;
- padding: 20px 40px;
-}
-
-label, input {
- display: flex;
-}
-
-label {
- font-weight: 500;
-}
-
-[type='color'],
-[type='date'],
-[type='datetime'],
-[type='datetime-local'],
-[type='email'],
-[type='month'],
-[type='number'],
-[type='password'],
-[type='search'],
-[type='tel'],
-[type='text'],
-[type='time'],
-[type='url'],
-[type='week'],
-input:not([type]),
-textarea {
- border-radius: 3px;
- border: 1px solid #bbb;
- margin: 7px 0 14px 0;
- max-width: 400px;
- padding: 8px 6px;
- width: 100%;
-}
-
-[type='submit'] {
- font-weight: 900;
- margin: 9px 0;
- padding: 6px 9px;
-}
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/emails/.keep b/fixtures/browser_src_template__generate_auth/expected/src/emails/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/js/app.js b/fixtures/browser_src_template__generate_auth/expected/src/js/app.js
deleted file mode 100644
index cca98fa2..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/js/app.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* eslint no-console:0 */
-
-// Rails Unobtrusive JavaScript (UJS) is *required* for links in Lucky that use DELETE, POST and PUT.
-// Though it says "Rails" it actually works with any framework.
-import Rails from "@rails/ujs";
-Rails.start();
-
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/models/mixins/.keep b/fixtures/browser_src_template__generate_auth/expected/src/models/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/operations/.keep b/fixtures/browser_src_template__generate_auth/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/operations/mixins/.keep b/fixtures/browser_src_template__generate_auth/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/pages/errors/show_page.cr b/fixtures/browser_src_template__generate_auth/expected/src/pages/errors/show_page.cr
deleted file mode 100644
index e7636de9..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/pages/errors/show_page.cr
+++ /dev/null
@@ -1,93 +0,0 @@
-class Errors::ShowPage
- include Lucky::HTMLPage
-
- needs message : String
- needs status_code : Int32
-
- def render
- html_doctype
- html lang: "en" do
- head do
- utf8_charset
- title "Something went wrong"
- load_lato_font
- normalize_styles
- error_page_styles
- end
-
- body do
- div class: "container" do
- h2 status_code, class: "status-code"
- h1 message, class: "message"
-
- ul class: "helpful-links" do
- li do
- a "Try heading back to home", href: "/", class: "helpful-link"
- end
- end
- end
- end
- end
- end
-
- def load_lato_font
- css_link "https://fonts.googleapis.com/css?family=Lato"
- end
-
- def normalize_styles
- style <<-CSS
- /*! normalize.css v7.0.0 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}template{display:none}[hidden]{display:none}
- CSS
- end
-
- def error_page_styles
- style <<-CSS
- body {
- background-color: #f5f5f5;
- color: #000;
- font-family: 'Lato', sans-serif;
- padding-top: 100px;
- }
-
- .helpful-links {
- list-style-type: none;
- margin: 0;
- padding: 0;
- }
-
- .helpful-link {
- color: #15A38B;
- }
-
- .status-code {
- opacity: 0.4;
- font-size: 26px;
- font-weight: normal;
- }
-
- .message {
- font-size: 34px;
- line-height: 56px;
- font-weight: normal;
- }
-
- .container {
- margin: 0 auto;
- max-width: 450px;
- padding: 55px;
- }
-
- @media only screen and (max-width: 500px) {
- .status-code {
- font-size: 18px;
- }
-
- .message {
- font-size: 26px;
- line-height: 40px;
- margin: 20px 0 35px 0;
- }
- }
- CSS
- end
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/src/pages/main_layout.cr b/fixtures/browser_src_template__generate_auth/expected/src/pages/main_layout.cr
deleted file mode 100644
index 40f7c5ce..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/src/pages/main_layout.cr
+++ /dev/null
@@ -1,27 +0,0 @@
-abstract class MainLayout
- include Lucky::HTMLPage
-
- abstract def content
- abstract def page_title
-
- # The default page title. It is passed to `Shared::LayoutHead`.
- #
- # Add a `page_title` method to pages to override it. You can also remove
- # This method so every page is required to have its own page title.
- def page_title
- "Welcome"
- end
-
- def render
- html_doctype
-
- html lang: "en" do
- mount Shared::LayoutHead, page_title: page_title
-
- body do
- mount Shared::FlashMessages, context.flash
- content
- end
- end
- end
-end
diff --git a/fixtures/browser_src_template__generate_auth/expected/vite.config.js b/fixtures/browser_src_template__generate_auth/expected/vite.config.js
deleted file mode 100644
index 2076b094..00000000
--- a/fixtures/browser_src_template__generate_auth/expected/vite.config.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import { defineConfig } from 'vite'
-import { resolve } from 'path'
-import compression from 'vite-plugin-compression'
-import devManifest from 'vite-plugin-dev-manifest'
-
-// https://vitejs.dev/config/
-export default defineConfig({
- // Root directory is project root (where vite.config.js is)
- root: '.',
-
- // Public directory for static assets
- publicDir: 'public/assets',
-
- // Build configuration
- build: {
- // Output directory
- outDir: 'public',
- // Don't empty the output directory (Lucky serves from public/)
- emptyOutDir: false,
- // Generate manifest for Lucky asset helpers
- manifest: true,
- // Define entry points
- rollupOptions: {
- input: {
- // These entry names map to asset paths in Lucky:
- // "app" -> asset("js/app.js")
- // "styles" -> asset("css/app.scss")
- app: resolve(__dirname, 'src/js/app.js'),
- styles: resolve(__dirname, 'src/css/app.scss')
- }
- },
- // Asset output configuration
- assetsDir: 'assets',
- // Source maps for production
- sourcemap: process.env.NODE_ENV === 'production' ? false : 'inline'
- },
-
- // CSS configuration
- css: {
- devSourcemap: true
- },
-
- // Server configuration for development
- server: {
- // This allows Vite to be accessed from Lucky's dev server
- origin: 'http://localhost:3001',
- port: 3001,
- strictPort: true,
- // Enable HMR
- hmr: {
- host: 'localhost'
- }
- },
-
- // Preview server configuration (for testing production builds)
- preview: {
- port: 3001
- },
-
- // Plugins
- plugins: [
- // Generate dev manifest for Lucky's compile-time asset validation
- devManifest({
- manifestName: 'manifest.dev',
- clearOnClose: false
- }),
- // Gzip compression for production builds
- process.env.NODE_ENV === 'production' && compression({
- algorithm: 'gzip',
- ext: '.gz',
- threshold: 1024,
- }),
- // Add Brotli compression if desired
- // process.env.NODE_ENV === 'production' && compression({
- // algorithm: 'brotliCompress',
- // ext: '.br',
- // threshold: 1024,
- // }),
- ].filter(Boolean),
-
- // Resolve configuration
- resolve: {
- alias: {
- '@': resolve(__dirname, 'src')
- }
- }
-})
\ No newline at end of file
diff --git a/fixtures/cat.gif b/fixtures/cat.gif
deleted file mode 100644
index d47e9572..00000000
Binary files a/fixtures/cat.gif and /dev/null differ
diff --git a/fixtures/hello_crystal.cr b/fixtures/hello_crystal.cr
deleted file mode 100644
index 58d66257..00000000
--- a/fixtures/hello_crystal.cr
+++ /dev/null
@@ -1 +0,0 @@
-puts "Hello, Crystal!"
diff --git a/fixtures/hello_world.cr b/fixtures/hello_world.cr
deleted file mode 100644
index 01a178ad..00000000
--- a/fixtures/hello_world.cr
+++ /dev/null
@@ -1 +0,0 @@
-puts "Hello World!"
diff --git a/fixtures/shard_file_template/expected/shard.yml b/fixtures/shard_file_template/expected/shard.yml
deleted file mode 100644
index 10a7483f..00000000
--- a/fixtures/shard_file_template/expected/shard.yml
+++ /dev/null
@@ -1,39 +0,0 @@
----
-name: test-shard
-version: 0.1.0
-targets:
- test-shard:
- main: src/test-shard.cr
-crystal: '>= 1.16.1'
-dependencies:
- lucky:
- github: luckyframework/lucky
- version: ~> 1.4.0
- avram:
- github: luckyframework/avram
- version: ~> 1.4.0
- carbon:
- github: luckyframework/carbon
- version: ~> 0.6.0
- carbon_sendgrid_adapter:
- github: luckyframework/carbon_sendgrid_adapter
- version: ~> 0.6.0
- lucky_env:
- github: luckyframework/lucky_env
- version: ~> 0.3.0
- lucky_task:
- github: luckyframework/lucky_task
- version: ~> 0.3.0
- authentic:
- github: luckyframework/authentic
- version: '>= 1.0.2, < 2.0.0'
- jwt:
- github: crystal-community/jwt
- version: ~> 1.6.1
-development_dependencies:
- lucky_flow:
- github: luckyframework/lucky_flow
- version: ~> 0.10.1
- lucky_sec_tester:
- github: luckyframework/lucky_sec_tester
- version: ~> 0.3.3
diff --git a/fixtures/shard_file_template__browser/expected/shard.yml b/fixtures/shard_file_template__browser/expected/shard.yml
deleted file mode 100644
index 76a3bf27..00000000
--- a/fixtures/shard_file_template__browser/expected/shard.yml
+++ /dev/null
@@ -1,30 +0,0 @@
----
-name: test-shard
-version: 0.1.0
-targets:
- test-shard:
- main: src/test-shard.cr
-crystal: '>= 1.16.1'
-dependencies:
- lucky:
- github: luckyframework/lucky
- version: ~> 1.4.0
- avram:
- github: luckyframework/avram
- version: ~> 1.4.0
- carbon:
- github: luckyframework/carbon
- version: ~> 0.6.0
- carbon_sendgrid_adapter:
- github: luckyframework/carbon_sendgrid_adapter
- version: ~> 0.6.0
- lucky_env:
- github: luckyframework/lucky_env
- version: ~> 0.3.0
- lucky_task:
- github: luckyframework/lucky_task
- version: ~> 0.3.0
-development_dependencies:
- lucky_flow:
- github: luckyframework/lucky_flow
- version: ~> 0.10.1
diff --git a/fixtures/shard_file_template__generate_auth/expected/shard.yml b/fixtures/shard_file_template__generate_auth/expected/shard.yml
deleted file mode 100644
index b8305cbc..00000000
--- a/fixtures/shard_file_template__generate_auth/expected/shard.yml
+++ /dev/null
@@ -1,33 +0,0 @@
----
-name: test-shard
-version: 0.1.0
-targets:
- test-shard:
- main: src/test-shard.cr
-crystal: '>= 1.16.1'
-dependencies:
- lucky:
- github: luckyframework/lucky
- version: ~> 1.4.0
- avram:
- github: luckyframework/avram
- version: ~> 1.4.0
- carbon:
- github: luckyframework/carbon
- version: ~> 0.6.0
- carbon_sendgrid_adapter:
- github: luckyframework/carbon_sendgrid_adapter
- version: ~> 0.6.0
- lucky_env:
- github: luckyframework/lucky_env
- version: ~> 0.3.0
- lucky_task:
- github: luckyframework/lucky_task
- version: ~> 0.3.0
- authentic:
- github: luckyframework/authentic
- version: '>= 1.0.2, < 2.0.0'
- jwt:
- github: crystal-community/jwt
- version: ~> 1.6.1
-development_dependencies: {}
diff --git a/fixtures/shard_file_template__with_sec_tester/expected/shard.yml b/fixtures/shard_file_template__with_sec_tester/expected/shard.yml
deleted file mode 100644
index 877221c3..00000000
--- a/fixtures/shard_file_template__with_sec_tester/expected/shard.yml
+++ /dev/null
@@ -1,30 +0,0 @@
----
-name: test-shard
-version: 0.1.0
-targets:
- test-shard:
- main: src/test-shard.cr
-crystal: '>= 1.16.1'
-dependencies:
- lucky:
- github: luckyframework/lucky
- version: ~> 1.4.0
- avram:
- github: luckyframework/avram
- version: ~> 1.4.0
- carbon:
- github: luckyframework/carbon
- version: ~> 0.6.0
- carbon_sendgrid_adapter:
- github: luckyframework/carbon_sendgrid_adapter
- version: ~> 0.6.0
- lucky_env:
- github: luckyframework/lucky_env
- version: ~> 0.3.0
- lucky_task:
- github: luckyframework/lucky_task
- version: ~> 0.3.0
-development_dependencies:
- lucky_sec_tester:
- github: luckyframework/lucky_sec_tester
- version: ~> 0.3.3
diff --git a/fixtures/src_template/expected/.crystal-version b/fixtures/src_template/expected/.crystal-version
deleted file mode 100644
index 41c11ffb..00000000
--- a/fixtures/src_template/expected/.crystal-version
+++ /dev/null
@@ -1 +0,0 @@
-1.16.1
diff --git a/fixtures/src_template/expected/.env b/fixtures/src_template/expected/.env
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/.github/workflows/ci.yml b/fixtures/src_template/expected/.github/workflows/ci.yml
deleted file mode 100644
index 8955cbf5..00000000
--- a/fixtures/src_template/expected/.github/workflows/ci.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-name: test-project CI
-
-on:
- push:
- branches: "*"
- pull_request:
- branches: "*"
-
-jobs:
- check-format:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental }}
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
- - name: Format
- run: crystal tool format --check
-
- specs:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- env:
- LUCKY_ENV: test
- DB_HOST: localhost
- continue-on-error: ${{ matrix.experimental }}
- services:
- postgres:
- image: postgres:14-alpine
- env:
- POSTGRES_PASSWORD: postgres
- ports:
- - 5432:5432
- # Set health checks to wait until postgres has started
- options: >-
- --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
-
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
-
- - name: Set up Crystal cache
- uses: actions/cache@v4
- id: crystal-cache
- with:
- path: |
- ~/.cache/crystal
- lib
- key: ${{ runner.os }}-crystal-${{ hashFiles('**/shard.lock') }}
- restore-keys: |
- ${{ runner.os }}-crystal-
-
- - name: Install shards
- if: steps.crystal-cache.outputs.cache-hit != 'true'
- run: shards check || shards install
-
- - name: Build lucky_tasks
- run: crystal build tasks.cr -o ./lucky_tasks
-
- - name: Prepare database
- run: |
- ./lucky_tasks db.create
- ./lucky_tasks db.migrate
- ./lucky_tasks db.seed.required_data
-
- - name: Run tests
- run: crystal spec -Dwith_sec_tests
\ No newline at end of file
diff --git a/fixtures/src_template/expected/Procfile b/fixtures/src_template/expected/Procfile
deleted file mode 100644
index e524d70d..00000000
--- a/fixtures/src_template/expected/Procfile
+++ /dev/null
@@ -1,2 +0,0 @@
-web: bin/app
-release: lucky db.migrate
diff --git a/fixtures/src_template/expected/Procfile.dev b/fixtures/src_template/expected/Procfile.dev
deleted file mode 100644
index dc39e8fe..00000000
--- a/fixtures/src_template/expected/Procfile.dev
+++ /dev/null
@@ -1,2 +0,0 @@
-system_check: crystal script/system_check.cr
-web: lucky watch
diff --git a/fixtures/src_template/expected/README.md b/fixtures/src_template/expected/README.md
deleted file mode 100644
index da2d97cc..00000000
--- a/fixtures/src_template/expected/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# test-project
-
-This is a project written using [Lucky](https://luckyframework.org). Enjoy!
-
-### Setting up the project
-
-1. [Install required dependencies](https://luckyframework.org/guides/getting-started/installing#install-required-dependencies)
-1. Update database settings in `config/database.cr`
-1. Run `script/setup`
-1. Run `lucky dev` to start the app
-
-### Using Docker for development
-
-1. [Install Docker](https://docs.docker.com/engine/install/)
-1. Run `docker compose up`
-
-The Docker container will boot all of the necessary components needed to run your Lucky application.
-To configure the container, update the `docker-compose.yml` file, and the `docker/development.dockerfile` file.
-
-
-### Learning Lucky
-
-Lucky uses the [Crystal](https://crystal-lang.org) programming language. You can learn about Lucky from the [Lucky Guides](https://luckyframework.org/guides/getting-started/why-lucky).
diff --git a/fixtures/src_template/expected/config/application.cr b/fixtures/src_template/expected/config/application.cr
deleted file mode 100644
index c807149a..00000000
--- a/fixtures/src_template/expected/config/application.cr
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file may be used for custom Application configurations.
-# It will be loaded before other config files.
-#
-# Read more on configuration:
-# https://luckyframework.org/guides/getting-started/configuration#configuring-your-own-code
-
-# Use this code as an example:
-#
-# ```
-# module Application
-# Habitat.create do
-# setting support_email : String
-# setting lock_with_basic_auth : Bool
-# end
-# end
-#
-# Application.configure do |settings|
-# settings.support_email = "support@myapp.io"
-# settings.lock_with_basic_auth = LuckyEnv.staging?
-# end
-#
-# # In your application, call
-# # `Application.settings.support_email` anywhere you need it.
-# ```
diff --git a/fixtures/src_template/expected/config/colors.cr b/fixtures/src_template/expected/config/colors.cr
deleted file mode 100644
index 761ae940..00000000
--- a/fixtures/src_template/expected/config/colors.cr
+++ /dev/null
@@ -1,4 +0,0 @@
-# This enables the color output when in development or test
-# Check out the Colorize docs for more information
-# https://crystal-lang.org/api/Colorize.html
-Colorize.enabled = LuckyEnv.development? || LuckyEnv.test?
diff --git a/fixtures/src_template/expected/config/cookies.cr b/fixtures/src_template/expected/config/cookies.cr
deleted file mode 100644
index 2d5055f2..00000000
--- a/fixtures/src_template/expected/config/cookies.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-require "./server"
-
-Lucky::Session.configure do |settings|
- settings.key = "_test_project_session"
-end
-
-Lucky::CookieJar.configure do |settings|
- settings.on_set = ->(cookie : HTTP::Cookie) {
- # If ForceSSLHandler is enabled, only send cookies over HTTPS
- cookie.secure(Lucky::ForceSSLHandler.settings.enabled)
-
- # By default, don't allow reading cookies with JavaScript
- cookie.http_only(true)
-
- # Restrict cookies to a first-party or same-site context
- cookie.samesite(:lax)
-
- # Set all cookies to the root path by default
- cookie.path("/")
-
- # You can set other defaults for cookies here. For example:
- #
- # cookie.expires(1.year.from_now).domain("mydomain.com")
- }
-end
diff --git a/fixtures/src_template/expected/config/database.cr b/fixtures/src_template/expected/config/database.cr
deleted file mode 100644
index f614299a..00000000
--- a/fixtures/src_template/expected/config/database.cr
+++ /dev/null
@@ -1,29 +0,0 @@
-database_name = "test_project_#{LuckyEnv.environment}"
-
-AppDatabase.configure do |settings|
- if LuckyEnv.production?
- settings.credentials = Avram::Credentials.parse(ENV["DATABASE_URL"])
- else
- settings.credentials = Avram::Credentials.parse?(ENV["DATABASE_URL"]?) || Avram::Credentials.new(
- database: database_name,
- hostname: ENV["DB_HOST"]? || "localhost",
- port: ENV["DB_PORT"]?.try(&.to_i) || 5432,
- # Some common usernames are "postgres", "root", or your system username (run 'whoami')
- username: ENV["DB_USERNAME"]? || "postgres",
- # Some Postgres installations require no password. Use "" if that is the case.
- password: ENV["DB_PASSWORD"]? || "postgres"
- )
- end
-end
-
-Avram.configure do |settings|
- settings.database_to_migrate = AppDatabase
-
- # In production, allow lazy loading (N+1).
- # In development and test, raise an error if you forget to preload associations
- settings.lazy_load_enabled = LuckyEnv.production?
-
- # Always parse `Time` values with these specific formats.
- # Used for both database values, and datetime input fields.
- # settings.time_formats << "%F"
-end
diff --git a/fixtures/src_template/expected/config/email.cr b/fixtures/src_template/expected/config/email.cr
deleted file mode 100644
index 7c875449..00000000
--- a/fixtures/src_template/expected/config/email.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-require "carbon_sendgrid_adapter"
-
-BaseEmail.configure do |settings|
- if LuckyEnv.production?
- # If you don't need to send emails, set the adapter to DevAdapter instead:
- #
- # settings.adapter = Carbon::DevAdapter.new
- #
- # If you do need emails, get a key from SendGrid and set an ENV variable
- send_grid_key = send_grid_key_from_env
- settings.adapter = Carbon::SendGridAdapter.new(api_key: send_grid_key)
- elsif LuckyEnv.development?
- settings.adapter = Carbon::DevAdapter.new(print_emails: true)
- else
- settings.adapter = Carbon::DevAdapter.new
- end
-end
-
-private def send_grid_key_from_env
- ENV["SEND_GRID_KEY"]? || raise_missing_key_message
-end
-
-private def raise_missing_key_message
- puts "Missing SEND_GRID_KEY. Set the SEND_GRID_KEY env variable to 'unused' if not sending emails, or set the SEND_GRID_KEY ENV var.".colorize.red
- exit(1)
-end
diff --git a/fixtures/src_template/expected/config/env.cr b/fixtures/src_template/expected/config/env.cr
deleted file mode 100644
index 3f364072..00000000
--- a/fixtures/src_template/expected/config/env.cr
+++ /dev/null
@@ -1,33 +0,0 @@
-# Environments are managed using `LuckyEnv`. By default, development, production
-# and test are supported. See
-# https://luckyframework.org/guides/getting-started/configuration for details.
-#
-# The default environment is development unless the environment variable
-# LUCKY_ENV is set.
-#
-# Example:
-# ```
-# LuckyEnv.environment # => "development"
-# LuckyEnv.development? # => true
-# LuckyEnv.production? # => false
-# LuckyEnv.test? # => false
-# ```
-#
-# New environments can be added using the `LuckyEnv.add_env` macro.
-#
-# Example:
-# ```
-# LuckyEnv.add_env :staging
-# LuckyEnv.staging? # => false
-# ```
-#
-# To determine whether or not a `LuckyTask` is currently running, you can use
-# the `LuckyEnv.task?` predicate.
-#
-# Example:
-# ```
-# LuckyEnv.task? # => false
-# ```
-
-# Add a staging environment.
-# LuckyEnv.add_env :staging
diff --git a/fixtures/src_template/expected/config/error_handler.cr b/fixtures/src_template/expected/config/error_handler.cr
deleted file mode 100644
index c6b736e3..00000000
--- a/fixtures/src_template/expected/config/error_handler.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Lucky::ErrorHandler.configure do |settings|
- settings.show_debug_output = !LuckyEnv.production?
-end
diff --git a/fixtures/src_template/expected/config/log.cr b/fixtures/src_template/expected/config/log.cr
deleted file mode 100644
index a43940d9..00000000
--- a/fixtures/src_template/expected/config/log.cr
+++ /dev/null
@@ -1,50 +0,0 @@
-require "file_utils"
-
-if LuckyEnv.test?
- # Logs to `tmp/test.log` so you can see what's happening without having
- # a bunch of log output in your spec results.
- FileUtils.mkdir_p("tmp")
-
- backend = Log::IOBackend.new(File.new("tmp/test.log", mode: "w"))
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
-elsif LuckyEnv.production?
- # Lucky uses JSON in production so logs can be searched more easily
- #
- # If you want logs like in development use 'Lucky::PrettyLogFormatter.proc'.
- backend = Log::IOBackend.new
- backend.formatter = Dexter::JSONLogFormatter.proc
- Log.dexter.configure(:info, backend)
-else
- # Use a pretty formatter printing to STDOUT in development
- backend = Log::IOBackend.new
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
- DB::Log.level = :info
-end
-
-# Lucky only logs when before/after pipes halt by redirecting, or rendering a
-# response. Pipes that run without halting are not logged.
-#
-# If you want to log every pipe that runs, set the log level to ':info'
-Lucky::ContinuedPipeLog.dexter.configure(:none)
-
-# Lucky only logs failed queries by default.
-#
-# Set the log to ':info' to log all queries
-Avram::QueryLog.dexter.configure(:none)
-
-# Subscribe to Pulsar events to log when queries are made,
-# queries fail, or save operations fail. Remove this to
-# disable these log events without disabling all logging.
-Avram.initialize_logging
-
-# Skip logging static assets requests in development
-Lucky::LogHandler.configure do |settings|
- if LuckyEnv.development?
- settings.skip_if = ->(context : HTTP::Server::Context) {
- context.request.method.downcase == "get" &&
- context.request.resource.starts_with?(/\/css\/|\/js\/|\/assets\/|\/favicon\.ico/)
- }
- end
-end
diff --git a/fixtures/src_template/expected/config/route_helper.cr b/fixtures/src_template/expected/config/route_helper.cr
deleted file mode 100644
index ede1f328..00000000
--- a/fixtures/src_template/expected/config/route_helper.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is used when generating URLs for your application
-Lucky::RouteHelper.configure do |settings|
- if LuckyEnv.production?
- # Example: https://my_app.com
- settings.base_uri = ENV.fetch("APP_DOMAIN")
- else
- # Set domain to the default host/port in development/test
- settings.base_uri = "http://localhost:#{Lucky::ServerSettings.port}"
- end
-end
diff --git a/fixtures/src_template/expected/config/server.cr b/fixtures/src_template/expected/config/server.cr
deleted file mode 100644
index b7cca25c..00000000
--- a/fixtures/src_template/expected/config/server.cr
+++ /dev/null
@@ -1,68 +0,0 @@
-# Here is where you configure the Lucky server
-#
-# Look at config/route_helper.cr if you want to change the domain used when
-# generating links with `Action.url`.
-Lucky::Server.configure do |settings|
- if LuckyEnv.production?
- settings.secret_key_base = secret_key_from_env
- settings.host = "0.0.0.0"
- settings.port = ENV["PORT"].to_i
- settings.gzip_enabled = true
- # By default certain content types will be gzipped.
- # For a full list look in
- # https://github.com/luckyframework/lucky/blob/main/src/lucky/server.cr
- # To add additional extensions do something like this:
- # settings.gzip_content_types << "content/type"
- else
- settings.secret_key_base = "1234567890"
- # Change host/port in config/watch.yml
- # Alternatively, you can set the DEV_PORT env to set the port for local development
- settings.host = Lucky::ServerSettings.host
- settings.port = Lucky::ServerSettings.port
- end
-
- # Configure the asset build system (default is Vite)
- settings.asset_build_system = Lucky::AssetBuilder::Vite.new
-
- # Configure asset host for Vite
- if LuckyEnv.development?
- # In development, Vite serves assets from its dev server
- settings.asset_host = "http://localhost:3001"
- elsif LuckyEnv.production?
- # In production, Lucky serves the built assets
- # You could also use a CDN here:
- # settings.asset_host = "https://mycdnhost.com"
- settings.asset_host = ""
- else
- settings.asset_host = ""
- end
-end
-
-Lucky::ForceSSLHandler.configure do |settings|
- # To force SSL in production, uncomment the lines below.
- # This will cause http requests to be redirected to https:
- #
- # settings.enabled = LuckyEnv.production?
- # settings.strict_transport_security = {max_age: 1.year, include_subdomains: true}
- #
- # Or, leave it disabled:
- settings.enabled = false
-end
-
-# Set a unique ID for each HTTP request.
-# To enable the request ID, uncomment the lines below.
-# You can set your own custom String, or use a random UUID.
-# Lucky::RequestIdHandler.configure do |settings|
-# settings.set_request_id = ->(context : HTTP::Server::Context) {
-# UUID.random.to_s
-# }
-# end
-
-private def secret_key_from_env
- ENV["SECRET_KEY_BASE"]? || raise_missing_secret_key_in_production
-end
-
-private def raise_missing_secret_key_in_production
- puts "Please set the SECRET_KEY_BASE environment variable. You can generate a secret key with 'lucky gen.secret_key'".colorize.red
- exit(1)
-end
\ No newline at end of file
diff --git a/fixtures/src_template/expected/config/watch.yml b/fixtures/src_template/expected/config/watch.yml
deleted file mode 100644
index 3a59b410..00000000
--- a/fixtures/src_template/expected/config/watch.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-host: 127.0.0.1
-port: 3000
-reload_port: 3001
diff --git a/fixtures/src_template/expected/db/migrations/.keep b/fixtures/src_template/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/docker-compose.yml b/fixtures/src_template/expected/docker-compose.yml
deleted file mode 100644
index d00779db..00000000
--- a/fixtures/src_template/expected/docker-compose.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-version: "3.8"
-services:
- lucky:
- build:
- context: .
- dockerfile: docker/development.dockerfile
- environment:
- DATABASE_URL: postgres://lucky:password@postgres:5432/lucky
- DEV_HOST: "0.0.0.0"
- volumes:
- - .:/app
- - node_modules:/app/node_modules
- - shards_lib:/app/lib
- - app_bin:/app/bin
- - build_cache:/root/.cache
- depends_on:
- - postgres
- ports:
- - 3000:3000 # This is the Lucky Server port
- - 3001:3001 # This is the Lucky watcher reload port
-
- entrypoint: ["docker/dev_entrypoint.sh"]
-
- postgres:
- image: postgres:14-alpine
- environment:
- POSTGRES_USER: lucky
- POSTGRES_PASSWORD: password
- POSTGRES_DB: lucky
- volumes:
- - postgres_data:/var/lib/postgresql/data
- ports:
- # The postgres database container is exposed on the host at port 6543 to
- # allow connecting directly to it with postgres clients. The port differs
- # from the postgres default to avoid conflict with existing postgres
- # servers. Connect to a running postgres container with:
- # postgres://lucky:password@localhost:6543/lucky
- - 6543:5432
-
-volumes:
- postgres_data:
- node_modules:
- shards_lib:
- app_bin:
- build_cache:
diff --git a/fixtures/src_template/expected/docker/dev_entrypoint.sh b/fixtures/src_template/expected/docker/dev_entrypoint.sh
deleted file mode 100755
index f5aab877..00000000
--- a/fixtures/src_template/expected/docker/dev_entrypoint.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# This is the entrypoint script used for development docker workflows.
-# By default it will:
-# - Install dependencies.
-# - Run migrations.
-# - Start the dev server.
-# It also accepts any commands to be run instead.
-
-
-warnfail () {
- echo "$@" >&2
- exit 1
-}
-
-case ${1:-} in
- "") # If no arguments are provided, start lucky dev server.
- ;;
-
- *) # If any arguments are provided, execute them instead.
- exec "$@"
-esac
-
-if ! [ -d bin ] ; then
- echo 'Creating bin directory'
- mkdir bin
-fi
-if ! shards check ; then
- echo 'Installing shards...'
- shards install
-fi
-
-echo 'Waiting for postgres to be available...'
-./docker/wait-for-it.sh -q postgres:5432
-
-if ! psql -d "$DATABASE_URL" -c '\d migrations' > /dev/null ; then
- echo 'Finishing database setup...'
- lucky db.migrate
-fi
-
-echo 'Starting lucky dev server...'
-exec lucky dev
diff --git a/fixtures/src_template/expected/docker/development.dockerfile b/fixtures/src_template/expected/docker/development.dockerfile
deleted file mode 100644
index a4e5b267..00000000
--- a/fixtures/src_template/expected/docker/development.dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM crystallang/crystal:1.16.1
-
-# Install utilities required to make this Dockerfile run
-RUN apt-get update && \
- apt-get install -y wget
-
-# Apt installs:
-# - Postgres cli tools are required for lucky-cli.
-# - tmux is required for the Overmind process manager.
-RUN apt-get update && \
- apt-get install -y postgresql-client tmux && \
- rm -rf /var/lib/apt/lists/*
-
-# Install lucky cli
-WORKDIR /lucky/cli
-RUN git clone https://github.com/luckyframework/lucky_cli . && \
- git checkout v1.3.0 && \
- shards build --without-development && \
- cp bin/lucky /usr/bin
-
-WORKDIR /app
-ENV DATABASE_URL=postgres://postgres:postgres@host.docker.internal:5432/postgres
-EXPOSE 3000
-EXPOSE 3001
-
diff --git a/fixtures/src_template/expected/docker/wait-for-it.sh b/fixtures/src_template/expected/docker/wait-for-it.sh
deleted file mode 100755
index 06e0638c..00000000
--- a/fixtures/src_template/expected/docker/wait-for-it.sh
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/bash
-#
-# Pulled from https://github.com/vishnubob/wait-for-it on 2022-02-28.
-# Licensed under the MIT license as of 81b1373f.
-#
-# Below this line, wait-for-it is the original work of the author.
-#
-# Use this script to test if a given TCP host/port are available
-
-WAITFORIT_cmdname=${0##*/}
-
-echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
-
-usage()
-{
- cat << USAGE >&2
-Usage:
- $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
- -h HOST | --host=HOST Host or IP under test
- -p PORT | --port=PORT TCP port under test
- Alternatively, you specify the host and port as host:port
- -s | --strict Only execute subcommand if the test succeeds
- -q | --quiet Don't output any status messages
- -t TIMEOUT | --timeout=TIMEOUT
- Timeout in seconds, zero for no timeout
- -- COMMAND ARGS Execute command with args after the test finishes
-USAGE
- exit 1
-}
-
-wait_for()
-{
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- else
- echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
- fi
- WAITFORIT_start_ts=$(date +%s)
- while :
- do
- if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
- nc -z $WAITFORIT_HOST $WAITFORIT_PORT
- WAITFORIT_result=$?
- else
- (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
- WAITFORIT_result=$?
- fi
- if [[ $WAITFORIT_result -eq 0 ]]; then
- WAITFORIT_end_ts=$(date +%s)
- echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
- break
- fi
- sleep 1
- done
- return $WAITFORIT_result
-}
-
-wait_for_wrapper()
-{
- # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
- if [[ $WAITFORIT_QUIET -eq 1 ]]; then
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- else
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- fi
- WAITFORIT_PID=$!
- trap "kill -INT -$WAITFORIT_PID" INT
- wait $WAITFORIT_PID
- WAITFORIT_RESULT=$?
- if [[ $WAITFORIT_RESULT -ne 0 ]]; then
- echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- fi
- return $WAITFORIT_RESULT
-}
-
-# process arguments
-while [[ $# -gt 0 ]]
-do
- case "$1" in
- *:* )
- WAITFORIT_hostport=(${1//:/ })
- WAITFORIT_HOST=${WAITFORIT_hostport[0]}
- WAITFORIT_PORT=${WAITFORIT_hostport[1]}
- shift 1
- ;;
- --child)
- WAITFORIT_CHILD=1
- shift 1
- ;;
- -q | --quiet)
- WAITFORIT_QUIET=1
- shift 1
- ;;
- -s | --strict)
- WAITFORIT_STRICT=1
- shift 1
- ;;
- -h)
- WAITFORIT_HOST="$2"
- if [[ $WAITFORIT_HOST == "" ]]; then break; fi
- shift 2
- ;;
- --host=*)
- WAITFORIT_HOST="${1#*=}"
- shift 1
- ;;
- -p)
- WAITFORIT_PORT="$2"
- if [[ $WAITFORIT_PORT == "" ]]; then break; fi
- shift 2
- ;;
- --port=*)
- WAITFORIT_PORT="${1#*=}"
- shift 1
- ;;
- -t)
- WAITFORIT_TIMEOUT="$2"
- if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
- shift 2
- ;;
- --timeout=*)
- WAITFORIT_TIMEOUT="${1#*=}"
- shift 1
- ;;
- --)
- shift
- WAITFORIT_CLI=("$@")
- break
- ;;
- --help)
- usage
- ;;
- *)
- echoerr "Unknown argument: $1"
- usage
- ;;
- esac
-done
-
-if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
- echoerr "Error: you need to provide a host and port to test."
- usage
-fi
-
-WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
-WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
-WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
-WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
-
-# Check to see if timeout is from busybox?
-WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
-WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
-
-WAITFORIT_BUSYTIMEFLAG=""
-if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
- WAITFORIT_ISBUSY=1
- # Check if busybox timeout uses -t flag
- # (recent Alpine versions don't support -t anymore)
- if timeout &>/dev/stdout | grep -q -e '-t '; then
- WAITFORIT_BUSYTIMEFLAG="-t"
- fi
-else
- WAITFORIT_ISBUSY=0
-fi
-
-if [[ $WAITFORIT_CHILD -gt 0 ]]; then
- wait_for
- WAITFORIT_RESULT=$?
- exit $WAITFORIT_RESULT
-else
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- wait_for_wrapper
- WAITFORIT_RESULT=$?
- else
- wait_for
- WAITFORIT_RESULT=$?
- fi
-fi
-
-if [[ $WAITFORIT_CLI != "" ]]; then
- if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
- echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
- exit $WAITFORIT_RESULT
- fi
- exec "${WAITFORIT_CLI[@]}"
-else
- exit $WAITFORIT_RESULT
-fi
-
diff --git a/fixtures/src_template/expected/script/helpers/function_helpers.cr b/fixtures/src_template/expected/script/helpers/function_helpers.cr
deleted file mode 100644
index 8abcb6a2..00000000
--- a/fixtures/src_template/expected/script/helpers/function_helpers.cr
+++ /dev/null
@@ -1,32 +0,0 @@
-require "colorize"
-
-# These are helper methods provided to help keep your code
-# clean. Add new methods, or alter these as needed.
-
-def notice(message : String) : Nil
- puts "\n▸ #{message}"
-end
-
-def print_done : Nil
- puts "✔ Done"
-end
-
-def print_error(message : String) : Nil
- puts "There is a problem with your system setup:\n".colorize.red.bold
- puts "#{message}\n".colorize.red.bold
- Process.exit(1)
-end
-
-def command_not_found(command : String) : Bool
- Process.find_executable(command).nil?
-end
-
-def command_not_running(command : String, *args) : Bool
- output = IO::Memory.new
- code = Process.run(command, args, output: output).exit_code
- code > 0
-end
-
-def run_command(command : String, *args) : Nil
- Process.run(command, args, output: STDOUT, error: STDERR, input: STDIN)
-end
diff --git a/fixtures/src_template/expected/script/setup.cr b/fixtures/src_template/expected/script/setup.cr
deleted file mode 100644
index f8d4a907..00000000
--- a/fixtures/src_template/expected/script/setup.cr
+++ /dev/null
@@ -1,28 +0,0 @@
-require "./helpers/*"
-
-notice "Running System Check"
-
-require "./system_check"
-
-print_done
-
-
-notice "Installing shards"
-run_command "shards", "install"
-
-if !File.exists?(".env")
- notice "No .env found. Creating one."
- File.touch ".env"
- print_done
-end
-
-notice "Setting up the database"
-
-run_command "lucky", "db.setup"
-
-notice "Seeding the database with required and sample records"
-run_command "lucky", "db.seed.required_data"
-run_command "lucky", "db.seed.sample_data"
-
-print_done
-notice "Run 'lucky dev' to start the app"
\ No newline at end of file
diff --git a/fixtures/src_template/expected/script/system_check.cr b/fixtures/src_template/expected/script/system_check.cr
deleted file mode 100644
index b76720ba..00000000
--- a/fixtures/src_template/expected/script/system_check.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-require "./helpers/*"
-
-# Use this script to check the system for required tools and process that your app needs.
-# A few helper functions are provided to keep the code simple. See the
-# script/helpers/function_helpers.cr file for more examples.
-#
-# A few examples you might use here:
-# * 'lucky db.verify_connection' to test postgres can be connected
-# * Checking that elasticsearch, redis, or postgres is installed and/or booted
-# * Note: Booting additional processes for things like mail, background jobs, etc...
-# should go in your Procfile.dev.
-
-
-# CUSTOM PRE-BOOT CHECKS
-# example:
-# if command_not_running "redis-cli", "ping"
-# print_error "Redis is not running."
-# end
diff --git a/fixtures/src_template/expected/spec/setup/clean_database.cr b/fixtures/src_template/expected/spec/setup/clean_database.cr
deleted file mode 100644
index a1bc631c..00000000
--- a/fixtures/src_template/expected/spec/setup/clean_database.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- AppDatabase.truncate
-end
diff --git a/fixtures/src_template/expected/spec/setup/reset_emails.cr b/fixtures/src_template/expected/spec/setup/reset_emails.cr
deleted file mode 100644
index 140ab416..00000000
--- a/fixtures/src_template/expected/spec/setup/reset_emails.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- Carbon::DevAdapter.reset
-end
diff --git a/fixtures/src_template/expected/spec/setup/setup_database.cr b/fixtures/src_template/expected/spec/setup/setup_database.cr
deleted file mode 100644
index 393c6da3..00000000
--- a/fixtures/src_template/expected/spec/setup/setup_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-Db::Create.new(quiet: true).call
-Db::Migrate.new(quiet: true).call
diff --git a/fixtures/src_template/expected/spec/setup/start_app_server.cr b/fixtures/src_template/expected/spec/setup/start_app_server.cr
deleted file mode 100644
index 3a64c702..00000000
--- a/fixtures/src_template/expected/spec/setup/start_app_server.cr
+++ /dev/null
@@ -1,9 +0,0 @@
-app_server = AppServer.new
-
-spawn do
- app_server.listen
-end
-
-Spec.after_suite do
- app_server.close
-end
diff --git a/fixtures/src_template/expected/spec/spec_helper.cr b/fixtures/src_template/expected/spec/spec_helper.cr
deleted file mode 100644
index d876014d..00000000
--- a/fixtures/src_template/expected/spec/spec_helper.cr
+++ /dev/null
@@ -1,19 +0,0 @@
-ENV["LUCKY_ENV"] = "test"
-ENV["DEV_PORT"] = "5001"
-require "spec"
-require "../src/app"
-require "./support/**"
-require "../db/migrations/**"
-
-# Add/modify files in spec/setup to start/configure programs or run hooks
-#
-# By default there are scripts for setting up and cleaning the database,
-# configuring LuckyFlow, starting the app server, etc.
-require "./setup/**"
-
-include Carbon::Expectations
-include Lucky::RequestExpectations
-
-Avram::Migrator::Runner.new.ensure_migrated!
-Avram::SchemaEnforcer.ensure_correct_column_mappings!
-Habitat.raise_if_missing_settings!
diff --git a/fixtures/src_template/expected/spec/support/.keep b/fixtures/src_template/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/spec/support/api_client.cr b/fixtures/src_template/expected/spec/support/api_client.cr
deleted file mode 100644
index 46d449a8..00000000
--- a/fixtures/src_template/expected/spec/support/api_client.cr
+++ /dev/null
@@ -1,12 +0,0 @@
-class ApiClient < Lucky::BaseHTTPClient
- app AppServer.new
-
- def initialize
- super
- headers("Content-Type": "application/json")
- end
-
- def self.auth(user : User)
- new.headers("Authorization": UserToken.generate(user))
- end
-end
diff --git a/fixtures/src_template/expected/spec/support/factories/.keep b/fixtures/src_template/expected/spec/support/factories/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/actions/api_action.cr b/fixtures/src_template/expected/src/actions/api_action.cr
deleted file mode 100644
index a16fd09e..00000000
--- a/fixtures/src_template/expected/src/actions/api_action.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-# Include modules and add methods that are for all API requests
-abstract class ApiAction < Lucky::Action
- # APIs typically do not need to send cookie/session data.
- # Remove this line if you want to send cookies in the response header.
- disable_cookies
- accepted_formats [:json]
-
- include Api::Auth::Helpers
-
- # By default all actions require sign in.
- # Add 'include Api::Auth::SkipRequireAuthToken' to your actions to allow all requests.
- include Api::Auth::RequireAuthToken
-
- # By default all actions are required to use underscores to separate words.
- # Add 'include Lucky::SkipRouteStyleCheck' to your actions if you wish to ignore this check for specific routes.
- include Lucky::EnforceUnderscoredRoute
-end
diff --git a/fixtures/src_template/expected/src/actions/errors/show.cr b/fixtures/src_template/expected/src/actions/errors/show.cr
deleted file mode 100644
index a80eaa4d..00000000
--- a/fixtures/src_template/expected/src/actions/errors/show.cr
+++ /dev/null
@@ -1,42 +0,0 @@
-# This class handles error responses and reporting.
-#
-# https://luckyframework.org/guides/http-and-routing/error-handling
-class Errors::Show < Lucky::ErrorAction
- DEFAULT_MESSAGE = "Something went wrong."
- default_format :json
- dont_report [Lucky::RouteNotFoundError, Avram::RecordNotFoundError]
-
- def render(error : Lucky::RouteNotFoundError | Avram::RecordNotFoundError)
- error_json "Not found", status: 404
- end
-
- # When an InvalidOperationError is raised, show a helpful error with the
- # param that is invalid, and what was wrong with it.
- def render(error : Avram::InvalidOperationError)
- error_json \
- message: error.renderable_message,
- details: error.renderable_details,
- param: error.invalid_attribute_name,
- status: 400
- end
-
- # Always keep this below other 'render' methods or it may override your
- # custom 'render' methods.
- def render(error : Lucky::RenderableError)
- error_json error.renderable_message, status: error.renderable_status
- end
-
- # If none of the 'render' methods return a response for the raised Exception,
- # Lucky will use this method.
- def default_render(error : Exception) : Lucky::Response
- error_json DEFAULT_MESSAGE, status: 500
- end
-
- private def error_json(message : String, status : Int, details = nil, param = nil)
- json ErrorSerializer.new(message: message, details: details, param: param), status: status
- end
-
- private def report(error : Exception) : Nil
- # Send to Rollbar, send an email, etc.
- end
-end
diff --git a/fixtures/src_template/expected/src/actions/home/index.cr b/fixtures/src_template/expected/src/actions/home/index.cr
deleted file mode 100644
index 5a72b779..00000000
--- a/fixtures/src_template/expected/src/actions/home/index.cr
+++ /dev/null
@@ -1,7 +0,0 @@
-class Home::Index < ApiAction
- include Api::Auth::SkipRequireAuthToken
-
- get "/" do
- json({hello: "Hello World from Home::Index"})
- end
-end
diff --git a/fixtures/src_template/expected/src/actions/mixins/.keep b/fixtures/src_template/expected/src/actions/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/app.cr b/fixtures/src_template/expected/src/app.cr
deleted file mode 100644
index a658febc..00000000
--- a/fixtures/src_template/expected/src/app.cr
+++ /dev/null
@@ -1,20 +0,0 @@
-require "./shards"
-
-require "../config/server"
-require "./app_database"
-require "../config/**"
-require "./models/base_model"
-require "./models/mixins/**"
-require "./models/**"
-require "./queries/mixins/**"
-require "./queries/**"
-require "./operations/mixins/**"
-require "./operations/**"
-require "./serializers/base_serializer"
-require "./serializers/**"
-require "./emails/base_email"
-require "./emails/**"
-require "./actions/mixins/**"
-require "./actions/**"
-require "../db/migrations/**"
-require "./app_server"
\ No newline at end of file
diff --git a/fixtures/src_template/expected/src/app_database.cr b/fixtures/src_template/expected/src/app_database.cr
deleted file mode 100644
index 0efd4f50..00000000
--- a/fixtures/src_template/expected/src/app_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-class AppDatabase < Avram::Database
-end
diff --git a/fixtures/src_template/expected/src/app_server.cr b/fixtures/src_template/expected/src/app_server.cr
deleted file mode 100644
index 53f483d1..00000000
--- a/fixtures/src_template/expected/src/app_server.cr
+++ /dev/null
@@ -1,28 +0,0 @@
-class AppServer < Lucky::BaseAppServer
- # Learn about middleware with HTTP::Handlers:
- # https://luckyframework.org/guides/http-and-routing/http-handlers
- def middleware : Array(HTTP::Handler)
- [
- Lucky::RequestIdHandler.new,
- Lucky::ForceSSLHandler.new,
- Lucky::HttpMethodOverrideHandler.new,
- Lucky::LogHandler.new,
- Lucky::ErrorHandler.new(action: Errors::Show),
- Lucky::RemoteIpHandler.new,
- Lucky::RouteHandler.new,
-
- # Disabled in API mode:
- # Lucky::StaticCompressionHandler.new("./public", file_ext: "gz", content_encoding: "gzip"),
- # Lucky::StaticFileHandler.new("./public", fallthrough: false, directory_listing: false),
- Lucky::RouteNotFoundHandler.new,
- ] of HTTP::Handler
- end
-
- def protocol
- "http"
- end
-
- def listen
- server.listen(host, port, reuse_port: false)
- end
-end
diff --git a/fixtures/src_template/expected/src/emails/base_email.cr b/fixtures/src_template/expected/src/emails/base_email.cr
deleted file mode 100644
index 656f4f11..00000000
--- a/fixtures/src_template/expected/src/emails/base_email.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# Learn about sending emails
-# https://luckyframework.org/guides/emails/sending-emails-with-carbon
-abstract class BaseEmail < Carbon::Email
- # You can add defaults using the 'inherited' hook
- #
- # Example:
- #
- # macro inherited
- # from default_from
- # end
- #
- # def default_from
- # Carbon::Address.new("support@app.com")
- # end
-end
diff --git a/fixtures/src_template/expected/src/models/base_model.cr b/fixtures/src_template/expected/src/models/base_model.cr
deleted file mode 100644
index 6bafeb84..00000000
--- a/fixtures/src_template/expected/src/models/base_model.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-abstract class BaseModel < Avram::Model
- def self.database : Avram::Database.class
- AppDatabase
- end
-end
diff --git a/fixtures/src_template/expected/src/models/mixins/.keep b/fixtures/src_template/expected/src/models/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/operations/.keep b/fixtures/src_template/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/operations/mixins/.keep b/fixtures/src_template/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/queries/.keep b/fixtures/src_template/expected/src/queries/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/queries/mixins/.keep b/fixtures/src_template/expected/src/queries/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/serializers/.keep b/fixtures/src_template/expected/src/serializers/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/src/serializers/base_serializer.cr b/fixtures/src_template/expected/src/serializers/base_serializer.cr
deleted file mode 100644
index e769f5c0..00000000
--- a/fixtures/src_template/expected/src/serializers/base_serializer.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-abstract class BaseSerializer
- include Lucky::Serializable
-
- def self.for_collection(collection : Enumerable, *args, **named_args) : Array(self)
- collection.map do |object|
- new(object, *args, **named_args)
- end
- end
-
- def self.for_collection(collection : Enumerable, pages : Lucky::Paginator, *args, **named_args)
- {
- "items" => collection.map do |object|
- new(object, *args, **named_args)
- end,
- "pagination" => PaginationSerializer.new(pages),
- }
- end
-end
diff --git a/fixtures/src_template/expected/src/serializers/error_serializer.cr b/fixtures/src_template/expected/src/serializers/error_serializer.cr
deleted file mode 100644
index b7b55283..00000000
--- a/fixtures/src_template/expected/src/serializers/error_serializer.cr
+++ /dev/null
@@ -1,14 +0,0 @@
-# This is the default error serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class ErrorSerializer < BaseSerializer
- def initialize(
- @message : String,
- @details : String? = nil,
- @param : String? = nil, # so you can track which param (if any) caused the problem
- )
- end
-
- def render
- {message: @message, param: @param, details: @details}
- end
-end
diff --git a/fixtures/src_template/expected/src/serializers/pagination_serializer.cr b/fixtures/src_template/expected/src/serializers/pagination_serializer.cr
deleted file mode 100644
index 9e44788c..00000000
--- a/fixtures/src_template/expected/src/serializers/pagination_serializer.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# This is the default pagination serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class PaginationSerializer < BaseSerializer
- def initialize(@pages : Lucky::Paginator)
- end
-
- def render
- {
- next_page: @pages.path_to_next,
- previous_page: @pages.path_to_previous,
- total_items: @pages.item_count,
- total_pages: @pages.total,
- }
- end
-end
diff --git a/fixtures/src_template/expected/src/shards.cr b/fixtures/src_template/expected/src/shards.cr
deleted file mode 100644
index 7cadec18..00000000
--- a/fixtures/src_template/expected/src/shards.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-# Load .env file before any other config or app code
-require "lucky_env"
-LuckyEnv.load?(".env")
-
-# Require your shards here
-require "lucky"
-require "avram/lucky"
-require "carbon"
-require "authentic"
-require "jwt"
diff --git a/fixtures/src_template/expected/src/start_server.cr b/fixtures/src_template/expected/src/start_server.cr
deleted file mode 100644
index de8af78e..00000000
--- a/fixtures/src_template/expected/src/start_server.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-require "./app"
-
-Habitat.raise_if_missing_settings!
-
-if LuckyEnv.development?
- Avram::Migrator::Runner.new.ensure_migrated!
- Avram::SchemaEnforcer.ensure_correct_column_mappings!
-end
-
-app_server = AppServer.new
-puts "Listening on http://#{app_server.host}:#{app_server.port}"
-
-Signal::INT.trap do
- app_server.close
-end
-
-app_server.listen
diff --git a/fixtures/src_template/expected/src/test_project.cr b/fixtures/src_template/expected/src/test_project.cr
deleted file mode 100644
index 68e1a8d2..00000000
--- a/fixtures/src_template/expected/src/test_project.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-# Typically you will not use or modify this file. 'shards build' and some
-# other crystal tools will sometimes use this.
-#
-# When this file is compiled/run it will require and run 'start_server',
-# which as its name implies will start the server for you app.
-require "./start_server"
diff --git a/fixtures/src_template/expected/tasks.cr b/fixtures/src_template/expected/tasks.cr
deleted file mode 100644
index 5a892d4d..00000000
--- a/fixtures/src_template/expected/tasks.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file loads your app and all your tasks when running 'lucky'
-#
-# Run 'lucky --help' to see all available tasks.
-#
-# Learn to create your own tasks:
-# https://luckyframework.org/guides/command-line-tasks/custom-tasks
-
-# See `LuckyEnv#task?`
-ENV["LUCKY_TASK"] = "true"
-
-# Load Lucky and the app (actions, models, etc.)
-require "./src/app"
-require "lucky_task"
-
-# You can add your own tasks here in the ./tasks folder
-require "./tasks/**"
-
-# Load migrations
-require "./db/migrations/**"
-
-# Load Lucky tasks (dev, routes, etc.)
-require "lucky/tasks/**"
-require "avram/lucky/tasks"
-
-LuckyTask::Runner.run
diff --git a/fixtures/src_template/expected/tasks/.keep b/fixtures/src_template/expected/tasks/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template/expected/tasks/db/seed/required_data.cr b/fixtures/src_template/expected/tasks/db/seed/required_data.cr
deleted file mode 100644
index d866040f..00000000
--- a/fixtures/src_template/expected/tasks/db/seed/required_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add seeds here that are *required* for your app to work.
-# For example, you might need at least one admin user or you might need at least
-# one category for your blog posts for the app to work.
-#
-# Use `Db::Seed::SampleData` if your only want to add sample data helpful for
-# development.
-class Db::Seed::RequiredData < LuckyTask::Task
- summary "Add database records required for the app to work"
-
- def call
- # Using a Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- #
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- #
- # unless UserQuery.new.email("me@example.com").first?
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- # end
- puts "Done adding required data"
- end
-end
diff --git a/fixtures/src_template/expected/tasks/db/seed/sample_data.cr b/fixtures/src_template/expected/tasks/db/seed/sample_data.cr
deleted file mode 100644
index 231d7e8d..00000000
--- a/fixtures/src_template/expected/tasks/db/seed/sample_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add sample data helpful for development, e.g. (fake users, blog posts, etc.)
-#
-# Use `Db::Seed::RequiredData` if you need to create data *required* for your
-# app to work.
-class Db::Seed::SampleData < LuckyTask::Task
- summary "Add sample database records helpful for development"
-
- def call
- # Using an Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- # ```
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # ```
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- # ```
- # if UserQuery.new.email("me@example.com").none?
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # end
- # ```
- puts "Done adding sample data"
- end
-end
diff --git a/fixtures/src_template__api_only/expected/.crystal-version b/fixtures/src_template__api_only/expected/.crystal-version
deleted file mode 100644
index 41c11ffb..00000000
--- a/fixtures/src_template__api_only/expected/.crystal-version
+++ /dev/null
@@ -1 +0,0 @@
-1.16.1
diff --git a/fixtures/src_template__api_only/expected/.env b/fixtures/src_template__api_only/expected/.env
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/.github/workflows/ci.yml b/fixtures/src_template__api_only/expected/.github/workflows/ci.yml
deleted file mode 100644
index 67005cad..00000000
--- a/fixtures/src_template__api_only/expected/.github/workflows/ci.yml
+++ /dev/null
@@ -1,88 +0,0 @@
-name: test-project CI
-
-on:
- push:
- branches: "*"
- pull_request:
- branches: "*"
-
-jobs:
- check-format:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental }}
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
- - name: Format
- run: crystal tool format --check
-
- specs:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- env:
- LUCKY_ENV: test
- DB_HOST: localhost
- continue-on-error: ${{ matrix.experimental }}
- services:
- postgres:
- image: postgres:14-alpine
- env:
- POSTGRES_PASSWORD: postgres
- ports:
- - 5432:5432
- # Set health checks to wait until postgres has started
- options: >-
- --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
-
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
-
- - name: Set up Crystal cache
- uses: actions/cache@v4
- id: crystal-cache
- with:
- path: |
- ~/.cache/crystal
- lib
- key: ${{ runner.os }}-crystal-${{ hashFiles('**/shard.lock') }}
- restore-keys: |
- ${{ runner.os }}-crystal-
-
- - name: Install shards
- if: steps.crystal-cache.outputs.cache-hit != 'true'
- run: shards check || shards install
-
- - name: Build lucky_tasks
- run: crystal build tasks.cr -o ./lucky_tasks
-
- - name: Prepare database
- run: |
- ./lucky_tasks db.create
- ./lucky_tasks db.migrate
- ./lucky_tasks db.seed.required_data
-
- - name: Run tests
- run: crystal spec
\ No newline at end of file
diff --git a/fixtures/src_template__api_only/expected/Procfile b/fixtures/src_template__api_only/expected/Procfile
deleted file mode 100644
index e524d70d..00000000
--- a/fixtures/src_template__api_only/expected/Procfile
+++ /dev/null
@@ -1,2 +0,0 @@
-web: bin/app
-release: lucky db.migrate
diff --git a/fixtures/src_template__api_only/expected/Procfile.dev b/fixtures/src_template__api_only/expected/Procfile.dev
deleted file mode 100644
index dc39e8fe..00000000
--- a/fixtures/src_template__api_only/expected/Procfile.dev
+++ /dev/null
@@ -1,2 +0,0 @@
-system_check: crystal script/system_check.cr
-web: lucky watch
diff --git a/fixtures/src_template__api_only/expected/README.md b/fixtures/src_template__api_only/expected/README.md
deleted file mode 100644
index da2d97cc..00000000
--- a/fixtures/src_template__api_only/expected/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# test-project
-
-This is a project written using [Lucky](https://luckyframework.org). Enjoy!
-
-### Setting up the project
-
-1. [Install required dependencies](https://luckyframework.org/guides/getting-started/installing#install-required-dependencies)
-1. Update database settings in `config/database.cr`
-1. Run `script/setup`
-1. Run `lucky dev` to start the app
-
-### Using Docker for development
-
-1. [Install Docker](https://docs.docker.com/engine/install/)
-1. Run `docker compose up`
-
-The Docker container will boot all of the necessary components needed to run your Lucky application.
-To configure the container, update the `docker-compose.yml` file, and the `docker/development.dockerfile` file.
-
-
-### Learning Lucky
-
-Lucky uses the [Crystal](https://crystal-lang.org) programming language. You can learn about Lucky from the [Lucky Guides](https://luckyframework.org/guides/getting-started/why-lucky).
diff --git a/fixtures/src_template__api_only/expected/config/application.cr b/fixtures/src_template__api_only/expected/config/application.cr
deleted file mode 100644
index c807149a..00000000
--- a/fixtures/src_template__api_only/expected/config/application.cr
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file may be used for custom Application configurations.
-# It will be loaded before other config files.
-#
-# Read more on configuration:
-# https://luckyframework.org/guides/getting-started/configuration#configuring-your-own-code
-
-# Use this code as an example:
-#
-# ```
-# module Application
-# Habitat.create do
-# setting support_email : String
-# setting lock_with_basic_auth : Bool
-# end
-# end
-#
-# Application.configure do |settings|
-# settings.support_email = "support@myapp.io"
-# settings.lock_with_basic_auth = LuckyEnv.staging?
-# end
-#
-# # In your application, call
-# # `Application.settings.support_email` anywhere you need it.
-# ```
diff --git a/fixtures/src_template__api_only/expected/config/colors.cr b/fixtures/src_template__api_only/expected/config/colors.cr
deleted file mode 100644
index 761ae940..00000000
--- a/fixtures/src_template__api_only/expected/config/colors.cr
+++ /dev/null
@@ -1,4 +0,0 @@
-# This enables the color output when in development or test
-# Check out the Colorize docs for more information
-# https://crystal-lang.org/api/Colorize.html
-Colorize.enabled = LuckyEnv.development? || LuckyEnv.test?
diff --git a/fixtures/src_template__api_only/expected/config/cookies.cr b/fixtures/src_template__api_only/expected/config/cookies.cr
deleted file mode 100644
index 2d5055f2..00000000
--- a/fixtures/src_template__api_only/expected/config/cookies.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-require "./server"
-
-Lucky::Session.configure do |settings|
- settings.key = "_test_project_session"
-end
-
-Lucky::CookieJar.configure do |settings|
- settings.on_set = ->(cookie : HTTP::Cookie) {
- # If ForceSSLHandler is enabled, only send cookies over HTTPS
- cookie.secure(Lucky::ForceSSLHandler.settings.enabled)
-
- # By default, don't allow reading cookies with JavaScript
- cookie.http_only(true)
-
- # Restrict cookies to a first-party or same-site context
- cookie.samesite(:lax)
-
- # Set all cookies to the root path by default
- cookie.path("/")
-
- # You can set other defaults for cookies here. For example:
- #
- # cookie.expires(1.year.from_now).domain("mydomain.com")
- }
-end
diff --git a/fixtures/src_template__api_only/expected/config/database.cr b/fixtures/src_template__api_only/expected/config/database.cr
deleted file mode 100644
index f614299a..00000000
--- a/fixtures/src_template__api_only/expected/config/database.cr
+++ /dev/null
@@ -1,29 +0,0 @@
-database_name = "test_project_#{LuckyEnv.environment}"
-
-AppDatabase.configure do |settings|
- if LuckyEnv.production?
- settings.credentials = Avram::Credentials.parse(ENV["DATABASE_URL"])
- else
- settings.credentials = Avram::Credentials.parse?(ENV["DATABASE_URL"]?) || Avram::Credentials.new(
- database: database_name,
- hostname: ENV["DB_HOST"]? || "localhost",
- port: ENV["DB_PORT"]?.try(&.to_i) || 5432,
- # Some common usernames are "postgres", "root", or your system username (run 'whoami')
- username: ENV["DB_USERNAME"]? || "postgres",
- # Some Postgres installations require no password. Use "" if that is the case.
- password: ENV["DB_PASSWORD"]? || "postgres"
- )
- end
-end
-
-Avram.configure do |settings|
- settings.database_to_migrate = AppDatabase
-
- # In production, allow lazy loading (N+1).
- # In development and test, raise an error if you forget to preload associations
- settings.lazy_load_enabled = LuckyEnv.production?
-
- # Always parse `Time` values with these specific formats.
- # Used for both database values, and datetime input fields.
- # settings.time_formats << "%F"
-end
diff --git a/fixtures/src_template__api_only/expected/config/email.cr b/fixtures/src_template__api_only/expected/config/email.cr
deleted file mode 100644
index 7c875449..00000000
--- a/fixtures/src_template__api_only/expected/config/email.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-require "carbon_sendgrid_adapter"
-
-BaseEmail.configure do |settings|
- if LuckyEnv.production?
- # If you don't need to send emails, set the adapter to DevAdapter instead:
- #
- # settings.adapter = Carbon::DevAdapter.new
- #
- # If you do need emails, get a key from SendGrid and set an ENV variable
- send_grid_key = send_grid_key_from_env
- settings.adapter = Carbon::SendGridAdapter.new(api_key: send_grid_key)
- elsif LuckyEnv.development?
- settings.adapter = Carbon::DevAdapter.new(print_emails: true)
- else
- settings.adapter = Carbon::DevAdapter.new
- end
-end
-
-private def send_grid_key_from_env
- ENV["SEND_GRID_KEY"]? || raise_missing_key_message
-end
-
-private def raise_missing_key_message
- puts "Missing SEND_GRID_KEY. Set the SEND_GRID_KEY env variable to 'unused' if not sending emails, or set the SEND_GRID_KEY ENV var.".colorize.red
- exit(1)
-end
diff --git a/fixtures/src_template__api_only/expected/config/env.cr b/fixtures/src_template__api_only/expected/config/env.cr
deleted file mode 100644
index 3f364072..00000000
--- a/fixtures/src_template__api_only/expected/config/env.cr
+++ /dev/null
@@ -1,33 +0,0 @@
-# Environments are managed using `LuckyEnv`. By default, development, production
-# and test are supported. See
-# https://luckyframework.org/guides/getting-started/configuration for details.
-#
-# The default environment is development unless the environment variable
-# LUCKY_ENV is set.
-#
-# Example:
-# ```
-# LuckyEnv.environment # => "development"
-# LuckyEnv.development? # => true
-# LuckyEnv.production? # => false
-# LuckyEnv.test? # => false
-# ```
-#
-# New environments can be added using the `LuckyEnv.add_env` macro.
-#
-# Example:
-# ```
-# LuckyEnv.add_env :staging
-# LuckyEnv.staging? # => false
-# ```
-#
-# To determine whether or not a `LuckyTask` is currently running, you can use
-# the `LuckyEnv.task?` predicate.
-#
-# Example:
-# ```
-# LuckyEnv.task? # => false
-# ```
-
-# Add a staging environment.
-# LuckyEnv.add_env :staging
diff --git a/fixtures/src_template__api_only/expected/config/error_handler.cr b/fixtures/src_template__api_only/expected/config/error_handler.cr
deleted file mode 100644
index c6b736e3..00000000
--- a/fixtures/src_template__api_only/expected/config/error_handler.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Lucky::ErrorHandler.configure do |settings|
- settings.show_debug_output = !LuckyEnv.production?
-end
diff --git a/fixtures/src_template__api_only/expected/config/log.cr b/fixtures/src_template__api_only/expected/config/log.cr
deleted file mode 100644
index a43940d9..00000000
--- a/fixtures/src_template__api_only/expected/config/log.cr
+++ /dev/null
@@ -1,50 +0,0 @@
-require "file_utils"
-
-if LuckyEnv.test?
- # Logs to `tmp/test.log` so you can see what's happening without having
- # a bunch of log output in your spec results.
- FileUtils.mkdir_p("tmp")
-
- backend = Log::IOBackend.new(File.new("tmp/test.log", mode: "w"))
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
-elsif LuckyEnv.production?
- # Lucky uses JSON in production so logs can be searched more easily
- #
- # If you want logs like in development use 'Lucky::PrettyLogFormatter.proc'.
- backend = Log::IOBackend.new
- backend.formatter = Dexter::JSONLogFormatter.proc
- Log.dexter.configure(:info, backend)
-else
- # Use a pretty formatter printing to STDOUT in development
- backend = Log::IOBackend.new
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
- DB::Log.level = :info
-end
-
-# Lucky only logs when before/after pipes halt by redirecting, or rendering a
-# response. Pipes that run without halting are not logged.
-#
-# If you want to log every pipe that runs, set the log level to ':info'
-Lucky::ContinuedPipeLog.dexter.configure(:none)
-
-# Lucky only logs failed queries by default.
-#
-# Set the log to ':info' to log all queries
-Avram::QueryLog.dexter.configure(:none)
-
-# Subscribe to Pulsar events to log when queries are made,
-# queries fail, or save operations fail. Remove this to
-# disable these log events without disabling all logging.
-Avram.initialize_logging
-
-# Skip logging static assets requests in development
-Lucky::LogHandler.configure do |settings|
- if LuckyEnv.development?
- settings.skip_if = ->(context : HTTP::Server::Context) {
- context.request.method.downcase == "get" &&
- context.request.resource.starts_with?(/\/css\/|\/js\/|\/assets\/|\/favicon\.ico/)
- }
- end
-end
diff --git a/fixtures/src_template__api_only/expected/config/route_helper.cr b/fixtures/src_template__api_only/expected/config/route_helper.cr
deleted file mode 100644
index ede1f328..00000000
--- a/fixtures/src_template__api_only/expected/config/route_helper.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is used when generating URLs for your application
-Lucky::RouteHelper.configure do |settings|
- if LuckyEnv.production?
- # Example: https://my_app.com
- settings.base_uri = ENV.fetch("APP_DOMAIN")
- else
- # Set domain to the default host/port in development/test
- settings.base_uri = "http://localhost:#{Lucky::ServerSettings.port}"
- end
-end
diff --git a/fixtures/src_template__api_only/expected/config/server.cr b/fixtures/src_template__api_only/expected/config/server.cr
deleted file mode 100644
index b7cca25c..00000000
--- a/fixtures/src_template__api_only/expected/config/server.cr
+++ /dev/null
@@ -1,68 +0,0 @@
-# Here is where you configure the Lucky server
-#
-# Look at config/route_helper.cr if you want to change the domain used when
-# generating links with `Action.url`.
-Lucky::Server.configure do |settings|
- if LuckyEnv.production?
- settings.secret_key_base = secret_key_from_env
- settings.host = "0.0.0.0"
- settings.port = ENV["PORT"].to_i
- settings.gzip_enabled = true
- # By default certain content types will be gzipped.
- # For a full list look in
- # https://github.com/luckyframework/lucky/blob/main/src/lucky/server.cr
- # To add additional extensions do something like this:
- # settings.gzip_content_types << "content/type"
- else
- settings.secret_key_base = "1234567890"
- # Change host/port in config/watch.yml
- # Alternatively, you can set the DEV_PORT env to set the port for local development
- settings.host = Lucky::ServerSettings.host
- settings.port = Lucky::ServerSettings.port
- end
-
- # Configure the asset build system (default is Vite)
- settings.asset_build_system = Lucky::AssetBuilder::Vite.new
-
- # Configure asset host for Vite
- if LuckyEnv.development?
- # In development, Vite serves assets from its dev server
- settings.asset_host = "http://localhost:3001"
- elsif LuckyEnv.production?
- # In production, Lucky serves the built assets
- # You could also use a CDN here:
- # settings.asset_host = "https://mycdnhost.com"
- settings.asset_host = ""
- else
- settings.asset_host = ""
- end
-end
-
-Lucky::ForceSSLHandler.configure do |settings|
- # To force SSL in production, uncomment the lines below.
- # This will cause http requests to be redirected to https:
- #
- # settings.enabled = LuckyEnv.production?
- # settings.strict_transport_security = {max_age: 1.year, include_subdomains: true}
- #
- # Or, leave it disabled:
- settings.enabled = false
-end
-
-# Set a unique ID for each HTTP request.
-# To enable the request ID, uncomment the lines below.
-# You can set your own custom String, or use a random UUID.
-# Lucky::RequestIdHandler.configure do |settings|
-# settings.set_request_id = ->(context : HTTP::Server::Context) {
-# UUID.random.to_s
-# }
-# end
-
-private def secret_key_from_env
- ENV["SECRET_KEY_BASE"]? || raise_missing_secret_key_in_production
-end
-
-private def raise_missing_secret_key_in_production
- puts "Please set the SECRET_KEY_BASE environment variable. You can generate a secret key with 'lucky gen.secret_key'".colorize.red
- exit(1)
-end
\ No newline at end of file
diff --git a/fixtures/src_template__api_only/expected/config/watch.yml b/fixtures/src_template__api_only/expected/config/watch.yml
deleted file mode 100644
index 3a59b410..00000000
--- a/fixtures/src_template__api_only/expected/config/watch.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-host: 127.0.0.1
-port: 3000
-reload_port: 3001
diff --git a/fixtures/src_template__api_only/expected/db/migrations/.keep b/fixtures/src_template__api_only/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/docker-compose.yml b/fixtures/src_template__api_only/expected/docker-compose.yml
deleted file mode 100644
index d00779db..00000000
--- a/fixtures/src_template__api_only/expected/docker-compose.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-version: "3.8"
-services:
- lucky:
- build:
- context: .
- dockerfile: docker/development.dockerfile
- environment:
- DATABASE_URL: postgres://lucky:password@postgres:5432/lucky
- DEV_HOST: "0.0.0.0"
- volumes:
- - .:/app
- - node_modules:/app/node_modules
- - shards_lib:/app/lib
- - app_bin:/app/bin
- - build_cache:/root/.cache
- depends_on:
- - postgres
- ports:
- - 3000:3000 # This is the Lucky Server port
- - 3001:3001 # This is the Lucky watcher reload port
-
- entrypoint: ["docker/dev_entrypoint.sh"]
-
- postgres:
- image: postgres:14-alpine
- environment:
- POSTGRES_USER: lucky
- POSTGRES_PASSWORD: password
- POSTGRES_DB: lucky
- volumes:
- - postgres_data:/var/lib/postgresql/data
- ports:
- # The postgres database container is exposed on the host at port 6543 to
- # allow connecting directly to it with postgres clients. The port differs
- # from the postgres default to avoid conflict with existing postgres
- # servers. Connect to a running postgres container with:
- # postgres://lucky:password@localhost:6543/lucky
- - 6543:5432
-
-volumes:
- postgres_data:
- node_modules:
- shards_lib:
- app_bin:
- build_cache:
diff --git a/fixtures/src_template__api_only/expected/docker/dev_entrypoint.sh b/fixtures/src_template__api_only/expected/docker/dev_entrypoint.sh
deleted file mode 100755
index f5aab877..00000000
--- a/fixtures/src_template__api_only/expected/docker/dev_entrypoint.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# This is the entrypoint script used for development docker workflows.
-# By default it will:
-# - Install dependencies.
-# - Run migrations.
-# - Start the dev server.
-# It also accepts any commands to be run instead.
-
-
-warnfail () {
- echo "$@" >&2
- exit 1
-}
-
-case ${1:-} in
- "") # If no arguments are provided, start lucky dev server.
- ;;
-
- *) # If any arguments are provided, execute them instead.
- exec "$@"
-esac
-
-if ! [ -d bin ] ; then
- echo 'Creating bin directory'
- mkdir bin
-fi
-if ! shards check ; then
- echo 'Installing shards...'
- shards install
-fi
-
-echo 'Waiting for postgres to be available...'
-./docker/wait-for-it.sh -q postgres:5432
-
-if ! psql -d "$DATABASE_URL" -c '\d migrations' > /dev/null ; then
- echo 'Finishing database setup...'
- lucky db.migrate
-fi
-
-echo 'Starting lucky dev server...'
-exec lucky dev
diff --git a/fixtures/src_template__api_only/expected/docker/development.dockerfile b/fixtures/src_template__api_only/expected/docker/development.dockerfile
deleted file mode 100644
index a4e5b267..00000000
--- a/fixtures/src_template__api_only/expected/docker/development.dockerfile
+++ /dev/null
@@ -1,25 +0,0 @@
-FROM crystallang/crystal:1.16.1
-
-# Install utilities required to make this Dockerfile run
-RUN apt-get update && \
- apt-get install -y wget
-
-# Apt installs:
-# - Postgres cli tools are required for lucky-cli.
-# - tmux is required for the Overmind process manager.
-RUN apt-get update && \
- apt-get install -y postgresql-client tmux && \
- rm -rf /var/lib/apt/lists/*
-
-# Install lucky cli
-WORKDIR /lucky/cli
-RUN git clone https://github.com/luckyframework/lucky_cli . && \
- git checkout v1.3.0 && \
- shards build --without-development && \
- cp bin/lucky /usr/bin
-
-WORKDIR /app
-ENV DATABASE_URL=postgres://postgres:postgres@host.docker.internal:5432/postgres
-EXPOSE 3000
-EXPOSE 3001
-
diff --git a/fixtures/src_template__api_only/expected/docker/wait-for-it.sh b/fixtures/src_template__api_only/expected/docker/wait-for-it.sh
deleted file mode 100755
index 06e0638c..00000000
--- a/fixtures/src_template__api_only/expected/docker/wait-for-it.sh
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/bash
-#
-# Pulled from https://github.com/vishnubob/wait-for-it on 2022-02-28.
-# Licensed under the MIT license as of 81b1373f.
-#
-# Below this line, wait-for-it is the original work of the author.
-#
-# Use this script to test if a given TCP host/port are available
-
-WAITFORIT_cmdname=${0##*/}
-
-echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
-
-usage()
-{
- cat << USAGE >&2
-Usage:
- $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
- -h HOST | --host=HOST Host or IP under test
- -p PORT | --port=PORT TCP port under test
- Alternatively, you specify the host and port as host:port
- -s | --strict Only execute subcommand if the test succeeds
- -q | --quiet Don't output any status messages
- -t TIMEOUT | --timeout=TIMEOUT
- Timeout in seconds, zero for no timeout
- -- COMMAND ARGS Execute command with args after the test finishes
-USAGE
- exit 1
-}
-
-wait_for()
-{
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- else
- echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
- fi
- WAITFORIT_start_ts=$(date +%s)
- while :
- do
- if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
- nc -z $WAITFORIT_HOST $WAITFORIT_PORT
- WAITFORIT_result=$?
- else
- (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
- WAITFORIT_result=$?
- fi
- if [[ $WAITFORIT_result -eq 0 ]]; then
- WAITFORIT_end_ts=$(date +%s)
- echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
- break
- fi
- sleep 1
- done
- return $WAITFORIT_result
-}
-
-wait_for_wrapper()
-{
- # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
- if [[ $WAITFORIT_QUIET -eq 1 ]]; then
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- else
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- fi
- WAITFORIT_PID=$!
- trap "kill -INT -$WAITFORIT_PID" INT
- wait $WAITFORIT_PID
- WAITFORIT_RESULT=$?
- if [[ $WAITFORIT_RESULT -ne 0 ]]; then
- echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- fi
- return $WAITFORIT_RESULT
-}
-
-# process arguments
-while [[ $# -gt 0 ]]
-do
- case "$1" in
- *:* )
- WAITFORIT_hostport=(${1//:/ })
- WAITFORIT_HOST=${WAITFORIT_hostport[0]}
- WAITFORIT_PORT=${WAITFORIT_hostport[1]}
- shift 1
- ;;
- --child)
- WAITFORIT_CHILD=1
- shift 1
- ;;
- -q | --quiet)
- WAITFORIT_QUIET=1
- shift 1
- ;;
- -s | --strict)
- WAITFORIT_STRICT=1
- shift 1
- ;;
- -h)
- WAITFORIT_HOST="$2"
- if [[ $WAITFORIT_HOST == "" ]]; then break; fi
- shift 2
- ;;
- --host=*)
- WAITFORIT_HOST="${1#*=}"
- shift 1
- ;;
- -p)
- WAITFORIT_PORT="$2"
- if [[ $WAITFORIT_PORT == "" ]]; then break; fi
- shift 2
- ;;
- --port=*)
- WAITFORIT_PORT="${1#*=}"
- shift 1
- ;;
- -t)
- WAITFORIT_TIMEOUT="$2"
- if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
- shift 2
- ;;
- --timeout=*)
- WAITFORIT_TIMEOUT="${1#*=}"
- shift 1
- ;;
- --)
- shift
- WAITFORIT_CLI=("$@")
- break
- ;;
- --help)
- usage
- ;;
- *)
- echoerr "Unknown argument: $1"
- usage
- ;;
- esac
-done
-
-if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
- echoerr "Error: you need to provide a host and port to test."
- usage
-fi
-
-WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
-WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
-WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
-WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
-
-# Check to see if timeout is from busybox?
-WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
-WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
-
-WAITFORIT_BUSYTIMEFLAG=""
-if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
- WAITFORIT_ISBUSY=1
- # Check if busybox timeout uses -t flag
- # (recent Alpine versions don't support -t anymore)
- if timeout &>/dev/stdout | grep -q -e '-t '; then
- WAITFORIT_BUSYTIMEFLAG="-t"
- fi
-else
- WAITFORIT_ISBUSY=0
-fi
-
-if [[ $WAITFORIT_CHILD -gt 0 ]]; then
- wait_for
- WAITFORIT_RESULT=$?
- exit $WAITFORIT_RESULT
-else
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- wait_for_wrapper
- WAITFORIT_RESULT=$?
- else
- wait_for
- WAITFORIT_RESULT=$?
- fi
-fi
-
-if [[ $WAITFORIT_CLI != "" ]]; then
- if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
- echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
- exit $WAITFORIT_RESULT
- fi
- exec "${WAITFORIT_CLI[@]}"
-else
- exit $WAITFORIT_RESULT
-fi
-
diff --git a/fixtures/src_template__api_only/expected/script/helpers/function_helpers.cr b/fixtures/src_template__api_only/expected/script/helpers/function_helpers.cr
deleted file mode 100644
index 8abcb6a2..00000000
--- a/fixtures/src_template__api_only/expected/script/helpers/function_helpers.cr
+++ /dev/null
@@ -1,32 +0,0 @@
-require "colorize"
-
-# These are helper methods provided to help keep your code
-# clean. Add new methods, or alter these as needed.
-
-def notice(message : String) : Nil
- puts "\n▸ #{message}"
-end
-
-def print_done : Nil
- puts "✔ Done"
-end
-
-def print_error(message : String) : Nil
- puts "There is a problem with your system setup:\n".colorize.red.bold
- puts "#{message}\n".colorize.red.bold
- Process.exit(1)
-end
-
-def command_not_found(command : String) : Bool
- Process.find_executable(command).nil?
-end
-
-def command_not_running(command : String, *args) : Bool
- output = IO::Memory.new
- code = Process.run(command, args, output: output).exit_code
- code > 0
-end
-
-def run_command(command : String, *args) : Nil
- Process.run(command, args, output: STDOUT, error: STDERR, input: STDIN)
-end
diff --git a/fixtures/src_template__api_only/expected/script/setup.cr b/fixtures/src_template__api_only/expected/script/setup.cr
deleted file mode 100644
index f8d4a907..00000000
--- a/fixtures/src_template__api_only/expected/script/setup.cr
+++ /dev/null
@@ -1,28 +0,0 @@
-require "./helpers/*"
-
-notice "Running System Check"
-
-require "./system_check"
-
-print_done
-
-
-notice "Installing shards"
-run_command "shards", "install"
-
-if !File.exists?(".env")
- notice "No .env found. Creating one."
- File.touch ".env"
- print_done
-end
-
-notice "Setting up the database"
-
-run_command "lucky", "db.setup"
-
-notice "Seeding the database with required and sample records"
-run_command "lucky", "db.seed.required_data"
-run_command "lucky", "db.seed.sample_data"
-
-print_done
-notice "Run 'lucky dev' to start the app"
\ No newline at end of file
diff --git a/fixtures/src_template__api_only/expected/script/system_check.cr b/fixtures/src_template__api_only/expected/script/system_check.cr
deleted file mode 100644
index b76720ba..00000000
--- a/fixtures/src_template__api_only/expected/script/system_check.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-require "./helpers/*"
-
-# Use this script to check the system for required tools and process that your app needs.
-# A few helper functions are provided to keep the code simple. See the
-# script/helpers/function_helpers.cr file for more examples.
-#
-# A few examples you might use here:
-# * 'lucky db.verify_connection' to test postgres can be connected
-# * Checking that elasticsearch, redis, or postgres is installed and/or booted
-# * Note: Booting additional processes for things like mail, background jobs, etc...
-# should go in your Procfile.dev.
-
-
-# CUSTOM PRE-BOOT CHECKS
-# example:
-# if command_not_running "redis-cli", "ping"
-# print_error "Redis is not running."
-# end
diff --git a/fixtures/src_template__api_only/expected/spec/setup/clean_database.cr b/fixtures/src_template__api_only/expected/spec/setup/clean_database.cr
deleted file mode 100644
index a1bc631c..00000000
--- a/fixtures/src_template__api_only/expected/spec/setup/clean_database.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- AppDatabase.truncate
-end
diff --git a/fixtures/src_template__api_only/expected/spec/setup/reset_emails.cr b/fixtures/src_template__api_only/expected/spec/setup/reset_emails.cr
deleted file mode 100644
index 140ab416..00000000
--- a/fixtures/src_template__api_only/expected/spec/setup/reset_emails.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- Carbon::DevAdapter.reset
-end
diff --git a/fixtures/src_template__api_only/expected/spec/setup/setup_database.cr b/fixtures/src_template__api_only/expected/spec/setup/setup_database.cr
deleted file mode 100644
index 393c6da3..00000000
--- a/fixtures/src_template__api_only/expected/spec/setup/setup_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-Db::Create.new(quiet: true).call
-Db::Migrate.new(quiet: true).call
diff --git a/fixtures/src_template__api_only/expected/spec/setup/start_app_server.cr b/fixtures/src_template__api_only/expected/spec/setup/start_app_server.cr
deleted file mode 100644
index 3a64c702..00000000
--- a/fixtures/src_template__api_only/expected/spec/setup/start_app_server.cr
+++ /dev/null
@@ -1,9 +0,0 @@
-app_server = AppServer.new
-
-spawn do
- app_server.listen
-end
-
-Spec.after_suite do
- app_server.close
-end
diff --git a/fixtures/src_template__api_only/expected/spec/spec_helper.cr b/fixtures/src_template__api_only/expected/spec/spec_helper.cr
deleted file mode 100644
index d876014d..00000000
--- a/fixtures/src_template__api_only/expected/spec/spec_helper.cr
+++ /dev/null
@@ -1,19 +0,0 @@
-ENV["LUCKY_ENV"] = "test"
-ENV["DEV_PORT"] = "5001"
-require "spec"
-require "../src/app"
-require "./support/**"
-require "../db/migrations/**"
-
-# Add/modify files in spec/setup to start/configure programs or run hooks
-#
-# By default there are scripts for setting up and cleaning the database,
-# configuring LuckyFlow, starting the app server, etc.
-require "./setup/**"
-
-include Carbon::Expectations
-include Lucky::RequestExpectations
-
-Avram::Migrator::Runner.new.ensure_migrated!
-Avram::SchemaEnforcer.ensure_correct_column_mappings!
-Habitat.raise_if_missing_settings!
diff --git a/fixtures/src_template__api_only/expected/spec/support/.keep b/fixtures/src_template__api_only/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/spec/support/api_client.cr b/fixtures/src_template__api_only/expected/spec/support/api_client.cr
deleted file mode 100644
index ef251251..00000000
--- a/fixtures/src_template__api_only/expected/spec/support/api_client.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-class ApiClient < Lucky::BaseHTTPClient
- app AppServer.new
-
- def initialize
- super
- headers("Content-Type": "application/json")
- end
-end
diff --git a/fixtures/src_template__api_only/expected/spec/support/factories/.keep b/fixtures/src_template__api_only/expected/spec/support/factories/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/actions/api_action.cr b/fixtures/src_template__api_only/expected/src/actions/api_action.cr
deleted file mode 100644
index fac02c8b..00000000
--- a/fixtures/src_template__api_only/expected/src/actions/api_action.cr
+++ /dev/null
@@ -1,11 +0,0 @@
-# Include modules and add methods that are for all API requests
-abstract class ApiAction < Lucky::Action
- # APIs typically do not need to send cookie/session data.
- # Remove this line if you want to send cookies in the response header.
- disable_cookies
- accepted_formats [:json]
-
- # By default all actions are required to use underscores to separate words.
- # Add 'include Lucky::SkipRouteStyleCheck' to your actions if you wish to ignore this check for specific routes.
- include Lucky::EnforceUnderscoredRoute
-end
diff --git a/fixtures/src_template__api_only/expected/src/actions/errors/show.cr b/fixtures/src_template__api_only/expected/src/actions/errors/show.cr
deleted file mode 100644
index a80eaa4d..00000000
--- a/fixtures/src_template__api_only/expected/src/actions/errors/show.cr
+++ /dev/null
@@ -1,42 +0,0 @@
-# This class handles error responses and reporting.
-#
-# https://luckyframework.org/guides/http-and-routing/error-handling
-class Errors::Show < Lucky::ErrorAction
- DEFAULT_MESSAGE = "Something went wrong."
- default_format :json
- dont_report [Lucky::RouteNotFoundError, Avram::RecordNotFoundError]
-
- def render(error : Lucky::RouteNotFoundError | Avram::RecordNotFoundError)
- error_json "Not found", status: 404
- end
-
- # When an InvalidOperationError is raised, show a helpful error with the
- # param that is invalid, and what was wrong with it.
- def render(error : Avram::InvalidOperationError)
- error_json \
- message: error.renderable_message,
- details: error.renderable_details,
- param: error.invalid_attribute_name,
- status: 400
- end
-
- # Always keep this below other 'render' methods or it may override your
- # custom 'render' methods.
- def render(error : Lucky::RenderableError)
- error_json error.renderable_message, status: error.renderable_status
- end
-
- # If none of the 'render' methods return a response for the raised Exception,
- # Lucky will use this method.
- def default_render(error : Exception) : Lucky::Response
- error_json DEFAULT_MESSAGE, status: 500
- end
-
- private def error_json(message : String, status : Int, details = nil, param = nil)
- json ErrorSerializer.new(message: message, details: details, param: param), status: status
- end
-
- private def report(error : Exception) : Nil
- # Send to Rollbar, send an email, etc.
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/actions/home/index.cr b/fixtures/src_template__api_only/expected/src/actions/home/index.cr
deleted file mode 100644
index eb326da9..00000000
--- a/fixtures/src_template__api_only/expected/src/actions/home/index.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-class Home::Index < ApiAction
- get "/" do
- json({hello: "Hello World from Home::Index"})
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/actions/mixins/.keep b/fixtures/src_template__api_only/expected/src/actions/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/app.cr b/fixtures/src_template__api_only/expected/src/app.cr
deleted file mode 100644
index a658febc..00000000
--- a/fixtures/src_template__api_only/expected/src/app.cr
+++ /dev/null
@@ -1,20 +0,0 @@
-require "./shards"
-
-require "../config/server"
-require "./app_database"
-require "../config/**"
-require "./models/base_model"
-require "./models/mixins/**"
-require "./models/**"
-require "./queries/mixins/**"
-require "./queries/**"
-require "./operations/mixins/**"
-require "./operations/**"
-require "./serializers/base_serializer"
-require "./serializers/**"
-require "./emails/base_email"
-require "./emails/**"
-require "./actions/mixins/**"
-require "./actions/**"
-require "../db/migrations/**"
-require "./app_server"
\ No newline at end of file
diff --git a/fixtures/src_template__api_only/expected/src/app_database.cr b/fixtures/src_template__api_only/expected/src/app_database.cr
deleted file mode 100644
index 0efd4f50..00000000
--- a/fixtures/src_template__api_only/expected/src/app_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-class AppDatabase < Avram::Database
-end
diff --git a/fixtures/src_template__api_only/expected/src/app_server.cr b/fixtures/src_template__api_only/expected/src/app_server.cr
deleted file mode 100644
index 53f483d1..00000000
--- a/fixtures/src_template__api_only/expected/src/app_server.cr
+++ /dev/null
@@ -1,28 +0,0 @@
-class AppServer < Lucky::BaseAppServer
- # Learn about middleware with HTTP::Handlers:
- # https://luckyframework.org/guides/http-and-routing/http-handlers
- def middleware : Array(HTTP::Handler)
- [
- Lucky::RequestIdHandler.new,
- Lucky::ForceSSLHandler.new,
- Lucky::HttpMethodOverrideHandler.new,
- Lucky::LogHandler.new,
- Lucky::ErrorHandler.new(action: Errors::Show),
- Lucky::RemoteIpHandler.new,
- Lucky::RouteHandler.new,
-
- # Disabled in API mode:
- # Lucky::StaticCompressionHandler.new("./public", file_ext: "gz", content_encoding: "gzip"),
- # Lucky::StaticFileHandler.new("./public", fallthrough: false, directory_listing: false),
- Lucky::RouteNotFoundHandler.new,
- ] of HTTP::Handler
- end
-
- def protocol
- "http"
- end
-
- def listen
- server.listen(host, port, reuse_port: false)
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/emails/base_email.cr b/fixtures/src_template__api_only/expected/src/emails/base_email.cr
deleted file mode 100644
index 656f4f11..00000000
--- a/fixtures/src_template__api_only/expected/src/emails/base_email.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# Learn about sending emails
-# https://luckyframework.org/guides/emails/sending-emails-with-carbon
-abstract class BaseEmail < Carbon::Email
- # You can add defaults using the 'inherited' hook
- #
- # Example:
- #
- # macro inherited
- # from default_from
- # end
- #
- # def default_from
- # Carbon::Address.new("support@app.com")
- # end
-end
diff --git a/fixtures/src_template__api_only/expected/src/models/base_model.cr b/fixtures/src_template__api_only/expected/src/models/base_model.cr
deleted file mode 100644
index 6bafeb84..00000000
--- a/fixtures/src_template__api_only/expected/src/models/base_model.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-abstract class BaseModel < Avram::Model
- def self.database : Avram::Database.class
- AppDatabase
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/models/mixins/.keep b/fixtures/src_template__api_only/expected/src/models/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/operations/.keep b/fixtures/src_template__api_only/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/operations/mixins/.keep b/fixtures/src_template__api_only/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/queries/.keep b/fixtures/src_template__api_only/expected/src/queries/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/queries/mixins/.keep b/fixtures/src_template__api_only/expected/src/queries/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/serializers/.keep b/fixtures/src_template__api_only/expected/src/serializers/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/src/serializers/base_serializer.cr b/fixtures/src_template__api_only/expected/src/serializers/base_serializer.cr
deleted file mode 100644
index e769f5c0..00000000
--- a/fixtures/src_template__api_only/expected/src/serializers/base_serializer.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-abstract class BaseSerializer
- include Lucky::Serializable
-
- def self.for_collection(collection : Enumerable, *args, **named_args) : Array(self)
- collection.map do |object|
- new(object, *args, **named_args)
- end
- end
-
- def self.for_collection(collection : Enumerable, pages : Lucky::Paginator, *args, **named_args)
- {
- "items" => collection.map do |object|
- new(object, *args, **named_args)
- end,
- "pagination" => PaginationSerializer.new(pages),
- }
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/serializers/error_serializer.cr b/fixtures/src_template__api_only/expected/src/serializers/error_serializer.cr
deleted file mode 100644
index b7b55283..00000000
--- a/fixtures/src_template__api_only/expected/src/serializers/error_serializer.cr
+++ /dev/null
@@ -1,14 +0,0 @@
-# This is the default error serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class ErrorSerializer < BaseSerializer
- def initialize(
- @message : String,
- @details : String? = nil,
- @param : String? = nil, # so you can track which param (if any) caused the problem
- )
- end
-
- def render
- {message: @message, param: @param, details: @details}
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/serializers/pagination_serializer.cr b/fixtures/src_template__api_only/expected/src/serializers/pagination_serializer.cr
deleted file mode 100644
index 9e44788c..00000000
--- a/fixtures/src_template__api_only/expected/src/serializers/pagination_serializer.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# This is the default pagination serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class PaginationSerializer < BaseSerializer
- def initialize(@pages : Lucky::Paginator)
- end
-
- def render
- {
- next_page: @pages.path_to_next,
- previous_page: @pages.path_to_previous,
- total_items: @pages.item_count,
- total_pages: @pages.total,
- }
- end
-end
diff --git a/fixtures/src_template__api_only/expected/src/shards.cr b/fixtures/src_template__api_only/expected/src/shards.cr
deleted file mode 100644
index 1afc72cb..00000000
--- a/fixtures/src_template__api_only/expected/src/shards.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-# Load .env file before any other config or app code
-require "lucky_env"
-LuckyEnv.load?(".env")
-
-# Require your shards here
-require "lucky"
-require "avram/lucky"
-require "carbon"
diff --git a/fixtures/src_template__api_only/expected/src/start_server.cr b/fixtures/src_template__api_only/expected/src/start_server.cr
deleted file mode 100644
index de8af78e..00000000
--- a/fixtures/src_template__api_only/expected/src/start_server.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-require "./app"
-
-Habitat.raise_if_missing_settings!
-
-if LuckyEnv.development?
- Avram::Migrator::Runner.new.ensure_migrated!
- Avram::SchemaEnforcer.ensure_correct_column_mappings!
-end
-
-app_server = AppServer.new
-puts "Listening on http://#{app_server.host}:#{app_server.port}"
-
-Signal::INT.trap do
- app_server.close
-end
-
-app_server.listen
diff --git a/fixtures/src_template__api_only/expected/src/test_project.cr b/fixtures/src_template__api_only/expected/src/test_project.cr
deleted file mode 100644
index 68e1a8d2..00000000
--- a/fixtures/src_template__api_only/expected/src/test_project.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-# Typically you will not use or modify this file. 'shards build' and some
-# other crystal tools will sometimes use this.
-#
-# When this file is compiled/run it will require and run 'start_server',
-# which as its name implies will start the server for you app.
-require "./start_server"
diff --git a/fixtures/src_template__api_only/expected/tasks.cr b/fixtures/src_template__api_only/expected/tasks.cr
deleted file mode 100644
index 5a892d4d..00000000
--- a/fixtures/src_template__api_only/expected/tasks.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file loads your app and all your tasks when running 'lucky'
-#
-# Run 'lucky --help' to see all available tasks.
-#
-# Learn to create your own tasks:
-# https://luckyframework.org/guides/command-line-tasks/custom-tasks
-
-# See `LuckyEnv#task?`
-ENV["LUCKY_TASK"] = "true"
-
-# Load Lucky and the app (actions, models, etc.)
-require "./src/app"
-require "lucky_task"
-
-# You can add your own tasks here in the ./tasks folder
-require "./tasks/**"
-
-# Load migrations
-require "./db/migrations/**"
-
-# Load Lucky tasks (dev, routes, etc.)
-require "lucky/tasks/**"
-require "avram/lucky/tasks"
-
-LuckyTask::Runner.run
diff --git a/fixtures/src_template__api_only/expected/tasks/.keep b/fixtures/src_template__api_only/expected/tasks/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__api_only/expected/tasks/db/seed/required_data.cr b/fixtures/src_template__api_only/expected/tasks/db/seed/required_data.cr
deleted file mode 100644
index d866040f..00000000
--- a/fixtures/src_template__api_only/expected/tasks/db/seed/required_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add seeds here that are *required* for your app to work.
-# For example, you might need at least one admin user or you might need at least
-# one category for your blog posts for the app to work.
-#
-# Use `Db::Seed::SampleData` if your only want to add sample data helpful for
-# development.
-class Db::Seed::RequiredData < LuckyTask::Task
- summary "Add database records required for the app to work"
-
- def call
- # Using a Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- #
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- #
- # unless UserQuery.new.email("me@example.com").first?
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- # end
- puts "Done adding required data"
- end
-end
diff --git a/fixtures/src_template__api_only/expected/tasks/db/seed/sample_data.cr b/fixtures/src_template__api_only/expected/tasks/db/seed/sample_data.cr
deleted file mode 100644
index 231d7e8d..00000000
--- a/fixtures/src_template__api_only/expected/tasks/db/seed/sample_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add sample data helpful for development, e.g. (fake users, blog posts, etc.)
-#
-# Use `Db::Seed::RequiredData` if you need to create data *required* for your
-# app to work.
-class Db::Seed::SampleData < LuckyTask::Task
- summary "Add sample database records helpful for development"
-
- def call
- # Using an Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- # ```
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # ```
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- # ```
- # if UserQuery.new.email("me@example.com").none?
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # end
- # ```
- puts "Done adding sample data"
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/.crystal-version b/fixtures/src_template__generate_auth/expected/.crystal-version
deleted file mode 100644
index 41c11ffb..00000000
--- a/fixtures/src_template__generate_auth/expected/.crystal-version
+++ /dev/null
@@ -1 +0,0 @@
-1.16.1
diff --git a/fixtures/src_template__generate_auth/expected/.env b/fixtures/src_template__generate_auth/expected/.env
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/.github/workflows/ci.yml b/fixtures/src_template__generate_auth/expected/.github/workflows/ci.yml
deleted file mode 100644
index 3ebc17ed..00000000
--- a/fixtures/src_template__generate_auth/expected/.github/workflows/ci.yml
+++ /dev/null
@@ -1,113 +0,0 @@
-name: test-project CI
-
-on:
- push:
- branches: "*"
- pull_request:
- branches: "*"
-
-jobs:
- check-format:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental }}
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
- - name: Format
- run: crystal tool format --check
-
- specs:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- env:
- LUCKY_ENV: test
- DB_HOST: localhost
- continue-on-error: ${{ matrix.experimental }}
- services:
- postgres:
- image: postgres:14-alpine
- env:
- POSTGRES_PASSWORD: postgres
- ports:
- - 5432:5432
- # Set health checks to wait until postgres has started
- options: >-
- --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
-
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
-
- - name: Get yarn cache directory path
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn cache dir)"
-
- - name: Set up Yarn cache
- uses: actions/cache@v4
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
-
- - name: Set up Node cache
- uses: actions/cache@v4
- id: node-cache # use this to check for `cache-hit` (`steps.node-cache.outputs.cache-hit != 'true'`)
- with:
- path: '**/node_modules'
- key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-node-
- - name: Set up Crystal cache
- uses: actions/cache@v4
- id: crystal-cache
- with:
- path: |
- ~/.cache/crystal
- lib
- key: ${{ runner.os }}-crystal-${{ hashFiles('**/shard.lock') }}
- restore-keys: |
- ${{ runner.os }}-crystal-
-
- - name: Install shards
- if: steps.crystal-cache.outputs.cache-hit != 'true'
- run: shards check || shards install
-
- - name: Install yarn packages
- if: steps.node-cache.outputs.cache-hit != 'true'
- run: yarn install --frozen-lockfile --no-progress
- - name: Compiling assets
- run: yarn prod
- - name: Build lucky_tasks
- run: crystal build tasks.cr -o ./lucky_tasks
-
- - name: Prepare database
- run: |
- ./lucky_tasks db.create
- ./lucky_tasks db.migrate
- ./lucky_tasks db.seed.required_data
-
- - name: Run tests
- run: crystal spec
\ No newline at end of file
diff --git a/fixtures/src_template__generate_auth/expected/Procfile b/fixtures/src_template__generate_auth/expected/Procfile
deleted file mode 100644
index e524d70d..00000000
--- a/fixtures/src_template__generate_auth/expected/Procfile
+++ /dev/null
@@ -1,2 +0,0 @@
-web: bin/app
-release: lucky db.migrate
diff --git a/fixtures/src_template__generate_auth/expected/Procfile.dev b/fixtures/src_template__generate_auth/expected/Procfile.dev
deleted file mode 100644
index 80369f14..00000000
--- a/fixtures/src_template__generate_auth/expected/Procfile.dev
+++ /dev/null
@@ -1,3 +0,0 @@
-system_check: crystal script/system_check.cr
-web: lucky watch --reload-browser
-assets: yarn dev
diff --git a/fixtures/src_template__generate_auth/expected/README.md b/fixtures/src_template__generate_auth/expected/README.md
deleted file mode 100644
index da2d97cc..00000000
--- a/fixtures/src_template__generate_auth/expected/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# test-project
-
-This is a project written using [Lucky](https://luckyframework.org). Enjoy!
-
-### Setting up the project
-
-1. [Install required dependencies](https://luckyframework.org/guides/getting-started/installing#install-required-dependencies)
-1. Update database settings in `config/database.cr`
-1. Run `script/setup`
-1. Run `lucky dev` to start the app
-
-### Using Docker for development
-
-1. [Install Docker](https://docs.docker.com/engine/install/)
-1. Run `docker compose up`
-
-The Docker container will boot all of the necessary components needed to run your Lucky application.
-To configure the container, update the `docker-compose.yml` file, and the `docker/development.dockerfile` file.
-
-
-### Learning Lucky
-
-Lucky uses the [Crystal](https://crystal-lang.org) programming language. You can learn about Lucky from the [Lucky Guides](https://luckyframework.org/guides/getting-started/why-lucky).
diff --git a/fixtures/src_template__generate_auth/expected/config/application.cr b/fixtures/src_template__generate_auth/expected/config/application.cr
deleted file mode 100644
index c807149a..00000000
--- a/fixtures/src_template__generate_auth/expected/config/application.cr
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file may be used for custom Application configurations.
-# It will be loaded before other config files.
-#
-# Read more on configuration:
-# https://luckyframework.org/guides/getting-started/configuration#configuring-your-own-code
-
-# Use this code as an example:
-#
-# ```
-# module Application
-# Habitat.create do
-# setting support_email : String
-# setting lock_with_basic_auth : Bool
-# end
-# end
-#
-# Application.configure do |settings|
-# settings.support_email = "support@myapp.io"
-# settings.lock_with_basic_auth = LuckyEnv.staging?
-# end
-#
-# # In your application, call
-# # `Application.settings.support_email` anywhere you need it.
-# ```
diff --git a/fixtures/src_template__generate_auth/expected/config/colors.cr b/fixtures/src_template__generate_auth/expected/config/colors.cr
deleted file mode 100644
index 761ae940..00000000
--- a/fixtures/src_template__generate_auth/expected/config/colors.cr
+++ /dev/null
@@ -1,4 +0,0 @@
-# This enables the color output when in development or test
-# Check out the Colorize docs for more information
-# https://crystal-lang.org/api/Colorize.html
-Colorize.enabled = LuckyEnv.development? || LuckyEnv.test?
diff --git a/fixtures/src_template__generate_auth/expected/config/cookies.cr b/fixtures/src_template__generate_auth/expected/config/cookies.cr
deleted file mode 100644
index 2d5055f2..00000000
--- a/fixtures/src_template__generate_auth/expected/config/cookies.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-require "./server"
-
-Lucky::Session.configure do |settings|
- settings.key = "_test_project_session"
-end
-
-Lucky::CookieJar.configure do |settings|
- settings.on_set = ->(cookie : HTTP::Cookie) {
- # If ForceSSLHandler is enabled, only send cookies over HTTPS
- cookie.secure(Lucky::ForceSSLHandler.settings.enabled)
-
- # By default, don't allow reading cookies with JavaScript
- cookie.http_only(true)
-
- # Restrict cookies to a first-party or same-site context
- cookie.samesite(:lax)
-
- # Set all cookies to the root path by default
- cookie.path("/")
-
- # You can set other defaults for cookies here. For example:
- #
- # cookie.expires(1.year.from_now).domain("mydomain.com")
- }
-end
diff --git a/fixtures/src_template__generate_auth/expected/config/database.cr b/fixtures/src_template__generate_auth/expected/config/database.cr
deleted file mode 100644
index f614299a..00000000
--- a/fixtures/src_template__generate_auth/expected/config/database.cr
+++ /dev/null
@@ -1,29 +0,0 @@
-database_name = "test_project_#{LuckyEnv.environment}"
-
-AppDatabase.configure do |settings|
- if LuckyEnv.production?
- settings.credentials = Avram::Credentials.parse(ENV["DATABASE_URL"])
- else
- settings.credentials = Avram::Credentials.parse?(ENV["DATABASE_URL"]?) || Avram::Credentials.new(
- database: database_name,
- hostname: ENV["DB_HOST"]? || "localhost",
- port: ENV["DB_PORT"]?.try(&.to_i) || 5432,
- # Some common usernames are "postgres", "root", or your system username (run 'whoami')
- username: ENV["DB_USERNAME"]? || "postgres",
- # Some Postgres installations require no password. Use "" if that is the case.
- password: ENV["DB_PASSWORD"]? || "postgres"
- )
- end
-end
-
-Avram.configure do |settings|
- settings.database_to_migrate = AppDatabase
-
- # In production, allow lazy loading (N+1).
- # In development and test, raise an error if you forget to preload associations
- settings.lazy_load_enabled = LuckyEnv.production?
-
- # Always parse `Time` values with these specific formats.
- # Used for both database values, and datetime input fields.
- # settings.time_formats << "%F"
-end
diff --git a/fixtures/src_template__generate_auth/expected/config/email.cr b/fixtures/src_template__generate_auth/expected/config/email.cr
deleted file mode 100644
index 7c875449..00000000
--- a/fixtures/src_template__generate_auth/expected/config/email.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-require "carbon_sendgrid_adapter"
-
-BaseEmail.configure do |settings|
- if LuckyEnv.production?
- # If you don't need to send emails, set the adapter to DevAdapter instead:
- #
- # settings.adapter = Carbon::DevAdapter.new
- #
- # If you do need emails, get a key from SendGrid and set an ENV variable
- send_grid_key = send_grid_key_from_env
- settings.adapter = Carbon::SendGridAdapter.new(api_key: send_grid_key)
- elsif LuckyEnv.development?
- settings.adapter = Carbon::DevAdapter.new(print_emails: true)
- else
- settings.adapter = Carbon::DevAdapter.new
- end
-end
-
-private def send_grid_key_from_env
- ENV["SEND_GRID_KEY"]? || raise_missing_key_message
-end
-
-private def raise_missing_key_message
- puts "Missing SEND_GRID_KEY. Set the SEND_GRID_KEY env variable to 'unused' if not sending emails, or set the SEND_GRID_KEY ENV var.".colorize.red
- exit(1)
-end
diff --git a/fixtures/src_template__generate_auth/expected/config/env.cr b/fixtures/src_template__generate_auth/expected/config/env.cr
deleted file mode 100644
index 3f364072..00000000
--- a/fixtures/src_template__generate_auth/expected/config/env.cr
+++ /dev/null
@@ -1,33 +0,0 @@
-# Environments are managed using `LuckyEnv`. By default, development, production
-# and test are supported. See
-# https://luckyframework.org/guides/getting-started/configuration for details.
-#
-# The default environment is development unless the environment variable
-# LUCKY_ENV is set.
-#
-# Example:
-# ```
-# LuckyEnv.environment # => "development"
-# LuckyEnv.development? # => true
-# LuckyEnv.production? # => false
-# LuckyEnv.test? # => false
-# ```
-#
-# New environments can be added using the `LuckyEnv.add_env` macro.
-#
-# Example:
-# ```
-# LuckyEnv.add_env :staging
-# LuckyEnv.staging? # => false
-# ```
-#
-# To determine whether or not a `LuckyTask` is currently running, you can use
-# the `LuckyEnv.task?` predicate.
-#
-# Example:
-# ```
-# LuckyEnv.task? # => false
-# ```
-
-# Add a staging environment.
-# LuckyEnv.add_env :staging
diff --git a/fixtures/src_template__generate_auth/expected/config/error_handler.cr b/fixtures/src_template__generate_auth/expected/config/error_handler.cr
deleted file mode 100644
index c6b736e3..00000000
--- a/fixtures/src_template__generate_auth/expected/config/error_handler.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Lucky::ErrorHandler.configure do |settings|
- settings.show_debug_output = !LuckyEnv.production?
-end
diff --git a/fixtures/src_template__generate_auth/expected/config/log.cr b/fixtures/src_template__generate_auth/expected/config/log.cr
deleted file mode 100644
index a43940d9..00000000
--- a/fixtures/src_template__generate_auth/expected/config/log.cr
+++ /dev/null
@@ -1,50 +0,0 @@
-require "file_utils"
-
-if LuckyEnv.test?
- # Logs to `tmp/test.log` so you can see what's happening without having
- # a bunch of log output in your spec results.
- FileUtils.mkdir_p("tmp")
-
- backend = Log::IOBackend.new(File.new("tmp/test.log", mode: "w"))
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
-elsif LuckyEnv.production?
- # Lucky uses JSON in production so logs can be searched more easily
- #
- # If you want logs like in development use 'Lucky::PrettyLogFormatter.proc'.
- backend = Log::IOBackend.new
- backend.formatter = Dexter::JSONLogFormatter.proc
- Log.dexter.configure(:info, backend)
-else
- # Use a pretty formatter printing to STDOUT in development
- backend = Log::IOBackend.new
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
- DB::Log.level = :info
-end
-
-# Lucky only logs when before/after pipes halt by redirecting, or rendering a
-# response. Pipes that run without halting are not logged.
-#
-# If you want to log every pipe that runs, set the log level to ':info'
-Lucky::ContinuedPipeLog.dexter.configure(:none)
-
-# Lucky only logs failed queries by default.
-#
-# Set the log to ':info' to log all queries
-Avram::QueryLog.dexter.configure(:none)
-
-# Subscribe to Pulsar events to log when queries are made,
-# queries fail, or save operations fail. Remove this to
-# disable these log events without disabling all logging.
-Avram.initialize_logging
-
-# Skip logging static assets requests in development
-Lucky::LogHandler.configure do |settings|
- if LuckyEnv.development?
- settings.skip_if = ->(context : HTTP::Server::Context) {
- context.request.method.downcase == "get" &&
- context.request.resource.starts_with?(/\/css\/|\/js\/|\/assets\/|\/favicon\.ico/)
- }
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/config/route_helper.cr b/fixtures/src_template__generate_auth/expected/config/route_helper.cr
deleted file mode 100644
index ede1f328..00000000
--- a/fixtures/src_template__generate_auth/expected/config/route_helper.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is used when generating URLs for your application
-Lucky::RouteHelper.configure do |settings|
- if LuckyEnv.production?
- # Example: https://my_app.com
- settings.base_uri = ENV.fetch("APP_DOMAIN")
- else
- # Set domain to the default host/port in development/test
- settings.base_uri = "http://localhost:#{Lucky::ServerSettings.port}"
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/config/server.cr b/fixtures/src_template__generate_auth/expected/config/server.cr
deleted file mode 100644
index b7cca25c..00000000
--- a/fixtures/src_template__generate_auth/expected/config/server.cr
+++ /dev/null
@@ -1,68 +0,0 @@
-# Here is where you configure the Lucky server
-#
-# Look at config/route_helper.cr if you want to change the domain used when
-# generating links with `Action.url`.
-Lucky::Server.configure do |settings|
- if LuckyEnv.production?
- settings.secret_key_base = secret_key_from_env
- settings.host = "0.0.0.0"
- settings.port = ENV["PORT"].to_i
- settings.gzip_enabled = true
- # By default certain content types will be gzipped.
- # For a full list look in
- # https://github.com/luckyframework/lucky/blob/main/src/lucky/server.cr
- # To add additional extensions do something like this:
- # settings.gzip_content_types << "content/type"
- else
- settings.secret_key_base = "1234567890"
- # Change host/port in config/watch.yml
- # Alternatively, you can set the DEV_PORT env to set the port for local development
- settings.host = Lucky::ServerSettings.host
- settings.port = Lucky::ServerSettings.port
- end
-
- # Configure the asset build system (default is Vite)
- settings.asset_build_system = Lucky::AssetBuilder::Vite.new
-
- # Configure asset host for Vite
- if LuckyEnv.development?
- # In development, Vite serves assets from its dev server
- settings.asset_host = "http://localhost:3001"
- elsif LuckyEnv.production?
- # In production, Lucky serves the built assets
- # You could also use a CDN here:
- # settings.asset_host = "https://mycdnhost.com"
- settings.asset_host = ""
- else
- settings.asset_host = ""
- end
-end
-
-Lucky::ForceSSLHandler.configure do |settings|
- # To force SSL in production, uncomment the lines below.
- # This will cause http requests to be redirected to https:
- #
- # settings.enabled = LuckyEnv.production?
- # settings.strict_transport_security = {max_age: 1.year, include_subdomains: true}
- #
- # Or, leave it disabled:
- settings.enabled = false
-end
-
-# Set a unique ID for each HTTP request.
-# To enable the request ID, uncomment the lines below.
-# You can set your own custom String, or use a random UUID.
-# Lucky::RequestIdHandler.configure do |settings|
-# settings.set_request_id = ->(context : HTTP::Server::Context) {
-# UUID.random.to_s
-# }
-# end
-
-private def secret_key_from_env
- ENV["SECRET_KEY_BASE"]? || raise_missing_secret_key_in_production
-end
-
-private def raise_missing_secret_key_in_production
- puts "Please set the SECRET_KEY_BASE environment variable. You can generate a secret key with 'lucky gen.secret_key'".colorize.red
- exit(1)
-end
\ No newline at end of file
diff --git a/fixtures/src_template__generate_auth/expected/config/watch.yml b/fixtures/src_template__generate_auth/expected/config/watch.yml
deleted file mode 100644
index 3a59b410..00000000
--- a/fixtures/src_template__generate_auth/expected/config/watch.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-host: 127.0.0.1
-port: 3000
-reload_port: 3001
diff --git a/fixtures/src_template__generate_auth/expected/db/migrations/.keep b/fixtures/src_template__generate_auth/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/docker-compose.yml b/fixtures/src_template__generate_auth/expected/docker-compose.yml
deleted file mode 100644
index d00779db..00000000
--- a/fixtures/src_template__generate_auth/expected/docker-compose.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-version: "3.8"
-services:
- lucky:
- build:
- context: .
- dockerfile: docker/development.dockerfile
- environment:
- DATABASE_URL: postgres://lucky:password@postgres:5432/lucky
- DEV_HOST: "0.0.0.0"
- volumes:
- - .:/app
- - node_modules:/app/node_modules
- - shards_lib:/app/lib
- - app_bin:/app/bin
- - build_cache:/root/.cache
- depends_on:
- - postgres
- ports:
- - 3000:3000 # This is the Lucky Server port
- - 3001:3001 # This is the Lucky watcher reload port
-
- entrypoint: ["docker/dev_entrypoint.sh"]
-
- postgres:
- image: postgres:14-alpine
- environment:
- POSTGRES_USER: lucky
- POSTGRES_PASSWORD: password
- POSTGRES_DB: lucky
- volumes:
- - postgres_data:/var/lib/postgresql/data
- ports:
- # The postgres database container is exposed on the host at port 6543 to
- # allow connecting directly to it with postgres clients. The port differs
- # from the postgres default to avoid conflict with existing postgres
- # servers. Connect to a running postgres container with:
- # postgres://lucky:password@localhost:6543/lucky
- - 6543:5432
-
-volumes:
- postgres_data:
- node_modules:
- shards_lib:
- app_bin:
- build_cache:
diff --git a/fixtures/src_template__generate_auth/expected/docker/dev_entrypoint.sh b/fixtures/src_template__generate_auth/expected/docker/dev_entrypoint.sh
deleted file mode 100755
index d16ef6ab..00000000
--- a/fixtures/src_template__generate_auth/expected/docker/dev_entrypoint.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# This is the entrypoint script used for development docker workflows.
-# By default it will:
-# - Install dependencies.
-# - Run migrations.
-# - Start the dev server.
-# It also accepts any commands to be run instead.
-
-
-warnfail () {
- echo "$@" >&2
- exit 1
-}
-
-case ${1:-} in
- "") # If no arguments are provided, start lucky dev server.
- ;;
-
- *) # If any arguments are provided, execute them instead.
- exec "$@"
-esac
-
-if ! [ -d bin ] ; then
- echo 'Creating bin directory'
- mkdir bin
-fi
-echo 'Installing npm packages...'
-yarn install
-if ! shards check ; then
- echo 'Installing shards...'
- shards install
-fi
-
-echo 'Waiting for postgres to be available...'
-./docker/wait-for-it.sh -q postgres:5432
-
-if ! psql -d "$DATABASE_URL" -c '\d migrations' > /dev/null ; then
- echo 'Finishing database setup...'
- lucky db.migrate
-fi
-
-echo 'Starting lucky dev server...'
-exec lucky dev
diff --git a/fixtures/src_template__generate_auth/expected/docker/development.dockerfile b/fixtures/src_template__generate_auth/expected/docker/development.dockerfile
deleted file mode 100644
index 962ad66c..00000000
--- a/fixtures/src_template__generate_auth/expected/docker/development.dockerfile
+++ /dev/null
@@ -1,33 +0,0 @@
-FROM crystallang/crystal:1.16.1
-
-# Install utilities required to make this Dockerfile run
-RUN apt-get update && \
- apt-get install -y wget
-# Add the nodesource ppa to apt. Update this to change the nodejs version.
-RUN wget https://deb.nodesource.com/setup_16.x -O- | bash
-
-# Apt installs:
-# - nodejs (from above ppa) is required for front-end apps.
-# - Postgres cli tools are required for lucky-cli.
-# - tmux is required for the Overmind process manager.
-RUN apt-get update && \
- apt-get install -y nodejs postgresql-client tmux && \
- rm -rf /var/lib/apt/lists/*
-
-# NPM global installs:
-# - Yarn is the default package manager for the node component of a lucky
-# browser app.
-RUN npm install -g yarn
-
-# Install lucky cli
-WORKDIR /lucky/cli
-RUN git clone https://github.com/luckyframework/lucky_cli . && \
- git checkout v1.3.0 && \
- shards build --without-development && \
- cp bin/lucky /usr/bin
-
-WORKDIR /app
-ENV DATABASE_URL=postgres://postgres:postgres@host.docker.internal:5432/postgres
-EXPOSE 3000
-EXPOSE 3001
-
diff --git a/fixtures/src_template__generate_auth/expected/docker/wait-for-it.sh b/fixtures/src_template__generate_auth/expected/docker/wait-for-it.sh
deleted file mode 100755
index 06e0638c..00000000
--- a/fixtures/src_template__generate_auth/expected/docker/wait-for-it.sh
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/bash
-#
-# Pulled from https://github.com/vishnubob/wait-for-it on 2022-02-28.
-# Licensed under the MIT license as of 81b1373f.
-#
-# Below this line, wait-for-it is the original work of the author.
-#
-# Use this script to test if a given TCP host/port are available
-
-WAITFORIT_cmdname=${0##*/}
-
-echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
-
-usage()
-{
- cat << USAGE >&2
-Usage:
- $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
- -h HOST | --host=HOST Host or IP under test
- -p PORT | --port=PORT TCP port under test
- Alternatively, you specify the host and port as host:port
- -s | --strict Only execute subcommand if the test succeeds
- -q | --quiet Don't output any status messages
- -t TIMEOUT | --timeout=TIMEOUT
- Timeout in seconds, zero for no timeout
- -- COMMAND ARGS Execute command with args after the test finishes
-USAGE
- exit 1
-}
-
-wait_for()
-{
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- else
- echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
- fi
- WAITFORIT_start_ts=$(date +%s)
- while :
- do
- if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
- nc -z $WAITFORIT_HOST $WAITFORIT_PORT
- WAITFORIT_result=$?
- else
- (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
- WAITFORIT_result=$?
- fi
- if [[ $WAITFORIT_result -eq 0 ]]; then
- WAITFORIT_end_ts=$(date +%s)
- echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
- break
- fi
- sleep 1
- done
- return $WAITFORIT_result
-}
-
-wait_for_wrapper()
-{
- # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
- if [[ $WAITFORIT_QUIET -eq 1 ]]; then
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- else
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- fi
- WAITFORIT_PID=$!
- trap "kill -INT -$WAITFORIT_PID" INT
- wait $WAITFORIT_PID
- WAITFORIT_RESULT=$?
- if [[ $WAITFORIT_RESULT -ne 0 ]]; then
- echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- fi
- return $WAITFORIT_RESULT
-}
-
-# process arguments
-while [[ $# -gt 0 ]]
-do
- case "$1" in
- *:* )
- WAITFORIT_hostport=(${1//:/ })
- WAITFORIT_HOST=${WAITFORIT_hostport[0]}
- WAITFORIT_PORT=${WAITFORIT_hostport[1]}
- shift 1
- ;;
- --child)
- WAITFORIT_CHILD=1
- shift 1
- ;;
- -q | --quiet)
- WAITFORIT_QUIET=1
- shift 1
- ;;
- -s | --strict)
- WAITFORIT_STRICT=1
- shift 1
- ;;
- -h)
- WAITFORIT_HOST="$2"
- if [[ $WAITFORIT_HOST == "" ]]; then break; fi
- shift 2
- ;;
- --host=*)
- WAITFORIT_HOST="${1#*=}"
- shift 1
- ;;
- -p)
- WAITFORIT_PORT="$2"
- if [[ $WAITFORIT_PORT == "" ]]; then break; fi
- shift 2
- ;;
- --port=*)
- WAITFORIT_PORT="${1#*=}"
- shift 1
- ;;
- -t)
- WAITFORIT_TIMEOUT="$2"
- if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
- shift 2
- ;;
- --timeout=*)
- WAITFORIT_TIMEOUT="${1#*=}"
- shift 1
- ;;
- --)
- shift
- WAITFORIT_CLI=("$@")
- break
- ;;
- --help)
- usage
- ;;
- *)
- echoerr "Unknown argument: $1"
- usage
- ;;
- esac
-done
-
-if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
- echoerr "Error: you need to provide a host and port to test."
- usage
-fi
-
-WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
-WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
-WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
-WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
-
-# Check to see if timeout is from busybox?
-WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
-WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
-
-WAITFORIT_BUSYTIMEFLAG=""
-if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
- WAITFORIT_ISBUSY=1
- # Check if busybox timeout uses -t flag
- # (recent Alpine versions don't support -t anymore)
- if timeout &>/dev/stdout | grep -q -e '-t '; then
- WAITFORIT_BUSYTIMEFLAG="-t"
- fi
-else
- WAITFORIT_ISBUSY=0
-fi
-
-if [[ $WAITFORIT_CHILD -gt 0 ]]; then
- wait_for
- WAITFORIT_RESULT=$?
- exit $WAITFORIT_RESULT
-else
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- wait_for_wrapper
- WAITFORIT_RESULT=$?
- else
- wait_for
- WAITFORIT_RESULT=$?
- fi
-fi
-
-if [[ $WAITFORIT_CLI != "" ]]; then
- if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
- echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
- exit $WAITFORIT_RESULT
- fi
- exec "${WAITFORIT_CLI[@]}"
-else
- exit $WAITFORIT_RESULT
-fi
-
diff --git a/fixtures/src_template__generate_auth/expected/script/helpers/function_helpers.cr b/fixtures/src_template__generate_auth/expected/script/helpers/function_helpers.cr
deleted file mode 100644
index 8abcb6a2..00000000
--- a/fixtures/src_template__generate_auth/expected/script/helpers/function_helpers.cr
+++ /dev/null
@@ -1,32 +0,0 @@
-require "colorize"
-
-# These are helper methods provided to help keep your code
-# clean. Add new methods, or alter these as needed.
-
-def notice(message : String) : Nil
- puts "\n▸ #{message}"
-end
-
-def print_done : Nil
- puts "✔ Done"
-end
-
-def print_error(message : String) : Nil
- puts "There is a problem with your system setup:\n".colorize.red.bold
- puts "#{message}\n".colorize.red.bold
- Process.exit(1)
-end
-
-def command_not_found(command : String) : Bool
- Process.find_executable(command).nil?
-end
-
-def command_not_running(command : String, *args) : Bool
- output = IO::Memory.new
- code = Process.run(command, args, output: output).exit_code
- code > 0
-end
-
-def run_command(command : String, *args) : Nil
- Process.run(command, args, output: STDOUT, error: STDERR, input: STDIN)
-end
diff --git a/fixtures/src_template__generate_auth/expected/script/setup.cr b/fixtures/src_template__generate_auth/expected/script/setup.cr
deleted file mode 100644
index faa74914..00000000
--- a/fixtures/src_template__generate_auth/expected/script/setup.cr
+++ /dev/null
@@ -1,32 +0,0 @@
-require "./helpers/*"
-
-notice "Running System Check"
-
-require "./system_check"
-
-print_done
-
-notice "Installing node dependencies"
-run_command "yarn", "install", "--no-progress"
-
-print_done
-
-notice "Installing shards"
-run_command "shards", "install"
-
-if !File.exists?(".env")
- notice "No .env found. Creating one."
- File.touch ".env"
- print_done
-end
-
-notice "Setting up the database"
-
-run_command "lucky", "db.setup"
-
-notice "Seeding the database with required and sample records"
-run_command "lucky", "db.seed.required_data"
-run_command "lucky", "db.seed.sample_data"
-
-print_done
-notice "Run 'lucky dev' to start the app"
\ No newline at end of file
diff --git a/fixtures/src_template__generate_auth/expected/script/system_check.cr b/fixtures/src_template__generate_auth/expected/script/system_check.cr
deleted file mode 100644
index c56ce3e9..00000000
--- a/fixtures/src_template__generate_auth/expected/script/system_check.cr
+++ /dev/null
@@ -1,21 +0,0 @@
-require "./helpers/*"
-
-# Use this script to check the system for required tools and process that your app needs.
-# A few helper functions are provided to keep the code simple. See the
-# script/helpers/function_helpers.cr file for more examples.
-#
-# A few examples you might use here:
-# * 'lucky db.verify_connection' to test postgres can be connected
-# * Checking that elasticsearch, redis, or postgres is installed and/or booted
-# * Note: Booting additional processes for things like mail, background jobs, etc...
-# should go in your Procfile.dev.
-
-if command_not_found "yarn"
- print_error "Yarn is not installed\n See https://yarnpkg.com/lang/en/docs/install/ for install instructions."
-end
-
-# CUSTOM PRE-BOOT CHECKS
-# example:
-# if command_not_running "redis-cli", "ping"
-# print_error "Redis is not running."
-# end
diff --git a/fixtures/src_template__generate_auth/expected/spec/setup/clean_database.cr b/fixtures/src_template__generate_auth/expected/spec/setup/clean_database.cr
deleted file mode 100644
index a1bc631c..00000000
--- a/fixtures/src_template__generate_auth/expected/spec/setup/clean_database.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- AppDatabase.truncate
-end
diff --git a/fixtures/src_template__generate_auth/expected/spec/setup/reset_emails.cr b/fixtures/src_template__generate_auth/expected/spec/setup/reset_emails.cr
deleted file mode 100644
index 140ab416..00000000
--- a/fixtures/src_template__generate_auth/expected/spec/setup/reset_emails.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- Carbon::DevAdapter.reset
-end
diff --git a/fixtures/src_template__generate_auth/expected/spec/setup/setup_database.cr b/fixtures/src_template__generate_auth/expected/spec/setup/setup_database.cr
deleted file mode 100644
index 393c6da3..00000000
--- a/fixtures/src_template__generate_auth/expected/spec/setup/setup_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-Db::Create.new(quiet: true).call
-Db::Migrate.new(quiet: true).call
diff --git a/fixtures/src_template__generate_auth/expected/spec/setup/start_app_server.cr b/fixtures/src_template__generate_auth/expected/spec/setup/start_app_server.cr
deleted file mode 100644
index ff0bfeeb..00000000
--- a/fixtures/src_template__generate_auth/expected/spec/setup/start_app_server.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-app_server = AppServer.new
-
-spawn do
- app_server.listen
-end
-
-Spec.after_suite do
- LuckyFlow.shutdown
- app_server.close
-end
diff --git a/fixtures/src_template__generate_auth/expected/spec/spec_helper.cr b/fixtures/src_template__generate_auth/expected/spec/spec_helper.cr
deleted file mode 100644
index 91223fd7..00000000
--- a/fixtures/src_template__generate_auth/expected/spec/spec_helper.cr
+++ /dev/null
@@ -1,29 +0,0 @@
-ENV["LUCKY_ENV"] = "test"
-ENV["DEV_PORT"] = "5001"
-require "spec"
-require "lucky_flow"
-require "lucky_flow/ext/lucky"
-require "lucky_flow/ext/avram"
-
-require "lucky_flow/ext/authentic"
-require "../src/app"
-require "./support/flows/base_flow"
-require "./support/**"
-require "../db/migrations/**"
-
-# Add/modify files in spec/setup to start/configure programs or run hooks
-#
-# By default there are scripts for setting up and cleaning the database,
-# configuring LuckyFlow, starting the app server, etc.
-require "./setup/**"
-
-include Carbon::Expectations
-include Lucky::RequestExpectations
-# NOTE: LuckyFlow specs are temporarily set to pending as of Lucky v1.4.0
-# This is due to race conditions in LuckyFlow.
-# Ref: https://github.com/luckyframework/lucky_cli/issues/883
-include LuckyFlow::Expectations
-
-Avram::Migrator::Runner.new.ensure_migrated!
-Avram::SchemaEnforcer.ensure_correct_column_mappings!
-Habitat.raise_if_missing_settings!
diff --git a/fixtures/src_template__generate_auth/expected/spec/support/.keep b/fixtures/src_template__generate_auth/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/spec/support/api_client.cr b/fixtures/src_template__generate_auth/expected/spec/support/api_client.cr
deleted file mode 100644
index 46d449a8..00000000
--- a/fixtures/src_template__generate_auth/expected/spec/support/api_client.cr
+++ /dev/null
@@ -1,12 +0,0 @@
-class ApiClient < Lucky::BaseHTTPClient
- app AppServer.new
-
- def initialize
- super
- headers("Content-Type": "application/json")
- end
-
- def self.auth(user : User)
- new.headers("Authorization": UserToken.generate(user))
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/spec/support/factories/.keep b/fixtures/src_template__generate_auth/expected/spec/support/factories/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/actions/api_action.cr b/fixtures/src_template__generate_auth/expected/src/actions/api_action.cr
deleted file mode 100644
index a16fd09e..00000000
--- a/fixtures/src_template__generate_auth/expected/src/actions/api_action.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-# Include modules and add methods that are for all API requests
-abstract class ApiAction < Lucky::Action
- # APIs typically do not need to send cookie/session data.
- # Remove this line if you want to send cookies in the response header.
- disable_cookies
- accepted_formats [:json]
-
- include Api::Auth::Helpers
-
- # By default all actions require sign in.
- # Add 'include Api::Auth::SkipRequireAuthToken' to your actions to allow all requests.
- include Api::Auth::RequireAuthToken
-
- # By default all actions are required to use underscores to separate words.
- # Add 'include Lucky::SkipRouteStyleCheck' to your actions if you wish to ignore this check for specific routes.
- include Lucky::EnforceUnderscoredRoute
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/actions/errors/show.cr b/fixtures/src_template__generate_auth/expected/src/actions/errors/show.cr
deleted file mode 100644
index d01ed541..00000000
--- a/fixtures/src_template__generate_auth/expected/src/actions/errors/show.cr
+++ /dev/null
@@ -1,63 +0,0 @@
-# This class handles error responses and reporting.
-#
-# https://luckyframework.org/guides/http-and-routing/error-handling
-class Errors::Show < Lucky::ErrorAction
- DEFAULT_MESSAGE = "Something went wrong."
- default_format :html
- dont_report [Lucky::RouteNotFoundError, Avram::RecordNotFoundError]
-
- def render(error : Lucky::RouteNotFoundError | Avram::RecordNotFoundError)
- if html?
- error_html "Sorry, we couldn't find that page.", status: 404
- else
- error_json "Not found", status: 404
- end
- end
-
- # When the request is JSON and an InvalidOperationError is raised, show a
- # helpful error with the param that is invalid, and what was wrong with it.
- def render(error : Avram::InvalidOperationError)
- if html?
- error_html DEFAULT_MESSAGE, status: 500
- else
- error_json \
- message: error.renderable_message,
- details: error.renderable_details,
- param: error.invalid_attribute_name,
- status: 400
- end
- end
-
- # Always keep this below other 'render' methods or it may override your
- # custom 'render' methods.
- def render(error : Lucky::RenderableError)
- if html?
- error_html DEFAULT_MESSAGE, status: error.renderable_status
- else
- error_json error.renderable_message, status: error.renderable_status
- end
- end
-
- # If none of the 'render' methods return a response for the raised Exception,
- # Lucky will use this method.
- def default_render(error : Exception) : Lucky::Response
- if html?
- error_html DEFAULT_MESSAGE, status: 500
- else
- error_json DEFAULT_MESSAGE, status: 500
- end
- end
-
- private def error_html(message : String, status : Int)
- context.response.status_code = status
- html_with_status Errors::ShowPage, status, message: message, status_code: status
- end
-
- private def error_json(message : String, status : Int, details = nil, param = nil)
- json ErrorSerializer.new(message: message, details: details, param: param), status: status
- end
-
- private def report(error : Exception) : Nil
- # Send to Rollbar, send an email, etc.
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/actions/home/index.cr b/fixtures/src_template__generate_auth/expected/src/actions/home/index.cr
deleted file mode 100644
index f780130a..00000000
--- a/fixtures/src_template__generate_auth/expected/src/actions/home/index.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-class Home::Index < BrowserAction
- include Auth::AllowGuests
-
- get "/" do
- if current_user?
- redirect Me::Show
- else
- # When you're ready change this line to:
- #
- # redirect SignIns::New
- #
- # Or maybe show signed out users a marketing page:
- #
- # html Marketing::IndexPage
- html Lucky::WelcomePage
- end
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/actions/mixins/.keep b/fixtures/src_template__generate_auth/expected/src/actions/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/app.cr b/fixtures/src_template__generate_auth/expected/src/app.cr
deleted file mode 100644
index d343c8cd..00000000
--- a/fixtures/src_template__generate_auth/expected/src/app.cr
+++ /dev/null
@@ -1,37 +0,0 @@
-require "./shards"
-
-# Load the asset manifest
-# In development, vite-plugin-dev-manifest creates public/manifest.dev.json
-# In production, Vite creates public/.vite/manifest.json
-# The manifest path is determined by which file exists at compile time
-{% if File.exists?("public/manifest.dev.json") %}
- Lucky::AssetHelpers.load_manifest "public/manifest.dev.json", use_vite: true
-{% elsif File.exists?("public/.vite/manifest.json") %}
- Lucky::AssetHelpers.load_manifest "public/.vite/manifest.json", use_vite: true
-{% else %}
- # For initial compilation, we'll assume development mode
- # The dev server will create the manifest before the app is recompiled
- Lucky::AssetHelpers.load_manifest "public/manifest.dev.json", use_vite: true
-{% end %}
-
-require "../config/server"
-require "./app_database"
-require "../config/**"
-require "./models/base_model"
-require "./models/mixins/**"
-require "./models/**"
-require "./queries/mixins/**"
-require "./queries/**"
-require "./operations/mixins/**"
-require "./operations/**"
-require "./serializers/base_serializer"
-require "./serializers/**"
-require "./emails/base_email"
-require "./emails/**"
-require "./actions/mixins/**"
-require "./actions/**"
-require "./components/base_component"
-require "./components/**"
-require "./pages/**"
-require "../db/migrations/**"
-require "./app_server"
\ No newline at end of file
diff --git a/fixtures/src_template__generate_auth/expected/src/app_database.cr b/fixtures/src_template__generate_auth/expected/src/app_database.cr
deleted file mode 100644
index 0efd4f50..00000000
--- a/fixtures/src_template__generate_auth/expected/src/app_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-class AppDatabase < Avram::Database
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/app_server.cr b/fixtures/src_template__generate_auth/expected/src/app_server.cr
deleted file mode 100644
index 8ec16c3c..00000000
--- a/fixtures/src_template__generate_auth/expected/src/app_server.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-class AppServer < Lucky::BaseAppServer
- # Learn about middleware with HTTP::Handlers:
- # https://luckyframework.org/guides/http-and-routing/http-handlers
- def middleware : Array(HTTP::Handler)
- [
- Lucky::RequestIdHandler.new,
- Lucky::ForceSSLHandler.new,
- Lucky::HttpMethodOverrideHandler.new,
- Lucky::LogHandler.new,
- Lucky::ErrorHandler.new(action: Errors::Show),
- Lucky::RemoteIpHandler.new,
- Lucky::RouteHandler.new,
- Lucky::StaticCompressionHandler.new("./public", file_ext: "gz", content_encoding: "gzip"),
- Lucky::StaticFileHandler.new("./public", fallthrough: false, directory_listing: false),
- Lucky::RouteNotFoundHandler.new,
- ] of HTTP::Handler
- end
-
- def protocol
- "http"
- end
-
- def listen
- server.listen(host, port, reuse_port: false)
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/emails/base_email.cr b/fixtures/src_template__generate_auth/expected/src/emails/base_email.cr
deleted file mode 100644
index 656f4f11..00000000
--- a/fixtures/src_template__generate_auth/expected/src/emails/base_email.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# Learn about sending emails
-# https://luckyframework.org/guides/emails/sending-emails-with-carbon
-abstract class BaseEmail < Carbon::Email
- # You can add defaults using the 'inherited' hook
- #
- # Example:
- #
- # macro inherited
- # from default_from
- # end
- #
- # def default_from
- # Carbon::Address.new("support@app.com")
- # end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/models/base_model.cr b/fixtures/src_template__generate_auth/expected/src/models/base_model.cr
deleted file mode 100644
index 6bafeb84..00000000
--- a/fixtures/src_template__generate_auth/expected/src/models/base_model.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-abstract class BaseModel < Avram::Model
- def self.database : Avram::Database.class
- AppDatabase
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/models/mixins/.keep b/fixtures/src_template__generate_auth/expected/src/models/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/operations/.keep b/fixtures/src_template__generate_auth/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/operations/mixins/.keep b/fixtures/src_template__generate_auth/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/queries/.keep b/fixtures/src_template__generate_auth/expected/src/queries/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/queries/mixins/.keep b/fixtures/src_template__generate_auth/expected/src/queries/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/serializers/.keep b/fixtures/src_template__generate_auth/expected/src/serializers/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/src/serializers/base_serializer.cr b/fixtures/src_template__generate_auth/expected/src/serializers/base_serializer.cr
deleted file mode 100644
index e769f5c0..00000000
--- a/fixtures/src_template__generate_auth/expected/src/serializers/base_serializer.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-abstract class BaseSerializer
- include Lucky::Serializable
-
- def self.for_collection(collection : Enumerable, *args, **named_args) : Array(self)
- collection.map do |object|
- new(object, *args, **named_args)
- end
- end
-
- def self.for_collection(collection : Enumerable, pages : Lucky::Paginator, *args, **named_args)
- {
- "items" => collection.map do |object|
- new(object, *args, **named_args)
- end,
- "pagination" => PaginationSerializer.new(pages),
- }
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/serializers/error_serializer.cr b/fixtures/src_template__generate_auth/expected/src/serializers/error_serializer.cr
deleted file mode 100644
index b7b55283..00000000
--- a/fixtures/src_template__generate_auth/expected/src/serializers/error_serializer.cr
+++ /dev/null
@@ -1,14 +0,0 @@
-# This is the default error serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class ErrorSerializer < BaseSerializer
- def initialize(
- @message : String,
- @details : String? = nil,
- @param : String? = nil, # so you can track which param (if any) caused the problem
- )
- end
-
- def render
- {message: @message, param: @param, details: @details}
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/serializers/pagination_serializer.cr b/fixtures/src_template__generate_auth/expected/src/serializers/pagination_serializer.cr
deleted file mode 100644
index 9e44788c..00000000
--- a/fixtures/src_template__generate_auth/expected/src/serializers/pagination_serializer.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# This is the default pagination serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class PaginationSerializer < BaseSerializer
- def initialize(@pages : Lucky::Paginator)
- end
-
- def render
- {
- next_page: @pages.path_to_next,
- previous_page: @pages.path_to_previous,
- total_items: @pages.item_count,
- total_pages: @pages.total,
- }
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/src/shards.cr b/fixtures/src_template__generate_auth/expected/src/shards.cr
deleted file mode 100644
index 7cadec18..00000000
--- a/fixtures/src_template__generate_auth/expected/src/shards.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-# Load .env file before any other config or app code
-require "lucky_env"
-LuckyEnv.load?(".env")
-
-# Require your shards here
-require "lucky"
-require "avram/lucky"
-require "carbon"
-require "authentic"
-require "jwt"
diff --git a/fixtures/src_template__generate_auth/expected/src/start_server.cr b/fixtures/src_template__generate_auth/expected/src/start_server.cr
deleted file mode 100644
index de8af78e..00000000
--- a/fixtures/src_template__generate_auth/expected/src/start_server.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-require "./app"
-
-Habitat.raise_if_missing_settings!
-
-if LuckyEnv.development?
- Avram::Migrator::Runner.new.ensure_migrated!
- Avram::SchemaEnforcer.ensure_correct_column_mappings!
-end
-
-app_server = AppServer.new
-puts "Listening on http://#{app_server.host}:#{app_server.port}"
-
-Signal::INT.trap do
- app_server.close
-end
-
-app_server.listen
diff --git a/fixtures/src_template__generate_auth/expected/src/test_project.cr b/fixtures/src_template__generate_auth/expected/src/test_project.cr
deleted file mode 100644
index 68e1a8d2..00000000
--- a/fixtures/src_template__generate_auth/expected/src/test_project.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-# Typically you will not use or modify this file. 'shards build' and some
-# other crystal tools will sometimes use this.
-#
-# When this file is compiled/run it will require and run 'start_server',
-# which as its name implies will start the server for you app.
-require "./start_server"
diff --git a/fixtures/src_template__generate_auth/expected/tasks.cr b/fixtures/src_template__generate_auth/expected/tasks.cr
deleted file mode 100644
index 5a892d4d..00000000
--- a/fixtures/src_template__generate_auth/expected/tasks.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file loads your app and all your tasks when running 'lucky'
-#
-# Run 'lucky --help' to see all available tasks.
-#
-# Learn to create your own tasks:
-# https://luckyframework.org/guides/command-line-tasks/custom-tasks
-
-# See `LuckyEnv#task?`
-ENV["LUCKY_TASK"] = "true"
-
-# Load Lucky and the app (actions, models, etc.)
-require "./src/app"
-require "lucky_task"
-
-# You can add your own tasks here in the ./tasks folder
-require "./tasks/**"
-
-# Load migrations
-require "./db/migrations/**"
-
-# Load Lucky tasks (dev, routes, etc.)
-require "lucky/tasks/**"
-require "avram/lucky/tasks"
-
-LuckyTask::Runner.run
diff --git a/fixtures/src_template__generate_auth/expected/tasks/.keep b/fixtures/src_template__generate_auth/expected/tasks/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__generate_auth/expected/tasks/db/seed/required_data.cr b/fixtures/src_template__generate_auth/expected/tasks/db/seed/required_data.cr
deleted file mode 100644
index d866040f..00000000
--- a/fixtures/src_template__generate_auth/expected/tasks/db/seed/required_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add seeds here that are *required* for your app to work.
-# For example, you might need at least one admin user or you might need at least
-# one category for your blog posts for the app to work.
-#
-# Use `Db::Seed::SampleData` if your only want to add sample data helpful for
-# development.
-class Db::Seed::RequiredData < LuckyTask::Task
- summary "Add database records required for the app to work"
-
- def call
- # Using a Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- #
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- #
- # unless UserQuery.new.email("me@example.com").first?
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- # end
- puts "Done adding required data"
- end
-end
diff --git a/fixtures/src_template__generate_auth/expected/tasks/db/seed/sample_data.cr b/fixtures/src_template__generate_auth/expected/tasks/db/seed/sample_data.cr
deleted file mode 100644
index 231d7e8d..00000000
--- a/fixtures/src_template__generate_auth/expected/tasks/db/seed/sample_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add sample data helpful for development, e.g. (fake users, blog posts, etc.)
-#
-# Use `Db::Seed::RequiredData` if you need to create data *required* for your
-# app to work.
-class Db::Seed::SampleData < LuckyTask::Task
- summary "Add sample database records helpful for development"
-
- def call
- # Using an Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- # ```
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # ```
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- # ```
- # if UserQuery.new.email("me@example.com").none?
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # end
- # ```
- puts "Done adding sample data"
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/.crystal-version b/fixtures/src_template__sec_tester/expected/.crystal-version
deleted file mode 100644
index 41c11ffb..00000000
--- a/fixtures/src_template__sec_tester/expected/.crystal-version
+++ /dev/null
@@ -1 +0,0 @@
-1.16.1
diff --git a/fixtures/src_template__sec_tester/expected/.env b/fixtures/src_template__sec_tester/expected/.env
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/.github/workflows/ci.yml b/fixtures/src_template__sec_tester/expected/.github/workflows/ci.yml
deleted file mode 100644
index 310ca50d..00000000
--- a/fixtures/src_template__sec_tester/expected/.github/workflows/ci.yml
+++ /dev/null
@@ -1,113 +0,0 @@
-name: test-project CI
-
-on:
- push:
- branches: "*"
- pull_request:
- branches: "*"
-
-jobs:
- check-format:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- continue-on-error: ${{ matrix.experimental }}
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
- - name: Format
- run: crystal tool format --check
-
- specs:
- strategy:
- fail-fast: false
- matrix:
- crystal_version:
- - 1.16.1
- experimental:
- - false
- runs-on: ubuntu-latest
- env:
- LUCKY_ENV: test
- DB_HOST: localhost
- continue-on-error: ${{ matrix.experimental }}
- services:
- postgres:
- image: postgres:14-alpine
- env:
- POSTGRES_PASSWORD: postgres
- ports:
- - 5432:5432
- # Set health checks to wait until postgres has started
- options: >-
- --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
-
- steps:
- - uses: actions/checkout@v4
- - name: Install Crystal
- uses: crystal-lang/install-crystal@v1
- with:
- crystal: ${{ matrix.crystal_version }}
-
- - name: Get yarn cache directory path
- id: yarn-cache-dir-path
- run: echo "::set-output name=dir::$(yarn cache dir)"
-
- - name: Set up Yarn cache
- uses: actions/cache@v4
- with:
- path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
- key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-yarn-
-
- - name: Set up Node cache
- uses: actions/cache@v4
- id: node-cache # use this to check for `cache-hit` (`steps.node-cache.outputs.cache-hit != 'true'`)
- with:
- path: '**/node_modules'
- key: ${{ runner.os }}-node-${{ hashFiles('**/yarn.lock') }}
- restore-keys: |
- ${{ runner.os }}-node-
- - name: Set up Crystal cache
- uses: actions/cache@v4
- id: crystal-cache
- with:
- path: |
- ~/.cache/crystal
- lib
- key: ${{ runner.os }}-crystal-${{ hashFiles('**/shard.lock') }}
- restore-keys: |
- ${{ runner.os }}-crystal-
-
- - name: Install shards
- if: steps.crystal-cache.outputs.cache-hit != 'true'
- run: shards check || shards install
-
- - name: Install yarn packages
- if: steps.node-cache.outputs.cache-hit != 'true'
- run: yarn install --frozen-lockfile --no-progress
- - name: Compiling assets
- run: yarn prod
- - name: Build lucky_tasks
- run: crystal build tasks.cr -o ./lucky_tasks
-
- - name: Prepare database
- run: |
- ./lucky_tasks db.create
- ./lucky_tasks db.migrate
- ./lucky_tasks db.seed.required_data
-
- - name: Run tests
- run: crystal spec -Dwith_sec_tests
\ No newline at end of file
diff --git a/fixtures/src_template__sec_tester/expected/Procfile b/fixtures/src_template__sec_tester/expected/Procfile
deleted file mode 100644
index e524d70d..00000000
--- a/fixtures/src_template__sec_tester/expected/Procfile
+++ /dev/null
@@ -1,2 +0,0 @@
-web: bin/app
-release: lucky db.migrate
diff --git a/fixtures/src_template__sec_tester/expected/Procfile.dev b/fixtures/src_template__sec_tester/expected/Procfile.dev
deleted file mode 100644
index 80369f14..00000000
--- a/fixtures/src_template__sec_tester/expected/Procfile.dev
+++ /dev/null
@@ -1,3 +0,0 @@
-system_check: crystal script/system_check.cr
-web: lucky watch --reload-browser
-assets: yarn dev
diff --git a/fixtures/src_template__sec_tester/expected/README.md b/fixtures/src_template__sec_tester/expected/README.md
deleted file mode 100644
index da2d97cc..00000000
--- a/fixtures/src_template__sec_tester/expected/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# test-project
-
-This is a project written using [Lucky](https://luckyframework.org). Enjoy!
-
-### Setting up the project
-
-1. [Install required dependencies](https://luckyframework.org/guides/getting-started/installing#install-required-dependencies)
-1. Update database settings in `config/database.cr`
-1. Run `script/setup`
-1. Run `lucky dev` to start the app
-
-### Using Docker for development
-
-1. [Install Docker](https://docs.docker.com/engine/install/)
-1. Run `docker compose up`
-
-The Docker container will boot all of the necessary components needed to run your Lucky application.
-To configure the container, update the `docker-compose.yml` file, and the `docker/development.dockerfile` file.
-
-
-### Learning Lucky
-
-Lucky uses the [Crystal](https://crystal-lang.org) programming language. You can learn about Lucky from the [Lucky Guides](https://luckyframework.org/guides/getting-started/why-lucky).
diff --git a/fixtures/src_template__sec_tester/expected/config/application.cr b/fixtures/src_template__sec_tester/expected/config/application.cr
deleted file mode 100644
index c807149a..00000000
--- a/fixtures/src_template__sec_tester/expected/config/application.cr
+++ /dev/null
@@ -1,24 +0,0 @@
-# This file may be used for custom Application configurations.
-# It will be loaded before other config files.
-#
-# Read more on configuration:
-# https://luckyframework.org/guides/getting-started/configuration#configuring-your-own-code
-
-# Use this code as an example:
-#
-# ```
-# module Application
-# Habitat.create do
-# setting support_email : String
-# setting lock_with_basic_auth : Bool
-# end
-# end
-#
-# Application.configure do |settings|
-# settings.support_email = "support@myapp.io"
-# settings.lock_with_basic_auth = LuckyEnv.staging?
-# end
-#
-# # In your application, call
-# # `Application.settings.support_email` anywhere you need it.
-# ```
diff --git a/fixtures/src_template__sec_tester/expected/config/colors.cr b/fixtures/src_template__sec_tester/expected/config/colors.cr
deleted file mode 100644
index 761ae940..00000000
--- a/fixtures/src_template__sec_tester/expected/config/colors.cr
+++ /dev/null
@@ -1,4 +0,0 @@
-# This enables the color output when in development or test
-# Check out the Colorize docs for more information
-# https://crystal-lang.org/api/Colorize.html
-Colorize.enabled = LuckyEnv.development? || LuckyEnv.test?
diff --git a/fixtures/src_template__sec_tester/expected/config/cookies.cr b/fixtures/src_template__sec_tester/expected/config/cookies.cr
deleted file mode 100644
index 2d5055f2..00000000
--- a/fixtures/src_template__sec_tester/expected/config/cookies.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-require "./server"
-
-Lucky::Session.configure do |settings|
- settings.key = "_test_project_session"
-end
-
-Lucky::CookieJar.configure do |settings|
- settings.on_set = ->(cookie : HTTP::Cookie) {
- # If ForceSSLHandler is enabled, only send cookies over HTTPS
- cookie.secure(Lucky::ForceSSLHandler.settings.enabled)
-
- # By default, don't allow reading cookies with JavaScript
- cookie.http_only(true)
-
- # Restrict cookies to a first-party or same-site context
- cookie.samesite(:lax)
-
- # Set all cookies to the root path by default
- cookie.path("/")
-
- # You can set other defaults for cookies here. For example:
- #
- # cookie.expires(1.year.from_now).domain("mydomain.com")
- }
-end
diff --git a/fixtures/src_template__sec_tester/expected/config/database.cr b/fixtures/src_template__sec_tester/expected/config/database.cr
deleted file mode 100644
index f614299a..00000000
--- a/fixtures/src_template__sec_tester/expected/config/database.cr
+++ /dev/null
@@ -1,29 +0,0 @@
-database_name = "test_project_#{LuckyEnv.environment}"
-
-AppDatabase.configure do |settings|
- if LuckyEnv.production?
- settings.credentials = Avram::Credentials.parse(ENV["DATABASE_URL"])
- else
- settings.credentials = Avram::Credentials.parse?(ENV["DATABASE_URL"]?) || Avram::Credentials.new(
- database: database_name,
- hostname: ENV["DB_HOST"]? || "localhost",
- port: ENV["DB_PORT"]?.try(&.to_i) || 5432,
- # Some common usernames are "postgres", "root", or your system username (run 'whoami')
- username: ENV["DB_USERNAME"]? || "postgres",
- # Some Postgres installations require no password. Use "" if that is the case.
- password: ENV["DB_PASSWORD"]? || "postgres"
- )
- end
-end
-
-Avram.configure do |settings|
- settings.database_to_migrate = AppDatabase
-
- # In production, allow lazy loading (N+1).
- # In development and test, raise an error if you forget to preload associations
- settings.lazy_load_enabled = LuckyEnv.production?
-
- # Always parse `Time` values with these specific formats.
- # Used for both database values, and datetime input fields.
- # settings.time_formats << "%F"
-end
diff --git a/fixtures/src_template__sec_tester/expected/config/email.cr b/fixtures/src_template__sec_tester/expected/config/email.cr
deleted file mode 100644
index 7c875449..00000000
--- a/fixtures/src_template__sec_tester/expected/config/email.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-require "carbon_sendgrid_adapter"
-
-BaseEmail.configure do |settings|
- if LuckyEnv.production?
- # If you don't need to send emails, set the adapter to DevAdapter instead:
- #
- # settings.adapter = Carbon::DevAdapter.new
- #
- # If you do need emails, get a key from SendGrid and set an ENV variable
- send_grid_key = send_grid_key_from_env
- settings.adapter = Carbon::SendGridAdapter.new(api_key: send_grid_key)
- elsif LuckyEnv.development?
- settings.adapter = Carbon::DevAdapter.new(print_emails: true)
- else
- settings.adapter = Carbon::DevAdapter.new
- end
-end
-
-private def send_grid_key_from_env
- ENV["SEND_GRID_KEY"]? || raise_missing_key_message
-end
-
-private def raise_missing_key_message
- puts "Missing SEND_GRID_KEY. Set the SEND_GRID_KEY env variable to 'unused' if not sending emails, or set the SEND_GRID_KEY ENV var.".colorize.red
- exit(1)
-end
diff --git a/fixtures/src_template__sec_tester/expected/config/env.cr b/fixtures/src_template__sec_tester/expected/config/env.cr
deleted file mode 100644
index 3f364072..00000000
--- a/fixtures/src_template__sec_tester/expected/config/env.cr
+++ /dev/null
@@ -1,33 +0,0 @@
-# Environments are managed using `LuckyEnv`. By default, development, production
-# and test are supported. See
-# https://luckyframework.org/guides/getting-started/configuration for details.
-#
-# The default environment is development unless the environment variable
-# LUCKY_ENV is set.
-#
-# Example:
-# ```
-# LuckyEnv.environment # => "development"
-# LuckyEnv.development? # => true
-# LuckyEnv.production? # => false
-# LuckyEnv.test? # => false
-# ```
-#
-# New environments can be added using the `LuckyEnv.add_env` macro.
-#
-# Example:
-# ```
-# LuckyEnv.add_env :staging
-# LuckyEnv.staging? # => false
-# ```
-#
-# To determine whether or not a `LuckyTask` is currently running, you can use
-# the `LuckyEnv.task?` predicate.
-#
-# Example:
-# ```
-# LuckyEnv.task? # => false
-# ```
-
-# Add a staging environment.
-# LuckyEnv.add_env :staging
diff --git a/fixtures/src_template__sec_tester/expected/config/error_handler.cr b/fixtures/src_template__sec_tester/expected/config/error_handler.cr
deleted file mode 100644
index c6b736e3..00000000
--- a/fixtures/src_template__sec_tester/expected/config/error_handler.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Lucky::ErrorHandler.configure do |settings|
- settings.show_debug_output = !LuckyEnv.production?
-end
diff --git a/fixtures/src_template__sec_tester/expected/config/log.cr b/fixtures/src_template__sec_tester/expected/config/log.cr
deleted file mode 100644
index a43940d9..00000000
--- a/fixtures/src_template__sec_tester/expected/config/log.cr
+++ /dev/null
@@ -1,50 +0,0 @@
-require "file_utils"
-
-if LuckyEnv.test?
- # Logs to `tmp/test.log` so you can see what's happening without having
- # a bunch of log output in your spec results.
- FileUtils.mkdir_p("tmp")
-
- backend = Log::IOBackend.new(File.new("tmp/test.log", mode: "w"))
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
-elsif LuckyEnv.production?
- # Lucky uses JSON in production so logs can be searched more easily
- #
- # If you want logs like in development use 'Lucky::PrettyLogFormatter.proc'.
- backend = Log::IOBackend.new
- backend.formatter = Dexter::JSONLogFormatter.proc
- Log.dexter.configure(:info, backend)
-else
- # Use a pretty formatter printing to STDOUT in development
- backend = Log::IOBackend.new
- backend.formatter = Lucky::PrettyLogFormatter.proc
- Log.dexter.configure(:debug, backend)
- DB::Log.level = :info
-end
-
-# Lucky only logs when before/after pipes halt by redirecting, or rendering a
-# response. Pipes that run without halting are not logged.
-#
-# If you want to log every pipe that runs, set the log level to ':info'
-Lucky::ContinuedPipeLog.dexter.configure(:none)
-
-# Lucky only logs failed queries by default.
-#
-# Set the log to ':info' to log all queries
-Avram::QueryLog.dexter.configure(:none)
-
-# Subscribe to Pulsar events to log when queries are made,
-# queries fail, or save operations fail. Remove this to
-# disable these log events without disabling all logging.
-Avram.initialize_logging
-
-# Skip logging static assets requests in development
-Lucky::LogHandler.configure do |settings|
- if LuckyEnv.development?
- settings.skip_if = ->(context : HTTP::Server::Context) {
- context.request.method.downcase == "get" &&
- context.request.resource.starts_with?(/\/css\/|\/js\/|\/assets\/|\/favicon\.ico/)
- }
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/config/route_helper.cr b/fixtures/src_template__sec_tester/expected/config/route_helper.cr
deleted file mode 100644
index ede1f328..00000000
--- a/fixtures/src_template__sec_tester/expected/config/route_helper.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-# This is used when generating URLs for your application
-Lucky::RouteHelper.configure do |settings|
- if LuckyEnv.production?
- # Example: https://my_app.com
- settings.base_uri = ENV.fetch("APP_DOMAIN")
- else
- # Set domain to the default host/port in development/test
- settings.base_uri = "http://localhost:#{Lucky::ServerSettings.port}"
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/config/server.cr b/fixtures/src_template__sec_tester/expected/config/server.cr
deleted file mode 100644
index b7cca25c..00000000
--- a/fixtures/src_template__sec_tester/expected/config/server.cr
+++ /dev/null
@@ -1,68 +0,0 @@
-# Here is where you configure the Lucky server
-#
-# Look at config/route_helper.cr if you want to change the domain used when
-# generating links with `Action.url`.
-Lucky::Server.configure do |settings|
- if LuckyEnv.production?
- settings.secret_key_base = secret_key_from_env
- settings.host = "0.0.0.0"
- settings.port = ENV["PORT"].to_i
- settings.gzip_enabled = true
- # By default certain content types will be gzipped.
- # For a full list look in
- # https://github.com/luckyframework/lucky/blob/main/src/lucky/server.cr
- # To add additional extensions do something like this:
- # settings.gzip_content_types << "content/type"
- else
- settings.secret_key_base = "1234567890"
- # Change host/port in config/watch.yml
- # Alternatively, you can set the DEV_PORT env to set the port for local development
- settings.host = Lucky::ServerSettings.host
- settings.port = Lucky::ServerSettings.port
- end
-
- # Configure the asset build system (default is Vite)
- settings.asset_build_system = Lucky::AssetBuilder::Vite.new
-
- # Configure asset host for Vite
- if LuckyEnv.development?
- # In development, Vite serves assets from its dev server
- settings.asset_host = "http://localhost:3001"
- elsif LuckyEnv.production?
- # In production, Lucky serves the built assets
- # You could also use a CDN here:
- # settings.asset_host = "https://mycdnhost.com"
- settings.asset_host = ""
- else
- settings.asset_host = ""
- end
-end
-
-Lucky::ForceSSLHandler.configure do |settings|
- # To force SSL in production, uncomment the lines below.
- # This will cause http requests to be redirected to https:
- #
- # settings.enabled = LuckyEnv.production?
- # settings.strict_transport_security = {max_age: 1.year, include_subdomains: true}
- #
- # Or, leave it disabled:
- settings.enabled = false
-end
-
-# Set a unique ID for each HTTP request.
-# To enable the request ID, uncomment the lines below.
-# You can set your own custom String, or use a random UUID.
-# Lucky::RequestIdHandler.configure do |settings|
-# settings.set_request_id = ->(context : HTTP::Server::Context) {
-# UUID.random.to_s
-# }
-# end
-
-private def secret_key_from_env
- ENV["SECRET_KEY_BASE"]? || raise_missing_secret_key_in_production
-end
-
-private def raise_missing_secret_key_in_production
- puts "Please set the SECRET_KEY_BASE environment variable. You can generate a secret key with 'lucky gen.secret_key'".colorize.red
- exit(1)
-end
\ No newline at end of file
diff --git a/fixtures/src_template__sec_tester/expected/config/watch.yml b/fixtures/src_template__sec_tester/expected/config/watch.yml
deleted file mode 100644
index 3a59b410..00000000
--- a/fixtures/src_template__sec_tester/expected/config/watch.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-host: 127.0.0.1
-port: 3000
-reload_port: 3001
diff --git a/fixtures/src_template__sec_tester/expected/db/migrations/.keep b/fixtures/src_template__sec_tester/expected/db/migrations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/docker-compose.yml b/fixtures/src_template__sec_tester/expected/docker-compose.yml
deleted file mode 100644
index d00779db..00000000
--- a/fixtures/src_template__sec_tester/expected/docker-compose.yml
+++ /dev/null
@@ -1,45 +0,0 @@
-version: "3.8"
-services:
- lucky:
- build:
- context: .
- dockerfile: docker/development.dockerfile
- environment:
- DATABASE_URL: postgres://lucky:password@postgres:5432/lucky
- DEV_HOST: "0.0.0.0"
- volumes:
- - .:/app
- - node_modules:/app/node_modules
- - shards_lib:/app/lib
- - app_bin:/app/bin
- - build_cache:/root/.cache
- depends_on:
- - postgres
- ports:
- - 3000:3000 # This is the Lucky Server port
- - 3001:3001 # This is the Lucky watcher reload port
-
- entrypoint: ["docker/dev_entrypoint.sh"]
-
- postgres:
- image: postgres:14-alpine
- environment:
- POSTGRES_USER: lucky
- POSTGRES_PASSWORD: password
- POSTGRES_DB: lucky
- volumes:
- - postgres_data:/var/lib/postgresql/data
- ports:
- # The postgres database container is exposed on the host at port 6543 to
- # allow connecting directly to it with postgres clients. The port differs
- # from the postgres default to avoid conflict with existing postgres
- # servers. Connect to a running postgres container with:
- # postgres://lucky:password@localhost:6543/lucky
- - 6543:5432
-
-volumes:
- postgres_data:
- node_modules:
- shards_lib:
- app_bin:
- build_cache:
diff --git a/fixtures/src_template__sec_tester/expected/docker/dev_entrypoint.sh b/fixtures/src_template__sec_tester/expected/docker/dev_entrypoint.sh
deleted file mode 100755
index d16ef6ab..00000000
--- a/fixtures/src_template__sec_tester/expected/docker/dev_entrypoint.sh
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# This is the entrypoint script used for development docker workflows.
-# By default it will:
-# - Install dependencies.
-# - Run migrations.
-# - Start the dev server.
-# It also accepts any commands to be run instead.
-
-
-warnfail () {
- echo "$@" >&2
- exit 1
-}
-
-case ${1:-} in
- "") # If no arguments are provided, start lucky dev server.
- ;;
-
- *) # If any arguments are provided, execute them instead.
- exec "$@"
-esac
-
-if ! [ -d bin ] ; then
- echo 'Creating bin directory'
- mkdir bin
-fi
-echo 'Installing npm packages...'
-yarn install
-if ! shards check ; then
- echo 'Installing shards...'
- shards install
-fi
-
-echo 'Waiting for postgres to be available...'
-./docker/wait-for-it.sh -q postgres:5432
-
-if ! psql -d "$DATABASE_URL" -c '\d migrations' > /dev/null ; then
- echo 'Finishing database setup...'
- lucky db.migrate
-fi
-
-echo 'Starting lucky dev server...'
-exec lucky dev
diff --git a/fixtures/src_template__sec_tester/expected/docker/development.dockerfile b/fixtures/src_template__sec_tester/expected/docker/development.dockerfile
deleted file mode 100644
index 962ad66c..00000000
--- a/fixtures/src_template__sec_tester/expected/docker/development.dockerfile
+++ /dev/null
@@ -1,33 +0,0 @@
-FROM crystallang/crystal:1.16.1
-
-# Install utilities required to make this Dockerfile run
-RUN apt-get update && \
- apt-get install -y wget
-# Add the nodesource ppa to apt. Update this to change the nodejs version.
-RUN wget https://deb.nodesource.com/setup_16.x -O- | bash
-
-# Apt installs:
-# - nodejs (from above ppa) is required for front-end apps.
-# - Postgres cli tools are required for lucky-cli.
-# - tmux is required for the Overmind process manager.
-RUN apt-get update && \
- apt-get install -y nodejs postgresql-client tmux && \
- rm -rf /var/lib/apt/lists/*
-
-# NPM global installs:
-# - Yarn is the default package manager for the node component of a lucky
-# browser app.
-RUN npm install -g yarn
-
-# Install lucky cli
-WORKDIR /lucky/cli
-RUN git clone https://github.com/luckyframework/lucky_cli . && \
- git checkout v1.3.0 && \
- shards build --without-development && \
- cp bin/lucky /usr/bin
-
-WORKDIR /app
-ENV DATABASE_URL=postgres://postgres:postgres@host.docker.internal:5432/postgres
-EXPOSE 3000
-EXPOSE 3001
-
diff --git a/fixtures/src_template__sec_tester/expected/docker/wait-for-it.sh b/fixtures/src_template__sec_tester/expected/docker/wait-for-it.sh
deleted file mode 100755
index 06e0638c..00000000
--- a/fixtures/src_template__sec_tester/expected/docker/wait-for-it.sh
+++ /dev/null
@@ -1,189 +0,0 @@
-#!/usr/bin/bash
-#
-# Pulled from https://github.com/vishnubob/wait-for-it on 2022-02-28.
-# Licensed under the MIT license as of 81b1373f.
-#
-# Below this line, wait-for-it is the original work of the author.
-#
-# Use this script to test if a given TCP host/port are available
-
-WAITFORIT_cmdname=${0##*/}
-
-echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
-
-usage()
-{
- cat << USAGE >&2
-Usage:
- $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
- -h HOST | --host=HOST Host or IP under test
- -p PORT | --port=PORT TCP port under test
- Alternatively, you specify the host and port as host:port
- -s | --strict Only execute subcommand if the test succeeds
- -q | --quiet Don't output any status messages
- -t TIMEOUT | --timeout=TIMEOUT
- Timeout in seconds, zero for no timeout
- -- COMMAND ARGS Execute command with args after the test finishes
-USAGE
- exit 1
-}
-
-wait_for()
-{
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- else
- echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
- fi
- WAITFORIT_start_ts=$(date +%s)
- while :
- do
- if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
- nc -z $WAITFORIT_HOST $WAITFORIT_PORT
- WAITFORIT_result=$?
- else
- (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
- WAITFORIT_result=$?
- fi
- if [[ $WAITFORIT_result -eq 0 ]]; then
- WAITFORIT_end_ts=$(date +%s)
- echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
- break
- fi
- sleep 1
- done
- return $WAITFORIT_result
-}
-
-wait_for_wrapper()
-{
- # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
- if [[ $WAITFORIT_QUIET -eq 1 ]]; then
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- else
- timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
- fi
- WAITFORIT_PID=$!
- trap "kill -INT -$WAITFORIT_PID" INT
- wait $WAITFORIT_PID
- WAITFORIT_RESULT=$?
- if [[ $WAITFORIT_RESULT -ne 0 ]]; then
- echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
- fi
- return $WAITFORIT_RESULT
-}
-
-# process arguments
-while [[ $# -gt 0 ]]
-do
- case "$1" in
- *:* )
- WAITFORIT_hostport=(${1//:/ })
- WAITFORIT_HOST=${WAITFORIT_hostport[0]}
- WAITFORIT_PORT=${WAITFORIT_hostport[1]}
- shift 1
- ;;
- --child)
- WAITFORIT_CHILD=1
- shift 1
- ;;
- -q | --quiet)
- WAITFORIT_QUIET=1
- shift 1
- ;;
- -s | --strict)
- WAITFORIT_STRICT=1
- shift 1
- ;;
- -h)
- WAITFORIT_HOST="$2"
- if [[ $WAITFORIT_HOST == "" ]]; then break; fi
- shift 2
- ;;
- --host=*)
- WAITFORIT_HOST="${1#*=}"
- shift 1
- ;;
- -p)
- WAITFORIT_PORT="$2"
- if [[ $WAITFORIT_PORT == "" ]]; then break; fi
- shift 2
- ;;
- --port=*)
- WAITFORIT_PORT="${1#*=}"
- shift 1
- ;;
- -t)
- WAITFORIT_TIMEOUT="$2"
- if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
- shift 2
- ;;
- --timeout=*)
- WAITFORIT_TIMEOUT="${1#*=}"
- shift 1
- ;;
- --)
- shift
- WAITFORIT_CLI=("$@")
- break
- ;;
- --help)
- usage
- ;;
- *)
- echoerr "Unknown argument: $1"
- usage
- ;;
- esac
-done
-
-if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
- echoerr "Error: you need to provide a host and port to test."
- usage
-fi
-
-WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
-WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
-WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
-WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
-
-# Check to see if timeout is from busybox?
-WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
-WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
-
-WAITFORIT_BUSYTIMEFLAG=""
-if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
- WAITFORIT_ISBUSY=1
- # Check if busybox timeout uses -t flag
- # (recent Alpine versions don't support -t anymore)
- if timeout &>/dev/stdout | grep -q -e '-t '; then
- WAITFORIT_BUSYTIMEFLAG="-t"
- fi
-else
- WAITFORIT_ISBUSY=0
-fi
-
-if [[ $WAITFORIT_CHILD -gt 0 ]]; then
- wait_for
- WAITFORIT_RESULT=$?
- exit $WAITFORIT_RESULT
-else
- if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
- wait_for_wrapper
- WAITFORIT_RESULT=$?
- else
- wait_for
- WAITFORIT_RESULT=$?
- fi
-fi
-
-if [[ $WAITFORIT_CLI != "" ]]; then
- if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
- echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
- exit $WAITFORIT_RESULT
- fi
- exec "${WAITFORIT_CLI[@]}"
-else
- exit $WAITFORIT_RESULT
-fi
-
diff --git a/fixtures/src_template__sec_tester/expected/script/helpers/function_helpers.cr b/fixtures/src_template__sec_tester/expected/script/helpers/function_helpers.cr
deleted file mode 100644
index 8abcb6a2..00000000
--- a/fixtures/src_template__sec_tester/expected/script/helpers/function_helpers.cr
+++ /dev/null
@@ -1,32 +0,0 @@
-require "colorize"
-
-# These are helper methods provided to help keep your code
-# clean. Add new methods, or alter these as needed.
-
-def notice(message : String) : Nil
- puts "\n▸ #{message}"
-end
-
-def print_done : Nil
- puts "✔ Done"
-end
-
-def print_error(message : String) : Nil
- puts "There is a problem with your system setup:\n".colorize.red.bold
- puts "#{message}\n".colorize.red.bold
- Process.exit(1)
-end
-
-def command_not_found(command : String) : Bool
- Process.find_executable(command).nil?
-end
-
-def command_not_running(command : String, *args) : Bool
- output = IO::Memory.new
- code = Process.run(command, args, output: output).exit_code
- code > 0
-end
-
-def run_command(command : String, *args) : Nil
- Process.run(command, args, output: STDOUT, error: STDERR, input: STDIN)
-end
diff --git a/fixtures/src_template__sec_tester/expected/script/setup.cr b/fixtures/src_template__sec_tester/expected/script/setup.cr
deleted file mode 100644
index faa74914..00000000
--- a/fixtures/src_template__sec_tester/expected/script/setup.cr
+++ /dev/null
@@ -1,32 +0,0 @@
-require "./helpers/*"
-
-notice "Running System Check"
-
-require "./system_check"
-
-print_done
-
-notice "Installing node dependencies"
-run_command "yarn", "install", "--no-progress"
-
-print_done
-
-notice "Installing shards"
-run_command "shards", "install"
-
-if !File.exists?(".env")
- notice "No .env found. Creating one."
- File.touch ".env"
- print_done
-end
-
-notice "Setting up the database"
-
-run_command "lucky", "db.setup"
-
-notice "Seeding the database with required and sample records"
-run_command "lucky", "db.seed.required_data"
-run_command "lucky", "db.seed.sample_data"
-
-print_done
-notice "Run 'lucky dev' to start the app"
\ No newline at end of file
diff --git a/fixtures/src_template__sec_tester/expected/script/system_check.cr b/fixtures/src_template__sec_tester/expected/script/system_check.cr
deleted file mode 100644
index c56ce3e9..00000000
--- a/fixtures/src_template__sec_tester/expected/script/system_check.cr
+++ /dev/null
@@ -1,21 +0,0 @@
-require "./helpers/*"
-
-# Use this script to check the system for required tools and process that your app needs.
-# A few helper functions are provided to keep the code simple. See the
-# script/helpers/function_helpers.cr file for more examples.
-#
-# A few examples you might use here:
-# * 'lucky db.verify_connection' to test postgres can be connected
-# * Checking that elasticsearch, redis, or postgres is installed and/or booted
-# * Note: Booting additional processes for things like mail, background jobs, etc...
-# should go in your Procfile.dev.
-
-if command_not_found "yarn"
- print_error "Yarn is not installed\n See https://yarnpkg.com/lang/en/docs/install/ for install instructions."
-end
-
-# CUSTOM PRE-BOOT CHECKS
-# example:
-# if command_not_running "redis-cli", "ping"
-# print_error "Redis is not running."
-# end
diff --git a/fixtures/src_template__sec_tester/expected/spec/setup/clean_database.cr b/fixtures/src_template__sec_tester/expected/spec/setup/clean_database.cr
deleted file mode 100644
index a1bc631c..00000000
--- a/fixtures/src_template__sec_tester/expected/spec/setup/clean_database.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- AppDatabase.truncate
-end
diff --git a/fixtures/src_template__sec_tester/expected/spec/setup/reset_emails.cr b/fixtures/src_template__sec_tester/expected/spec/setup/reset_emails.cr
deleted file mode 100644
index 140ab416..00000000
--- a/fixtures/src_template__sec_tester/expected/spec/setup/reset_emails.cr
+++ /dev/null
@@ -1,3 +0,0 @@
-Spec.before_each do
- Carbon::DevAdapter.reset
-end
diff --git a/fixtures/src_template__sec_tester/expected/spec/setup/setup_database.cr b/fixtures/src_template__sec_tester/expected/spec/setup/setup_database.cr
deleted file mode 100644
index 393c6da3..00000000
--- a/fixtures/src_template__sec_tester/expected/spec/setup/setup_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-Db::Create.new(quiet: true).call
-Db::Migrate.new(quiet: true).call
diff --git a/fixtures/src_template__sec_tester/expected/spec/setup/start_app_server.cr b/fixtures/src_template__sec_tester/expected/spec/setup/start_app_server.cr
deleted file mode 100644
index ff0bfeeb..00000000
--- a/fixtures/src_template__sec_tester/expected/spec/setup/start_app_server.cr
+++ /dev/null
@@ -1,10 +0,0 @@
-app_server = AppServer.new
-
-spawn do
- app_server.listen
-end
-
-Spec.after_suite do
- LuckyFlow.shutdown
- app_server.close
-end
diff --git a/fixtures/src_template__sec_tester/expected/spec/spec_helper.cr b/fixtures/src_template__sec_tester/expected/spec/spec_helper.cr
deleted file mode 100644
index 87be38b6..00000000
--- a/fixtures/src_template__sec_tester/expected/spec/spec_helper.cr
+++ /dev/null
@@ -1,27 +0,0 @@
-ENV["LUCKY_ENV"] = "test"
-ENV["DEV_PORT"] = "5001"
-require "spec"
-require "lucky_flow"
-require "lucky_flow/ext/lucky"
-require "lucky_flow/ext/avram"
-require "../src/app"
-require "./support/flows/base_flow"
-require "./support/**"
-require "../db/migrations/**"
-
-# Add/modify files in spec/setup to start/configure programs or run hooks
-#
-# By default there are scripts for setting up and cleaning the database,
-# configuring LuckyFlow, starting the app server, etc.
-require "./setup/**"
-
-include Carbon::Expectations
-include Lucky::RequestExpectations
-# NOTE: LuckyFlow specs are temporarily set to pending as of Lucky v1.4.0
-# This is due to race conditions in LuckyFlow.
-# Ref: https://github.com/luckyframework/lucky_cli/issues/883
-include LuckyFlow::Expectations
-
-Avram::Migrator::Runner.new.ensure_migrated!
-Avram::SchemaEnforcer.ensure_correct_column_mappings!
-Habitat.raise_if_missing_settings!
diff --git a/fixtures/src_template__sec_tester/expected/spec/support/.keep b/fixtures/src_template__sec_tester/expected/spec/support/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/spec/support/api_client.cr b/fixtures/src_template__sec_tester/expected/spec/support/api_client.cr
deleted file mode 100644
index ef251251..00000000
--- a/fixtures/src_template__sec_tester/expected/spec/support/api_client.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-class ApiClient < Lucky::BaseHTTPClient
- app AppServer.new
-
- def initialize
- super
- headers("Content-Type": "application/json")
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/spec/support/factories/.keep b/fixtures/src_template__sec_tester/expected/spec/support/factories/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/actions/api_action.cr b/fixtures/src_template__sec_tester/expected/src/actions/api_action.cr
deleted file mode 100644
index fac02c8b..00000000
--- a/fixtures/src_template__sec_tester/expected/src/actions/api_action.cr
+++ /dev/null
@@ -1,11 +0,0 @@
-# Include modules and add methods that are for all API requests
-abstract class ApiAction < Lucky::Action
- # APIs typically do not need to send cookie/session data.
- # Remove this line if you want to send cookies in the response header.
- disable_cookies
- accepted_formats [:json]
-
- # By default all actions are required to use underscores to separate words.
- # Add 'include Lucky::SkipRouteStyleCheck' to your actions if you wish to ignore this check for specific routes.
- include Lucky::EnforceUnderscoredRoute
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/actions/errors/show.cr b/fixtures/src_template__sec_tester/expected/src/actions/errors/show.cr
deleted file mode 100644
index d01ed541..00000000
--- a/fixtures/src_template__sec_tester/expected/src/actions/errors/show.cr
+++ /dev/null
@@ -1,63 +0,0 @@
-# This class handles error responses and reporting.
-#
-# https://luckyframework.org/guides/http-and-routing/error-handling
-class Errors::Show < Lucky::ErrorAction
- DEFAULT_MESSAGE = "Something went wrong."
- default_format :html
- dont_report [Lucky::RouteNotFoundError, Avram::RecordNotFoundError]
-
- def render(error : Lucky::RouteNotFoundError | Avram::RecordNotFoundError)
- if html?
- error_html "Sorry, we couldn't find that page.", status: 404
- else
- error_json "Not found", status: 404
- end
- end
-
- # When the request is JSON and an InvalidOperationError is raised, show a
- # helpful error with the param that is invalid, and what was wrong with it.
- def render(error : Avram::InvalidOperationError)
- if html?
- error_html DEFAULT_MESSAGE, status: 500
- else
- error_json \
- message: error.renderable_message,
- details: error.renderable_details,
- param: error.invalid_attribute_name,
- status: 400
- end
- end
-
- # Always keep this below other 'render' methods or it may override your
- # custom 'render' methods.
- def render(error : Lucky::RenderableError)
- if html?
- error_html DEFAULT_MESSAGE, status: error.renderable_status
- else
- error_json error.renderable_message, status: error.renderable_status
- end
- end
-
- # If none of the 'render' methods return a response for the raised Exception,
- # Lucky will use this method.
- def default_render(error : Exception) : Lucky::Response
- if html?
- error_html DEFAULT_MESSAGE, status: 500
- else
- error_json DEFAULT_MESSAGE, status: 500
- end
- end
-
- private def error_html(message : String, status : Int)
- context.response.status_code = status
- html_with_status Errors::ShowPage, status, message: message, status_code: status
- end
-
- private def error_json(message : String, status : Int, details = nil, param = nil)
- json ErrorSerializer.new(message: message, details: details, param: param), status: status
- end
-
- private def report(error : Exception) : Nil
- # Send to Rollbar, send an email, etc.
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/actions/home/index.cr b/fixtures/src_template__sec_tester/expected/src/actions/home/index.cr
deleted file mode 100644
index 2d39a100..00000000
--- a/fixtures/src_template__sec_tester/expected/src/actions/home/index.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-class Home::Index < BrowserAction
- get "/" do
- html Lucky::WelcomePage
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/actions/mixins/.keep b/fixtures/src_template__sec_tester/expected/src/actions/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/app.cr b/fixtures/src_template__sec_tester/expected/src/app.cr
deleted file mode 100644
index d343c8cd..00000000
--- a/fixtures/src_template__sec_tester/expected/src/app.cr
+++ /dev/null
@@ -1,37 +0,0 @@
-require "./shards"
-
-# Load the asset manifest
-# In development, vite-plugin-dev-manifest creates public/manifest.dev.json
-# In production, Vite creates public/.vite/manifest.json
-# The manifest path is determined by which file exists at compile time
-{% if File.exists?("public/manifest.dev.json") %}
- Lucky::AssetHelpers.load_manifest "public/manifest.dev.json", use_vite: true
-{% elsif File.exists?("public/.vite/manifest.json") %}
- Lucky::AssetHelpers.load_manifest "public/.vite/manifest.json", use_vite: true
-{% else %}
- # For initial compilation, we'll assume development mode
- # The dev server will create the manifest before the app is recompiled
- Lucky::AssetHelpers.load_manifest "public/manifest.dev.json", use_vite: true
-{% end %}
-
-require "../config/server"
-require "./app_database"
-require "../config/**"
-require "./models/base_model"
-require "./models/mixins/**"
-require "./models/**"
-require "./queries/mixins/**"
-require "./queries/**"
-require "./operations/mixins/**"
-require "./operations/**"
-require "./serializers/base_serializer"
-require "./serializers/**"
-require "./emails/base_email"
-require "./emails/**"
-require "./actions/mixins/**"
-require "./actions/**"
-require "./components/base_component"
-require "./components/**"
-require "./pages/**"
-require "../db/migrations/**"
-require "./app_server"
\ No newline at end of file
diff --git a/fixtures/src_template__sec_tester/expected/src/app_database.cr b/fixtures/src_template__sec_tester/expected/src/app_database.cr
deleted file mode 100644
index 0efd4f50..00000000
--- a/fixtures/src_template__sec_tester/expected/src/app_database.cr
+++ /dev/null
@@ -1,2 +0,0 @@
-class AppDatabase < Avram::Database
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/app_server.cr b/fixtures/src_template__sec_tester/expected/src/app_server.cr
deleted file mode 100644
index 8ec16c3c..00000000
--- a/fixtures/src_template__sec_tester/expected/src/app_server.cr
+++ /dev/null
@@ -1,26 +0,0 @@
-class AppServer < Lucky::BaseAppServer
- # Learn about middleware with HTTP::Handlers:
- # https://luckyframework.org/guides/http-and-routing/http-handlers
- def middleware : Array(HTTP::Handler)
- [
- Lucky::RequestIdHandler.new,
- Lucky::ForceSSLHandler.new,
- Lucky::HttpMethodOverrideHandler.new,
- Lucky::LogHandler.new,
- Lucky::ErrorHandler.new(action: Errors::Show),
- Lucky::RemoteIpHandler.new,
- Lucky::RouteHandler.new,
- Lucky::StaticCompressionHandler.new("./public", file_ext: "gz", content_encoding: "gzip"),
- Lucky::StaticFileHandler.new("./public", fallthrough: false, directory_listing: false),
- Lucky::RouteNotFoundHandler.new,
- ] of HTTP::Handler
- end
-
- def protocol
- "http"
- end
-
- def listen
- server.listen(host, port, reuse_port: false)
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/emails/base_email.cr b/fixtures/src_template__sec_tester/expected/src/emails/base_email.cr
deleted file mode 100644
index 656f4f11..00000000
--- a/fixtures/src_template__sec_tester/expected/src/emails/base_email.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# Learn about sending emails
-# https://luckyframework.org/guides/emails/sending-emails-with-carbon
-abstract class BaseEmail < Carbon::Email
- # You can add defaults using the 'inherited' hook
- #
- # Example:
- #
- # macro inherited
- # from default_from
- # end
- #
- # def default_from
- # Carbon::Address.new("support@app.com")
- # end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/models/base_model.cr b/fixtures/src_template__sec_tester/expected/src/models/base_model.cr
deleted file mode 100644
index 6bafeb84..00000000
--- a/fixtures/src_template__sec_tester/expected/src/models/base_model.cr
+++ /dev/null
@@ -1,5 +0,0 @@
-abstract class BaseModel < Avram::Model
- def self.database : Avram::Database.class
- AppDatabase
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/models/mixins/.keep b/fixtures/src_template__sec_tester/expected/src/models/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/operations/.keep b/fixtures/src_template__sec_tester/expected/src/operations/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/operations/mixins/.keep b/fixtures/src_template__sec_tester/expected/src/operations/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/queries/.keep b/fixtures/src_template__sec_tester/expected/src/queries/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/queries/mixins/.keep b/fixtures/src_template__sec_tester/expected/src/queries/mixins/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/serializers/.keep b/fixtures/src_template__sec_tester/expected/src/serializers/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/src/serializers/base_serializer.cr b/fixtures/src_template__sec_tester/expected/src/serializers/base_serializer.cr
deleted file mode 100644
index e769f5c0..00000000
--- a/fixtures/src_template__sec_tester/expected/src/serializers/base_serializer.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-abstract class BaseSerializer
- include Lucky::Serializable
-
- def self.for_collection(collection : Enumerable, *args, **named_args) : Array(self)
- collection.map do |object|
- new(object, *args, **named_args)
- end
- end
-
- def self.for_collection(collection : Enumerable, pages : Lucky::Paginator, *args, **named_args)
- {
- "items" => collection.map do |object|
- new(object, *args, **named_args)
- end,
- "pagination" => PaginationSerializer.new(pages),
- }
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/serializers/error_serializer.cr b/fixtures/src_template__sec_tester/expected/src/serializers/error_serializer.cr
deleted file mode 100644
index b7b55283..00000000
--- a/fixtures/src_template__sec_tester/expected/src/serializers/error_serializer.cr
+++ /dev/null
@@ -1,14 +0,0 @@
-# This is the default error serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class ErrorSerializer < BaseSerializer
- def initialize(
- @message : String,
- @details : String? = nil,
- @param : String? = nil, # so you can track which param (if any) caused the problem
- )
- end
-
- def render
- {message: @message, param: @param, details: @details}
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/serializers/pagination_serializer.cr b/fixtures/src_template__sec_tester/expected/src/serializers/pagination_serializer.cr
deleted file mode 100644
index 9e44788c..00000000
--- a/fixtures/src_template__sec_tester/expected/src/serializers/pagination_serializer.cr
+++ /dev/null
@@ -1,15 +0,0 @@
-# This is the default pagination serializer generated by Lucky.
-# Feel free to customize it in any way you like.
-class PaginationSerializer < BaseSerializer
- def initialize(@pages : Lucky::Paginator)
- end
-
- def render
- {
- next_page: @pages.path_to_next,
- previous_page: @pages.path_to_previous,
- total_items: @pages.item_count,
- total_pages: @pages.total,
- }
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/src/shards.cr b/fixtures/src_template__sec_tester/expected/src/shards.cr
deleted file mode 100644
index 1afc72cb..00000000
--- a/fixtures/src_template__sec_tester/expected/src/shards.cr
+++ /dev/null
@@ -1,8 +0,0 @@
-# Load .env file before any other config or app code
-require "lucky_env"
-LuckyEnv.load?(".env")
-
-# Require your shards here
-require "lucky"
-require "avram/lucky"
-require "carbon"
diff --git a/fixtures/src_template__sec_tester/expected/src/start_server.cr b/fixtures/src_template__sec_tester/expected/src/start_server.cr
deleted file mode 100644
index de8af78e..00000000
--- a/fixtures/src_template__sec_tester/expected/src/start_server.cr
+++ /dev/null
@@ -1,17 +0,0 @@
-require "./app"
-
-Habitat.raise_if_missing_settings!
-
-if LuckyEnv.development?
- Avram::Migrator::Runner.new.ensure_migrated!
- Avram::SchemaEnforcer.ensure_correct_column_mappings!
-end
-
-app_server = AppServer.new
-puts "Listening on http://#{app_server.host}:#{app_server.port}"
-
-Signal::INT.trap do
- app_server.close
-end
-
-app_server.listen
diff --git a/fixtures/src_template__sec_tester/expected/src/test_project.cr b/fixtures/src_template__sec_tester/expected/src/test_project.cr
deleted file mode 100644
index 68e1a8d2..00000000
--- a/fixtures/src_template__sec_tester/expected/src/test_project.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-# Typically you will not use or modify this file. 'shards build' and some
-# other crystal tools will sometimes use this.
-#
-# When this file is compiled/run it will require and run 'start_server',
-# which as its name implies will start the server for you app.
-require "./start_server"
diff --git a/fixtures/src_template__sec_tester/expected/tasks.cr b/fixtures/src_template__sec_tester/expected/tasks.cr
deleted file mode 100644
index 5a892d4d..00000000
--- a/fixtures/src_template__sec_tester/expected/tasks.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-# This file loads your app and all your tasks when running 'lucky'
-#
-# Run 'lucky --help' to see all available tasks.
-#
-# Learn to create your own tasks:
-# https://luckyframework.org/guides/command-line-tasks/custom-tasks
-
-# See `LuckyEnv#task?`
-ENV["LUCKY_TASK"] = "true"
-
-# Load Lucky and the app (actions, models, etc.)
-require "./src/app"
-require "lucky_task"
-
-# You can add your own tasks here in the ./tasks folder
-require "./tasks/**"
-
-# Load migrations
-require "./db/migrations/**"
-
-# Load Lucky tasks (dev, routes, etc.)
-require "lucky/tasks/**"
-require "avram/lucky/tasks"
-
-LuckyTask::Runner.run
diff --git a/fixtures/src_template__sec_tester/expected/tasks/.keep b/fixtures/src_template__sec_tester/expected/tasks/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/fixtures/src_template__sec_tester/expected/tasks/db/seed/required_data.cr b/fixtures/src_template__sec_tester/expected/tasks/db/seed/required_data.cr
deleted file mode 100644
index d866040f..00000000
--- a/fixtures/src_template__sec_tester/expected/tasks/db/seed/required_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add seeds here that are *required* for your app to work.
-# For example, you might need at least one admin user or you might need at least
-# one category for your blog posts for the app to work.
-#
-# Use `Db::Seed::SampleData` if your only want to add sample data helpful for
-# development.
-class Db::Seed::RequiredData < LuckyTask::Task
- summary "Add database records required for the app to work"
-
- def call
- # Using a Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- #
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- #
- # unless UserQuery.new.email("me@example.com").first?
- # SaveUser.create!(email: "me@example.com", name: "Jane")
- # end
- puts "Done adding required data"
- end
-end
diff --git a/fixtures/src_template__sec_tester/expected/tasks/db/seed/sample_data.cr b/fixtures/src_template__sec_tester/expected/tasks/db/seed/sample_data.cr
deleted file mode 100644
index 231d7e8d..00000000
--- a/fixtures/src_template__sec_tester/expected/tasks/db/seed/sample_data.cr
+++ /dev/null
@@ -1,30 +0,0 @@
-require "../../../spec/support/factories/**"
-
-# Add sample data helpful for development, e.g. (fake users, blog posts, etc.)
-#
-# Use `Db::Seed::RequiredData` if you need to create data *required* for your
-# app to work.
-class Db::Seed::SampleData < LuckyTask::Task
- summary "Add sample database records helpful for development"
-
- def call
- # Using an Avram::Factory:
- #
- # Use the defaults, but override just the email
- # UserFactory.create &.email("me@example.com")
-
- # Using a SaveOperation:
- # ```
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # ```
- #
- # You likely want to be able to run this file more than once. To do that,
- # only create the record if it doesn't exist yet:
- # ```
- # if UserQuery.new.email("me@example.com").none?
- # SignUpUser.create!(email: "me@example.com", password: "test123", password_confirmation: "test123")
- # end
- # ```
- puts "Done adding sample data"
- end
-end
diff --git a/fixtures/tasks.cr b/fixtures/tasks.cr
deleted file mode 100644
index d488be48..00000000
--- a/fixtures/tasks.cr
+++ /dev/null
@@ -1,22 +0,0 @@
-require "../src/lucky_cli"
-
-class PlaceholderTask < LuckyTask::Task
- summary "placeholder"
- help_message "Custom help message"
- switch :test_mode, "Run in test mode."
-
- def call
- output.puts "Calling Placeholder. Test: #{test_mode?}"
- end
-end
-
-class TaskWithInput < LuckyTask::Task
- summary "this should be first"
-
- def call
- input = gets
- puts "input: #{input}"
- end
-end
-
-LuckyTask::Runner.run
diff --git a/shard.yml b/shard.yml
index e6efd2b6..c6e855d8 100644
--- a/shard.yml
+++ b/shard.yml
@@ -7,8 +7,6 @@ authors:
targets:
lucky:
main: src/lucky.cr
- lucky.hello_world:
- main: fixtures/hello_world.cr
crystal: ~> 1.16
diff --git a/spec/end_to_end/api_no_auth_spec.cr b/spec/end_to_end/api_no_auth_spec.cr
new file mode 100644
index 00000000..c327716c
--- /dev/null
+++ b/spec/end_to_end/api_no_auth_spec.cr
@@ -0,0 +1,26 @@
+require "../spec_helper"
+
+include WithProjectCleanup
+include ShouldRunSuccessfully
+
+describe "Lucky CLI", tags: "end_to_end" do
+ describe "building an API app without authentication" do
+ it "generates the app and runs the included specs" do
+ with_project_cleanup do
+ should_run_successfully "crystal run src/lucky.cr -- init.custom test-project --api --no-auth"
+
+ FileUtils.cd "test-project" do
+ {% if !flag?(:windows) %}
+ # Due to formatter on Windows checking different line endings, this will report changes to all crystal files
+ # We only need to test this on 1 OS to ensure things are good
+ should_run_successfully "crystal tool format --check spec src config"
+ {% end %}
+ should_run_successfully "crystal script/setup.cr"
+ should_run_successfully "crystal build src/test_project.cr"
+ should_run_successfully "crystal spec"
+ should_run_successfully "lucky tasks"
+ end
+ end
+ end
+ end
+end
diff --git a/spec/end_to_end/api_with_auth_spec.cr b/spec/end_to_end/api_with_auth_spec.cr
new file mode 100644
index 00000000..e0cb4010
--- /dev/null
+++ b/spec/end_to_end/api_with_auth_spec.cr
@@ -0,0 +1,26 @@
+require "../spec_helper"
+
+include WithProjectCleanup
+include ShouldRunSuccessfully
+
+describe "Lucky CLI", tags: "end_to_end" do
+ describe "building an API app with authentication included" do
+ it "generates the app and runs the included specs" do
+ with_project_cleanup do
+ should_run_successfully "crystal run src/lucky.cr -- init.custom test-project --api"
+
+ FileUtils.cd "test-project" do
+ {% if !flag?(:windows) %}
+ # Due to formatter on Windows checking different line endings, this will report changes to all crystal files
+ # We only need to test this on 1 OS to ensure things are good
+ should_run_successfully "crystal tool format --check spec src config"
+ {% end %}
+ should_run_successfully "crystal script/setup.cr"
+ should_run_successfully "crystal build src/test_project.cr"
+ should_run_successfully "crystal spec"
+ should_run_successfully "lucky tasks"
+ end
+ end
+ end
+ end
+end
diff --git a/spec/end_to_end/browser_no_auth_spec.cr b/spec/end_to_end/browser_no_auth_spec.cr
new file mode 100644
index 00000000..174fd8d7
--- /dev/null
+++ b/spec/end_to_end/browser_no_auth_spec.cr
@@ -0,0 +1,35 @@
+require "../spec_helper"
+
+include WithProjectCleanup
+include ShouldRunSuccessfully
+
+describe "Lucky CLI", tags: "end_to_end" do
+ describe "building a full browser app without authentication" do
+ it "generates the app and runs the included specs" do
+ with_project_cleanup do
+ should_run_successfully "crystal run src/lucky.cr -- init.custom test-project --no-auth"
+
+ FileUtils.cd "test-project" do
+ should_run_successfully "crystal script/setup.cr"
+ should_run_successfully "crystal build src/test_project.cr"
+ should_run_successfully "lucky gen.action.api Api::Users::Show"
+ should_run_successfully "lucky gen.action.browser Users::Show"
+ should_run_successfully "lucky gen.migration CreateThings"
+ should_run_successfully "lucky gen.model User"
+ should_run_successfully "lucky gen.page Users::IndexPage"
+ should_run_successfully "lucky gen.component Users::Header"
+ should_run_successfully "lucky gen.resource.browser Comment title:String"
+ should_run_successfully "lucky gen.task email.monthly_update"
+ should_run_successfully "lucky gen.secret_key"
+ should_run_successfully "crystal spec"
+
+ {% if !flag?(:windows) %}
+ # Due to formatter on Windows checking different line endings, this will report changes to all crystal files
+ # We only need to test this on 1 OS to ensure things are good
+ should_run_successfully "crystal tool format --check spec src config"
+ {% end %}
+ end
+ end
+ end
+ end
+end
diff --git a/spec/end_to_end/browser_with_auth_spec.cr b/spec/end_to_end/browser_with_auth_spec.cr
new file mode 100644
index 00000000..c3e653d9
--- /dev/null
+++ b/spec/end_to_end/browser_with_auth_spec.cr
@@ -0,0 +1,26 @@
+require "../spec_helper"
+
+include WithProjectCleanup
+include ShouldRunSuccessfully
+
+describe "Lucky CLI", tags: "end_to_end" do
+ describe "building a full browser app with authentication included" do
+ it "generates the app and runs the included specs" do
+ with_project_cleanup do
+ should_run_successfully "crystal run src/lucky.cr -- init.custom test-project"
+
+ FileUtils.cd "test-project" do
+ {% if !flag?(:windows) %}
+ # Due to formatter on Windows checking different line endings, this will report changes to all crystal files
+ # We only need to test this on 1 OS to ensure things are good
+ should_run_successfully "crystal tool format --check spec src config"
+ {% end %}
+ should_run_successfully "crystal script/setup.cr"
+ should_run_successfully "crystal build src/test_project.cr"
+ should_run_successfully "crystal spec"
+ should_run_successfully "lucky tasks"
+ end
+ end
+ end
+ end
+end
diff --git a/spec/end_to_end/browser_with_security_spec.cr b/spec/end_to_end/browser_with_security_spec.cr
new file mode 100644
index 00000000..63c9acb6
--- /dev/null
+++ b/spec/end_to_end/browser_with_security_spec.cr
@@ -0,0 +1,26 @@
+require "../spec_helper"
+
+include WithProjectCleanup
+include ShouldRunSuccessfully
+
+describe "Lucky CLI", tags: "end_to_end" do
+ describe "building a full browser app with authentication and sec tester included" do
+ it "generates the app and runs the included specs" do
+ with_project_cleanup do
+ should_run_successfully "crystal run src/lucky.cr -- init.custom test-project --with-sec-test"
+
+ FileUtils.cd "test-project" do
+ {% if !flag?(:windows) %}
+ # Due to formatter on Windows checking different line endings, this will report changes to all crystal files
+ # We only need to test this on 1 OS to ensure things are good
+ should_run_successfully "crystal tool format --check spec src config"
+ {% end %}
+ should_run_successfully "crystal script/setup.cr"
+ should_run_successfully "crystal build src/test_project.cr"
+ should_run_successfully "crystal spec"
+ should_run_successfully "lucky tasks"
+ end
+ end
+ end
+ end
+end
diff --git a/spec/integration/lucky_cli_spec.cr b/spec/integration/lucky_cli_spec.cr
index f262ae74..375927db 100644
--- a/spec/integration/lucky_cli_spec.cr
+++ b/spec/integration/lucky_cli_spec.cr
@@ -2,47 +2,47 @@ require "../spec_helper"
describe "Lucky CLI", tags: "integration" do
describe "running a task", tags: "task" do
- it "runs precompiled tasks" do
- io = IO::Memory.new
- status = run_lucky(
- args: %w[hello_world],
- shell: true,
- output: io,
- env: {
- "LUCKY_TASKS_FILE" => "#{__DIR__}/../../fixtures/hello_world.cr",
- }
- )
- status.exit_code.should eq(0)
- io.to_s.should eq("Hello World!\n")
- end
+ # it "runs precompiled tasks" do
+ # io = IO::Memory.new
+ # status = run_lucky(
+ # args: %w[hello_world],
+ # shell: true,
+ # output: io,
+ # env: {
+ # "LUCKY_TASKS_FILE" => "#{__DIR__}/../../fixtures/hello_world.cr",
+ # }
+ # )
+ # status.exit_code.should eq(0)
+ # io.to_s.should eq("Hello World!\n")
+ # end
- it "runs non-compiled tasks" do
- io = IO::Memory.new
- status = run_lucky(
- args: %w[hello_crystal],
- shell: true,
- output: io,
- env: {
- "LUCKY_TASKS_FILE" => "#{__DIR__}/../../fixtures/hello_crystal.cr",
- }
- )
- status.exit_code.should eq(0)
- io.to_s.should eq("Hello, Crystal!\n")
- end
+ # it "runs non-compiled tasks" do
+ # io = IO::Memory.new
+ # status = run_lucky(
+ # args: %w[hello_crystal],
+ # shell: true,
+ # output: io,
+ # env: {
+ # "LUCKY_TASKS_FILE" => "#{__DIR__}/../../fixtures/hello_crystal.cr",
+ # }
+ # )
+ # status.exit_code.should eq(0)
+ # io.to_s.should eq("Hello, Crystal!\n")
+ # end
- it "allows tasks to accept input from STDIN" do
- io = IO::Memory.new
- run_lucky(
- args: %w[task_with_input],
- shell: true,
- input: IO::Memory.new("hello world"),
- output: io,
- env: {
- "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
- }
- )
- io.to_s.should eq("input: hello world\n")
- end
+ # it "allows tasks to accept input from STDIN" do
+ # io = IO::Memory.new
+ # run_lucky(
+ # args: %w[task_with_input],
+ # shell: true,
+ # input: IO::Memory.new("hello world"),
+ # output: io,
+ # env: {
+ # "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
+ # }
+ # )
+ # io.to_s.should eq("input: hello world\n")
+ # end
end
describe "getting help", tags: "lucky" do
@@ -54,49 +54,49 @@ describe "Lucky CLI", tags: "integration" do
end
describe "returns the proper help message for built-in CLI commands" do
- it "for 'tasks'" do
- io = IO::Memory.new
- status = run_lucky(
- args: %w[tasks -h],
- shell: true,
- output: io,
- env: {
- "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
- }
- )
- status.exit_code.should eq(0)
- io.to_s.should contain("Usage: lucky tasks")
- end
+ # it "for 'tasks'" do
+ # io = IO::Memory.new
+ # status = run_lucky(
+ # args: %w[tasks -h],
+ # shell: true,
+ # output: io,
+ # env: {
+ # "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
+ # }
+ # )
+ # status.exit_code.should eq(0)
+ # io.to_s.should contain("Usage: lucky tasks")
+ # end
- it "for 'dev'" do
- io = IO::Memory.new
- status = run_lucky(
- args: %w[dev -h],
- shell: true,
- output: io,
- env: {
- "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
- }
- )
- status.exit_code.should eq(0)
- io.to_s.should contain("Usage: lucky dev")
- end
+ # it "for 'dev'" do
+ # io = IO::Memory.new
+ # status = run_lucky(
+ # args: %w[dev -h],
+ # shell: true,
+ # output: io,
+ # env: {
+ # "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
+ # }
+ # )
+ # status.exit_code.should eq(0)
+ # io.to_s.should contain("Usage: lucky dev")
+ # end
end
- # NOTE: This must be `error` because of how the messages are printed out from the custom tasks
- it "returns custom help messages from custom tasks" do
- io = IO::Memory.new
- status = run_lucky(
- args: %w[placeholder_task -h],
- shell: true,
- error: io,
- env: {
- "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
- }
- )
- status.exit_code.should eq(0)
- io.to_s.should contain("Custom help message")
- end
+ # # NOTE: This must be `error` because of how the messages are printed out from the custom tasks
+ # it "returns custom help messages from custom tasks" do
+ # io = IO::Memory.new
+ # status = run_lucky(
+ # args: %w[placeholder_task -h],
+ # shell: true,
+ # error: io,
+ # env: {
+ # "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s,
+ # }
+ # )
+ # status.exit_code.should eq(0)
+ # io.to_s.should contain("Custom help message")
+ # end
end
describe "custom init", tags: "init" do
diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr
index d098d79b..00d7d05a 100644
--- a/spec/spec_helper.cr
+++ b/spec/spec_helper.cr
@@ -8,46 +8,6 @@ require "../src/lucky_cli"
include LuckyTemplate::Spec
-SPEC_UPDATE_SNAPSHOT = ENV["SPEC_UPDATE_SNAPSHOT"]? == "1"
-
-# Generates a snapshot of a generator with *fixture_name* folder
-#
-# NOTE: Can update a snapshot via `earthly +update-snapshot --spec=:`
-def generate_snapshot(fixture_name, file = __FILE__, line = __LINE__, &)
- generator = yield
-
- actual_path = Path[Dir.current]
- expected_path = Path["#{__DIR__}/../fixtures"] / fixture_name / "expected"
-
- if SPEC_UPDATE_SNAPSHOT
- FileUtils.rm_rf(expected_path)
- FileUtils.mkdir_p(expected_path)
- generator.render(expected_path)
- end
-
- FileUtils.mkdir_p(actual_path)
- generator.render(actual_path)
-
- generator.template_folder.should be_valid_at(actual_path), file: file, line: line
-
- snapshot = LuckyTemplate.snapshot(generator.template_folder)
- snapshot.select { |_, type| type.file? }.each do |filename, _|
- actual_filename = actual_path / filename
- expected_filename = expected_path / filename
-
- unless File.same_content?(actual_filename, expected_filename)
- actual_lines = File.read_lines(actual_filename)
- expected_lines = File.read_lines(expected_filename)
-
- actual_lines.each_with_index do |actual_line, index|
- actual_line.should eq(expected_lines[index]), file: file, line: line
- end
- end
- end
-
- generator
-end
-
# Executes a new `lucky` process
#
# NOTE: will mark the spec as pending if lucky command is not found
@@ -57,7 +17,3 @@ def run_lucky(**kwargs)
end
Process.run("lucky", **kwargs)
end
-
-def fixtures_tasks_path
- Path["#{__DIR__}/../fixtures/tasks.cr"]
-end
diff --git a/spec/support/should_run_successfully.cr b/spec/support/should_run_successfully.cr
new file mode 100644
index 00000000..2d46a894
--- /dev/null
+++ b/spec/support/should_run_successfully.cr
@@ -0,0 +1,17 @@
+module ShouldRunSuccessfully
+ private def should_run_successfully(command, output : IO = STDOUT) : Nil
+ result = Process.run(
+ command,
+ shell: true,
+ env: ENV.to_h,
+ output: output,
+ error: STDERR
+ )
+
+ result.exit_code.should be_successful
+ end
+
+ private def be_successful
+ eq 0
+ end
+end
diff --git a/spec/support/with_project_cleanup.cr b/spec/support/with_project_cleanup.cr
new file mode 100644
index 00000000..209fdd34
--- /dev/null
+++ b/spec/support/with_project_cleanup.cr
@@ -0,0 +1,18 @@
+module WithProjectCleanup
+ private def with_project_cleanup(project_directory = "test-project", skip_db_drop = false, &) : Nil
+ yield
+
+ FileUtils.cd(project_directory) {
+ output = IO::Memory.new
+ status = run_lucky(
+ args: %w[db.drop],
+ shell: true,
+ output: output,
+ )
+ status.exit_code.should eq(0)
+ output.to_s.should contain("Done dropping")
+ } unless skip_db_drop
+ ensure
+ FileUtils.rm_rf project_directory
+ end
+end
diff --git a/spec/unit/api_authentication_template_spec.cr b/spec/unit/api_authentication_template_spec.cr
deleted file mode 100644
index 67e0f220..00000000
--- a/spec/unit/api_authentication_template_spec.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-require "../spec_helper"
-
-describe ApiAuthenticationTemplate do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates api authentication template" do
- generate_snapshot("api_authentication_template") do
- ApiAuthenticationTemplate.new
- end
- end
-end
diff --git a/spec/unit/app_with_sec_tester_template_spec.cr b/spec/unit/app_with_sec_tester_template_spec.cr
deleted file mode 100644
index 835c9bb3..00000000
--- a/spec/unit/app_with_sec_tester_template_spec.cr
+++ /dev/null
@@ -1,48 +0,0 @@
-require "../spec_helper"
-
-describe AppWithSecTesterTemplate do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates app with sec tester template" do
- generate_snapshot("app_sec_tester_template") do
- AppWithSecTesterTemplate.new(
- generate_auth: true,
- browser: true
- )
- end
- end
-
- it "generates app with sec tester template with only generate auth option" do
- generate_snapshot("app_sec_tester_template__generate_auth") do
- AppWithSecTesterTemplate.new(
- generate_auth: true,
- browser: false
- )
- end
- end
-
- it "generates app with sec tester template with only browser option" do
- generate_snapshot("app_sec_tester_template__browser") do
- AppWithSecTesterTemplate.new(
- generate_auth: false,
- browser: true
- )
- end
- end
-
- it "generates app with sec tester template without generate auth or browser" do
- generate_snapshot("app_sec_tester_template__no_browser_auth") do
- AppWithSecTesterTemplate.new(
- generate_auth: false,
- browser: false
- )
- end
- end
-end
diff --git a/spec/unit/base_authentication_src_template_spec.cr b/spec/unit/base_authentication_src_template_spec.cr
deleted file mode 100644
index e82b84bb..00000000
--- a/spec/unit/base_authentication_src_template_spec.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-require "../spec_helper"
-
-describe BaseAuthenticationSrcTemplate do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates base authentication src template" do
- generate_snapshot("base_authentication_src_template") do
- BaseAuthenticationSrcTemplate.new
- end
- end
-end
diff --git a/spec/unit/browser_authentication_src_template_spec.cr b/spec/unit/browser_authentication_src_template_spec.cr
deleted file mode 100644
index 2fa3fa62..00000000
--- a/spec/unit/browser_authentication_src_template_spec.cr
+++ /dev/null
@@ -1,18 +0,0 @@
-require "../spec_helper"
-
-describe BrowserAuthenticationSrcTemplate do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates browser authentication src template" do
- generate_snapshot("browser_authentication_src_template") do
- BrowserAuthenticationSrcTemplate.new
- end
- end
-end
diff --git a/spec/unit/browser_src_template_spec.cr b/spec/unit/browser_src_template_spec.cr
deleted file mode 100644
index 0ba2281a..00000000
--- a/spec/unit/browser_src_template_spec.cr
+++ /dev/null
@@ -1,24 +0,0 @@
-require "../spec_helper"
-
-describe BrowserSrcTemplate do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates browser src template" do
- generate_snapshot("browser_src_template") do
- BrowserSrcTemplate.new(generate_auth: true)
- end
- end
-
- it "generates browser src template without generate auth" do
- generate_snapshot("browser_src_template__generate_auth") do
- BrowserSrcTemplate.new(generate_auth: false)
- end
- end
-end
diff --git a/spec/unit/shard_file_generator_spec.cr b/spec/unit/shard_file_generator_spec.cr
deleted file mode 100644
index 1e2644fc..00000000
--- a/spec/unit/shard_file_generator_spec.cr
+++ /dev/null
@@ -1,64 +0,0 @@
-require "../spec_helper"
-
-describe ShardFileGenerator do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates shard file template" do
- generate_snapshot("shard_file_template") do
- ShardFileGenerator.new(
- "test-shard",
- generate_auth: true,
- browser: true,
- with_sec_tester: true
- ).tap do |instance|
- instance.crystal_version = "1.16.1"
- end
- end
- end
-
- it "generates shard file template with only browser option" do
- generate_snapshot("shard_file_template__browser") do
- ShardFileGenerator.new(
- "test-shard",
- generate_auth: false,
- browser: true,
- with_sec_tester: false
- ).tap do |instance|
- instance.crystal_version = "1.16.1"
- end
- end
- end
-
- it "generates shard file template with only generate auth option" do
- generate_snapshot("shard_file_template__generate_auth") do
- ShardFileGenerator.new(
- "test-shard",
- generate_auth: true,
- browser: false,
- with_sec_tester: false
- ).tap do |instance|
- instance.crystal_version = "1.16.1"
- end
- end
- end
-
- it "generates shard file template with only sec tester option" do
- generate_snapshot("shard_file_template__with_sec_tester") do
- ShardFileGenerator.new(
- "test-shard",
- generate_auth: false,
- browser: false,
- with_sec_tester: true
- ).tap do |instance|
- instance.crystal_version = "1.16.1"
- end
- end
- end
-end
diff --git a/spec/unit/src_template_spec.cr b/spec/unit/src_template_spec.cr
deleted file mode 100644
index 0ba63efb..00000000
--- a/spec/unit/src_template_spec.cr
+++ /dev/null
@@ -1,72 +0,0 @@
-require "../spec_helper"
-
-describe SrcTemplate do
- around_each do |example|
- with_tempfile("tmp") do |tmp|
- Dir.mkdir_p(tmp)
- Dir.cd(tmp) do
- example.run
- end
- end
- end
-
- it "generates src template" do
- generate_snapshot("src_template") do
- SrcTemplate.new(
- "test-project",
- generate_auth: true,
- api_only: true,
- with_sec_tester: true
- ).tap do |instance|
- instance.secret_key_base = "1234567890"
- instance.crystal_version = "1.16.1"
- instance.lucky_cli_version = "1.3.0"
- end
- end
- end
-
- it "generates src template with only generate auth option" do
- generate_snapshot("src_template__generate_auth") do
- SrcTemplate.new(
- "test-project",
- generate_auth: true,
- api_only: false,
- with_sec_tester: false
- ).tap do |instance|
- instance.secret_key_base = "1234567890"
- instance.crystal_version = "1.16.1"
- instance.lucky_cli_version = "1.3.0"
- end
- end
- end
-
- it "generates src template with only api option" do
- generate_snapshot("src_template__api_only") do
- SrcTemplate.new(
- "test-project",
- generate_auth: false,
- api_only: true,
- with_sec_tester: false
- ).tap do |instance|
- instance.secret_key_base = "1234567890"
- instance.crystal_version = "1.16.1"
- instance.lucky_cli_version = "1.3.0"
- end
- end
- end
-
- it "generates src template with only sec tester option" do
- generate_snapshot("src_template__sec_tester") do
- SrcTemplate.new(
- "test-project",
- generate_auth: false,
- api_only: false,
- with_sec_tester: true
- ).tap do |instance|
- instance.secret_key_base = "1234567890"
- instance.crystal_version = "1.16.1"
- instance.lucky_cli_version = "1.3.0"
- end
- end
- end
-end
diff --git a/src/lucky_cli/src_template.cr b/src/lucky_cli/src_template.cr
index acf4a1af..7c1f1951 100644
--- a/src/lucky_cli/src_template.cr
+++ b/src/lucky_cli/src_template.cr
@@ -37,6 +37,9 @@ class SrcTemplate
root_dir.add_file(".env") do |io|
ECR.embed("#{__DIR__}/../web_app_skeleton/.env.ecr", io)
end
+ root_dir.add_file(".gitattributes") do |io|
+ ECR.embed("#{__DIR__}/../web_app_skeleton/.gitattributes.ecr", io)
+ end
root_dir.add_file("docker-compose.yml") do |io|
ECR.embed("#{__DIR__}/../web_app_skeleton/docker-compose.yml.ecr", io)
end
diff --git a/src/web_app_skeleton/.gitattributes.ecr b/src/web_app_skeleton/.gitattributes.ecr
new file mode 100644
index 00000000..fdd3f45e
--- /dev/null
+++ b/src/web_app_skeleton/.gitattributes.ecr
@@ -0,0 +1 @@
+*.cr text eol=lf
\ No newline at end of file
diff --git a/src/web_app_skeleton/.github/workflows/ci.yml.ecr b/src/web_app_skeleton/.github/workflows/ci.yml.ecr
index 6c555142..2b931f0e 100644
--- a/src/web_app_skeleton/.github/workflows/ci.yml.ecr
+++ b/src/web_app_skeleton/.github/workflows/ci.yml.ecr
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
continue-on-error: ${{ matrix.experimental }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
@@ -41,7 +41,7 @@ jobs:
continue-on-error: ${{ matrix.experimental }}
services:
postgres:
- image: postgres:14-alpine
+ image: postgres:18-alpine
env:
POSTGRES_PASSWORD: postgres
ports:
@@ -54,7 +54,7 @@ jobs:
--health-retries 5
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Install Crystal
uses: crystal-lang/install-crystal@v1
with:
@@ -66,7 +66,7 @@ jobs:
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Set up Yarn cache
- uses: actions/cache@v4
+ uses: actions/cache@v5
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
@@ -74,7 +74,7 @@ jobs:
${{ runner.os }}-yarn-
- name: Set up Node cache
- uses: actions/cache@v4
+ uses: actions/cache@v5
id: node-cache # use this to check for `cache-hit` (`steps.node-cache.outputs.cache-hit != 'true'`)
with:
path: '**/node_modules'
@@ -83,7 +83,7 @@ jobs:
${{ runner.os }}-node-
<%- end -%>
- name: Set up Crystal cache
- uses: actions/cache@v4
+ uses: actions/cache@v5
id: crystal-cache
with:
path: |