From f088a2c501d83f5a79bb3c7fc20ba00adab5a4d7 Mon Sep 17 00:00:00 2001 From: Long Nguyen Date: Fri, 7 Jan 2022 14:34:29 +0700 Subject: [PATCH 01/13] Poblish the README file content --- .../addons/github/.github/workflows/README.md | 64 +++++++++++++++++++ .../github/.github/workflows/README.md.tt | 57 ----------------- 2 files changed, 64 insertions(+), 57 deletions(-) create mode 100644 .template/addons/github/.github/workflows/README.md delete mode 100644 .template/addons/github/.github/workflows/README.md.tt diff --git a/.template/addons/github/.github/workflows/README.md b/.template/addons/github/.github/workflows/README.md new file mode 100644 index 00000000..1e79424c --- /dev/null +++ b/.template/addons/github/.github/workflows/README.md @@ -0,0 +1,64 @@ +# Github Actions +The following workflows are supported. Depends on what you choose when generating the project, some or all of them would be available: +- [Test](#test-workflow) +- [Test Production Build](#test-production-build-workflow) +- [Deploy to Heroku](#deploy-to-heroku-workflow) + +Please refer to the following sections for usage instruction. + +## Test workflow +Set up the following GitHub repository secrets. +- DOCKER_REGISTRY_HOST (currently support: `docker.io`, `ghcr.io`, `azurecr.io`, `gcr.io`, `registry.gitlab.com`) +- DOCKER_REGISTRY_USERNAME (Default: `${{ github.repository_owner }}`) +- DOCKER_REGISTRY_TOKEN (can be generated on the Docker registries) +- DOCKER_IMAGE (Default: `${{ github.repository }}`) + +## Test production build workflow +Set up the following GitHub repository secrets. +- DOCKER_REGISTRY_HOST (currently support: `docker.io`, `ghcr.io`, `azurecr.io`, `gcr.io`, `registry.gitlab.com`) +- DOCKER_IMAGE (Default: `${{ github.repository }}`) + +## Deploy to Heroku workflow + +### Requirements +- A Heroku API key. It can be generated under your [Account Settings](https://dashboard.heroku.com/account#api-key) +- 2 pre-generated [Heroku apps](https://devcenter.heroku.com/articles/creating-apps): + - {your-project-name} + - {your-project-name}-staging + +### How to use +- Set up the following GitHub repository secrets. + - DOCKER_REGISTRY_HOST (currently support: `docker.io`, `ghcr.io`, `azurecr.io`, `gcr.io`, `registry.gitlab.com`) + - DOCKER_REGISTRY_TOKEN (can be generated on the Docker registries) + - DOCKER_REGISTRY_USERNAME (Default: `${{ github.repository_owner }}`) + - DOCKER_IMAGE (Default: `${{ github.repository }}`) + - HEROKU_API_KEY + +- If needed, update the `.github\workflow\deploy_heroku.yml` file to matches your Heroku apps names: + + ```yml + [...] + - name: Set env HEROKU_APP + run: | + if [[ $BRANCH_TAG = "latest" ]] + then + echo "HEROKU_APP=HERE" >> $GITHUB_ENV + else + echo "HEROKU_APP=HERE-staging" >> $GITHUB_ENV + fi + [...] + +> This step might simply be changing '_' to '-' in the app name + +- Now you still need to attach a database to **each** app. + - From [Heroku Dashboard](https://dashboard.heroku.com/apps), open the app + - Go to the 'Resources' tab + - In the 'Add-ons' section, search for 'Postgres' and select 'Heroku Postgres' + - You can select a free plan to start (Hobby Dev - Free) and 'Submit Order Form' + +> Note that in 'Settings > Config vars', your now have the `DATABASE_URL` variable (which is used by your Web Container) + +Once all setup, give it a try by running manually the GitHub Action 'Deploy Heroku'! + +> **Troubleshooting:** +> You can check at Heroku's logs from your application dashboard, in 'More > View logs' diff --git a/.template/addons/github/.github/workflows/README.md.tt b/.template/addons/github/.github/workflows/README.md.tt deleted file mode 100644 index 834f5c6b..00000000 --- a/.template/addons/github/.github/workflows/README.md.tt +++ /dev/null @@ -1,57 +0,0 @@ -# Github Actions - -## Requirements: - -- Generate new token on docker registry, support `docker.io`, `ghcr.io`, `azurecr.io`, `gcr.io`, `registry.gitlab.com` -- Generate new Heroku API key - -## Setup the CI - -### Secrets - -Depending on the workflow used in the project, set up the following secrets: - -- DOCKER_REGISTRY_HOST -- DOCKER_REGISTRY_TOKEN -- DOCKER_REGISTRY_USERNAME (Default: ${{ github.repository_owner }}) -- DOCKER_IMAGE (Default: ${{ github. repository }}) -- HEROKU_API_KEY (for deployment) -- DANGER_GITHUB_API_TOKEN (Default: ${{ github.token }}) - -### Heroku Deployment - -Use the `deploy_heroku.yml` GitHub Action to deploy your app in Heroku. - -- If needed, create an account on [Heroku.com](https://www.heroku.com/) -- Add your Heroku API Key (`HEROKU_API_KEY`) in GitHub Secrets -- Create 2 new Heroku apps: - - {your-project-name} - - {your-project-name}-staging -- If needed, update the `.github\workflow\deploy_heroku.yml` file to matches your Heroku apps names: - - ```yml - [...] - - name: Set env HEROKU_APP - run: | - if [[ $BRANCH_TAG = "latest" ]] - then - echo "HEROKU_APP=HERE" >> $GITHUB_ENV - else - echo "HEROKU_APP=HERE-staging" >> $GITHUB_ENV - fi - [...] - -> This step might simply be changing '_' to '-' in the app name - -- Now you still need to attach a database to **each** app. - - From [Heroku Dashboard](https://dashboard.heroku.com/apps), open the app - - Go to the 'Resources' tab - - In the 'Add-ons' section, search for 'Postgres' and select 'Heroku Postgres' - - You can select a free plan to start (Hobby Dev - Free) and 'Submit Order Form' - -> Note that in 'Settings > Config vars', your now have the `DATABASE_URL` variable (which is used by your Web Container) - -Once all setup, give it a try by running manually the GitHub Action 'Deploy Heroku'! - -> **Troubleshooting:** -> You can check at Heroku's logs from your application dashboard, in 'More > View logs' From e6e04c5f619ba9c806ad87722bc90c4d0af0a8ca Mon Sep 17 00:00:00 2001 From: Long Nguyen Date: Fri, 7 Jan 2022 14:34:53 +0700 Subject: [PATCH 02/13] Update the release PR template --- .../PULL_REQUEST_TEMPLATE/RELEASE_TEMPLATE.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.template/addons/github/.github/PULL_REQUEST_TEMPLATE/RELEASE_TEMPLATE.md b/.template/addons/github/.github/PULL_REQUEST_TEMPLATE/RELEASE_TEMPLATE.md index 819fd591..1d9216e0 100644 --- a/.template/addons/github/.github/PULL_REQUEST_TEMPLATE/RELEASE_TEMPLATE.md +++ b/.template/addons/github/.github/PULL_REQUEST_TEMPLATE/RELEASE_TEMPLATE.md @@ -1,14 +1,9 @@ -Link to the milestone on Github e.g. https://github.com/nimblehq/git-templates/milestone/41?closed=1 -or -Link to the project management tool for the release +Link to the milestone on Github e.g. https://github.com/nimblehq/git-templates/milestone/41?closed=1 +or link to the release on the project management tool e.g. https://app.shortcut.com/nimblehq/label/12345 ## Features - -Provide the ID and title of the issue in the section for each type (feature, chore and bug). The link is optional. - -- [ch1234] As a user, I can log in - or -- [[ch1234](https://github.com/nimblehq/git-templates/issues/1234)] As a user, I can log in +Provide the Pull Request IDs in the section for each type (feature, chore, and bug), e.g. +- #1234 ## Chores - Same structure as in ## Feature From db87a0f5f6c067455f64d4aa1eced4104f19a55b Mon Sep 17 00:00:00 2001 From: Long Nguyen Date: Fri, 7 Jan 2022 14:40:44 +0700 Subject: [PATCH 03/13] Add a new workflow to publish wiki content --- .../workflows/{README.md => README.md.tt} | 8 ++++++++ .../.github/workflows/publish_wiki.yml.tt | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) rename .template/addons/github/.github/workflows/{README.md => README.md.tt} (80%) create mode 100644 .template/addons/github/.github/workflows/publish_wiki.yml.tt diff --git a/.template/addons/github/.github/workflows/README.md b/.template/addons/github/.github/workflows/README.md.tt similarity index 80% rename from .template/addons/github/.github/workflows/README.md rename to .template/addons/github/.github/workflows/README.md.tt index 1e79424c..0df8d844 100644 --- a/.template/addons/github/.github/workflows/README.md +++ b/.template/addons/github/.github/workflows/README.md.tt @@ -3,6 +3,7 @@ The following workflows are supported. Depends on what you choose when generatin - [Test](#test-workflow) - [Test Production Build](#test-production-build-workflow) - [Deploy to Heroku](#deploy-to-heroku-workflow) +- [Publish to Wiki](#publish-to-wiki-workflow) Please refer to the following sections for usage instruction. @@ -62,3 +63,10 @@ Once all setup, give it a try by running manually the GitHub Action 'Deploy Hero > **Troubleshooting:** > You can check at Heroku's logs from your application dashboard, in 'More > View logs' + +## Publish to Wiki workflow +- Setup the Github Wiki by following this [official guide](https://docs.github.com/en/communities/documenting-your-project-with-wikis/adding-or-editing-wiki-pages#adding-wiki-pages) +- Create [Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) with `repo` scope enabled - a bot account is recommended to generate that token +- Set up the following GitHub repository secrets + - GH_EMAIL (an email to identify the bot that publish the wiki content in the git history) + - GH_TOKEN (the above generated token) diff --git a/.template/addons/github/.github/workflows/publish_wiki.yml.tt b/.template/addons/github/.github/workflows/publish_wiki.yml.tt new file mode 100644 index 00000000..15764365 --- /dev/null +++ b/.template/addons/github/.github/workflows/publish_wiki.yml.tt @@ -0,0 +1,18 @@ +name: Publish Wiki + +on: + push: + paths: + - .github/wiki/** + branches: + - develop + +jobs: + publish: + name: Publish Wiki + uses: nimblehq/github-actions-workflows/.github/workflows/publish_wiki.yml@0.1.0 + with: + USER_NAME: github-wiki-workflow + USER_EMAIL: ${{ secrets.GH_EMAIL }} + secrets: + USER_TOKEN: ${{ secrets.GH_TOKEN }} From 73c311bee2de26145c99084fa083785e6cbed915 Mon Sep 17 00:00:00 2001 From: Long Nguyen Date: Fri, 7 Jan 2022 14:43:03 +0700 Subject: [PATCH 04/13] Update the instruction to use the Publish to Wiki workflow --- .template/addons/github/.github/workflows/README.md.tt | 1 + 1 file changed, 1 insertion(+) diff --git a/.template/addons/github/.github/workflows/README.md.tt b/.template/addons/github/.github/workflows/README.md.tt index 0df8d844..5a7b4974 100644 --- a/.template/addons/github/.github/workflows/README.md.tt +++ b/.template/addons/github/.github/workflows/README.md.tt @@ -70,3 +70,4 @@ Once all setup, give it a try by running manually the GitHub Action 'Deploy Hero - Set up the following GitHub repository secrets - GH_EMAIL (an email to identify the bot that publish the wiki content in the git history) - GH_TOKEN (the above generated token) +- Creat a `.github/wiki` directory to store the documents to be published to Wiki. From 9f625bb2b25190113f07744342821afc0558b544 Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Wed, 19 Jan 2022 16:29:07 +0700 Subject: [PATCH 05/13] Upgrade to Rails 7 (#307) * Update Gemfile * Fix backtrace silencer initializer * Fix package.json config and remove deprecated turbolinks modification * Install webpacker * Update workflows and readme to Rails 7 * Fix Bootstrap addon * Fix stylesheet error * Fix webpack * Upgrade Webpacker * Update rails to 7.0.1 * Disable hotwire turbo and stimulus, generate translation file by default * Update rails version in tests and readme * Update Nginx config and update web gemfile test * Update tests for new configurations * Enable capybara as it required by default * Update nginx config * Refactor package.json * Adjust Procfile for each variant * Fix format --- .github/workflows/test_production_build.yml | 2 +- .github/workflows/test_variants.yml | 2 +- .template/addons/bootstrap/package.json.rb | 8 ++--- .../nginx/config/environments/production.rb | 10 ++---- .template/addons/nginx/config/template.rb | 2 +- .template/addons/slim/Gemfile.rb | 2 +- .../spec/addons/base/nginx/template_spec.rb | 12 ++++--- .../variants/api/nginx/template_spec.rb | 4 --- .../variants/web/nginx/template_spec.rb | 4 --- .../initializers/backtrace_silencers_spec.rb | 12 ------- .template/spec/base/config/template_spec.rb | 4 +++ .template/spec/base/template_spec.rb | 1 - .../spec/variants/web/app/template_spec.rb | 14 ++++++++ .../web/config/initializers/assets_spec.rb | 7 ++++ .template/spec/variants/web/gemfile_spec.rb | 20 ++++++----- .../spec/variants/web/proc_file_dev_spec.rb | 7 ++++ .template/variants/web/Gemfile.rb | 25 +++++++++----- .template/variants/web/Procfile.dev.rb | 5 +++ .../web/app/javascript/packs/application.js | 1 + .template/variants/web/app/template.rb | 10 ++++-- .../web/config/initializers/assets.rb | 7 ++++ .template/variants/web/config/template.rb | 1 + .template/variants/web/package.json.rb | 32 +++++++++--------- .template/variants/web/template.rb | 33 ++++--------------- Gemfile.tt | 31 ++++++++++------- Makefile | 14 ++++---- Procfile.dev | 1 - README.md | 2 +- config/initializers/backtrace_silencers.rb | 12 ++++--- config/template.rb | 2 ++ template.rb | 2 -- 31 files changed, 158 insertions(+), 131 deletions(-) delete mode 100644 .template/spec/base/config/initializers/backtrace_silencers_spec.rb create mode 100644 .template/spec/variants/web/config/initializers/assets_spec.rb create mode 100644 .template/spec/variants/web/proc_file_dev_spec.rb create mode 100644 .template/variants/web/Procfile.dev.rb create mode 100644 .template/variants/web/app/javascript/packs/application.js create mode 100644 .template/variants/web/config/initializers/assets.rb diff --git a/.github/workflows/test_production_build.yml b/.github/workflows/test_production_build.yml index efcc64f7..d5e6a4a4 100644 --- a/.github/workflows/test_production_build.yml +++ b/.github/workflows/test_production_build.yml @@ -8,7 +8,7 @@ env: DOCKER_REGISTRY_HOST: ${{ secrets.DOCKER_REGISTRY_HOST }} RUBY_VERSION: 2.7.2 NODE_VERSION: 14 - RAILS_VERSION: 6.1.1 + RAILS_VERSION: 7.0.1 jobs: build_production: diff --git a/.github/workflows/test_variants.yml b/.github/workflows/test_variants.yml index 61a31860..979636d1 100644 --- a/.github/workflows/test_variants.yml +++ b/.github/workflows/test_variants.yml @@ -11,7 +11,7 @@ env: DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_REGISTRY_TOKEN }} RUBY_VERSION: 2.7.2 NODE_VERSION: 14 - RAILS_VERSION: 6.1.1 + RAILS_VERSION: 7.0.1 jobs: test: diff --git a/.template/addons/bootstrap/package.json.rb b/.template/addons/bootstrap/package.json.rb index c2520c7b..1d373ca0 100644 --- a/.template/addons/bootstrap/package.json.rb +++ b/.template/addons/bootstrap/package.json.rb @@ -1,8 +1,4 @@ # frozen_string_literal: true -insert_into_file 'package.json', after: /"i18n-js":.+\n/ do - <<~JSON - "bootstrap": "4.5.2", - "bootstrap.native": "3.0.13", - JSON -end +run 'yarn add bootstrap@^4.5.2' +run 'yarn add bootstrap.native@^3.0.13' diff --git a/.template/addons/nginx/config/environments/production.rb b/.template/addons/nginx/config/environments/production.rb index 237e5763..dda1c379 100644 --- a/.template/addons/nginx/config/environments/production.rb +++ b/.template/addons/nginx/config/environments/production.rb @@ -1,11 +1,5 @@ gsub_file( 'config/environments/production.rb', - "config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?", - 'config.public_file_server.enabled = false', -) - -gsub_file( - 'config/environments/production.rb', - 'config.public_file_server.enabled = true', - 'config.public_file_server.enabled = false', + /config.public_file_server.enabled.*/, + 'config.public_file_server.enabled = false' ) diff --git a/.template/addons/nginx/config/template.rb b/.template/addons/nginx/config/template.rb index 1f73efec..abf6ad99 100644 --- a/.template/addons/nginx/config/template.rb +++ b/.template/addons/nginx/config/template.rb @@ -1,5 +1,5 @@ use_source_path __dir__ -apply 'config/environments/production.rb' if WEB_VARIANT +apply 'config/environments/production.rb' template 'config/nginx/app.conf.template.tt' diff --git a/.template/addons/slim/Gemfile.rb b/.template/addons/slim/Gemfile.rb index 432980b2..82b54af1 100644 --- a/.template/addons/slim/Gemfile.rb +++ b/.template/addons/slim/Gemfile.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -insert_into_file 'Gemfile', after: /gem 'sass-rails'.*\n/ do +insert_into_file 'Gemfile', after: /gem 'pundit'.*\n/ do <<~GEM # Templating diff --git a/.template/spec/addons/base/nginx/template_spec.rb b/.template/spec/addons/base/nginx/template_spec.rb index 9748c3b1..1bae78cf 100644 --- a/.template/spec/addons/base/nginx/template_spec.rb +++ b/.template/spec/addons/base/nginx/template_spec.rb @@ -3,22 +3,26 @@ expect(file('bin/inject_port_into_nginx.sh')).to exist expect(file('bin/inject_port_into_nginx.sh')).to be_executable end - + it 'sets the $PORT as Nginx HTTP listener' do expect(file('bin/start.sh')).to contain('./bin/inject_port_into_nginx.sh') end - + it 'starts nginx in start.sh' do expect(file('bin/start.sh')).to contain('nginx -c /etc/nginx/conf.d/default.conf') end - + it 'starts the Puma under PORT 3000' do expect(file('bin/start.sh')).to contain('bundle exec rails s -p 3000 -b 0.0.0.0') end - + it 'adjusts Dockerfile to work with Nginx' do expect(file('Dockerfile')).to contain('nginx').after('unzip') expect(file('Dockerfile')).to contain('PORT=3000') expect(file('Dockerfile')).to contain('COPY config/nginx/app.conf.template /etc/nginx/conf.d/default.conf') end + + it 'disables Rails serve static file' do + expect(file('config/environments/production.rb')).to contain('config.public_file_server.enabled = false') + end end diff --git a/.template/spec/addons/variants/api/nginx/template_spec.rb b/.template/spec/addons/variants/api/nginx/template_spec.rb index bcdbb3f7..467792bf 100644 --- a/.template/spec/addons/variants/api/nginx/template_spec.rb +++ b/.template/spec/addons/variants/api/nginx/template_spec.rb @@ -1,8 +1,4 @@ describe 'Nginx addon - template' do - it 'allows Rails serve static file' do - expect(file('config/environments/production.rb')).to contain('config.public_file_server.enabled = true') - end - it 'creates config/nginx/app.conf.template file' do expect(file('config/nginx/app.conf.template')).not_to contain('gzip on;') end diff --git a/.template/spec/addons/variants/web/nginx/template_spec.rb b/.template/spec/addons/variants/web/nginx/template_spec.rb index ec73ad86..2ad3b332 100644 --- a/.template/spec/addons/variants/web/nginx/template_spec.rb +++ b/.template/spec/addons/variants/web/nginx/template_spec.rb @@ -1,8 +1,4 @@ describe 'Nginx addon - template' do - it 'disables Rails serve static file' do - expect(file('config/environments/production.rb')).to contain('config.public_file_server.enabled = false') - end - it 'creates config/nginx/app.conf.template file' do expect(file('config/nginx/app.conf.template')).to contain('gzip on;') end diff --git a/.template/spec/base/config/initializers/backtrace_silencers_spec.rb b/.template/spec/base/config/initializers/backtrace_silencers_spec.rb deleted file mode 100644 index 3552f9b3..00000000 --- a/.template/spec/base/config/initializers/backtrace_silencers_spec.rb +++ /dev/null @@ -1,12 +0,0 @@ -describe 'config/initializers/backtrace_silencers.rb' do - subject { file('config/initializers/backtrace_silencers.rb') } - - it 'enables Rails.backtrace_cleaner.remove_silencers!' do - expect(subject).to contain('Rails.backtrace_cleaner.remove_silencers!') - expect(subject).not_to contain('# Rails.backtrace_cleaner.remove_silencers!') - end - - it 'adds engines to Rails.backtrace_cleaner.add_silencer' do - expect(subject).to contain('/^engines/.match?(line)') - end -end diff --git a/.template/spec/base/config/template_spec.rb b/.template/spec/base/config/template_spec.rb index f33c74b4..2a039d5e 100644 --- a/.template/spec/base/config/template_spec.rb +++ b/.template/spec/base/config/template_spec.rb @@ -14,4 +14,8 @@ it 'creates the Rails Best Practices configuration' do expect(file('config/rails_best_practices.yml')).to exist end + + it 'creates the backtrace silencer initializer' do + expect(file('config/initializers/backtrace_silencers.rb')).to exist + end end diff --git a/.template/spec/base/template_spec.rb b/.template/spec/base/template_spec.rb index 44a2f529..9e04595e 100644 --- a/.template/spec/base/template_spec.rb +++ b/.template/spec/base/template_spec.rb @@ -24,5 +24,4 @@ it 'creates Reek configuration files' do expect(file('.reek.yml')).to exist end - end diff --git a/.template/spec/variants/web/app/template_spec.rb b/.template/spec/variants/web/app/template_spec.rb index b203ab1d..bd06893d 100644 --- a/.template/spec/variants/web/app/template_spec.rb +++ b/.template/spec/variants/web/app/template_spec.rb @@ -10,6 +10,10 @@ expect(file('app/javascript/screens')).to be_directory end + it 'creates javascript entry file' do + expect(file('app/javascript/packs/application.js')).to exist + end + context 'Initializers' do it 'creates main initializer file' do expect(file('app/javascript/initializers/index.js')).to exist @@ -43,6 +47,12 @@ expect(file('app/javascript/packs/hello_typescript.ts')).to exist end end + + context 'translations/translations.js' do + it 'creates the translation.js file' do + expect(file('app/javascript/translations/translations.js')).to exist + end + end end context 'Stylesheets' do @@ -86,5 +96,9 @@ it 'modifies the html tag to attach the current locale' do expect(file('app/views/layouts/application.html.erb')).to contain("") end + + it 'loads the javascript entry file' do + expect(file('app/views/layouts/application.html.erb')).to contain("<%= javascript_pack_tag 'application' %>") + end end end diff --git a/.template/spec/variants/web/config/initializers/assets_spec.rb b/.template/spec/variants/web/config/initializers/assets_spec.rb new file mode 100644 index 00000000..0aa86b96 --- /dev/null +++ b/.template/spec/variants/web/config/initializers/assets_spec.rb @@ -0,0 +1,7 @@ +describe 'Web variant - config/initializers/assets.rb' do + subject { file('config/initializers/assets.rb') } + + it 'configures the assets to add node_modules to the pipeline' do + expect(subject).to contain("Rails.application.config.assets.paths << Rails.root.join('node_modules')") + end +end diff --git a/.template/spec/variants/web/gemfile_spec.rb b/.template/spec/variants/web/gemfile_spec.rb index 7a7c74f2..d9e47291 100644 --- a/.template/spec/variants/web/gemfile_spec.rb +++ b/.template/spec/variants/web/gemfile_spec.rb @@ -9,15 +9,11 @@ expect(subject).to contain('webpacker') end - it 'adds sass-rails gem' do - expect(subject).to contain('sass-rails') + it 'adds sassc-rails gem' do + expect(subject).to contain('sassc-rails') end describe 'Development + Test Environment' do - it 'adds sassc-rails gem' do - expect(subject).to contain('sassc-rails').after('^group :development, :test') - end - it 'adds danger-eslint gem' do expect(subject).to contain('danger-eslint').after('^group :development, :test') end @@ -28,8 +24,16 @@ end describe 'Test Environment' do - it 'adds rspec-retry gem' do - expect(subject).to contain('rspec-retry').after('^group :test') + it 'adds capybara gem' do + expect(subject).to contain('capybara').after('^group :test') + end + + it 'adds selenium-webdriver gem' do + expect(subject).to contain('selenium-webdriver').after('^group :test') + end + + it 'adds webdrivers gem' do + expect(subject).to contain('webdrivers').after('^group :test') end end end diff --git a/.template/spec/variants/web/proc_file_dev_spec.rb b/.template/spec/variants/web/proc_file_dev_spec.rb new file mode 100644 index 00000000..f116b855 --- /dev/null +++ b/.template/spec/variants/web/proc_file_dev_spec.rb @@ -0,0 +1,7 @@ +describe 'Web variant - Procfile.dev' do + subject { file('Procfile.dev') } + + it 'adds a webpack process' do + expect(subject).to contain('webpack') + end +end diff --git a/.template/variants/web/Gemfile.rb b/.template/variants/web/Gemfile.rb index 76e98b8e..6aef075b 100644 --- a/.template/variants/web/Gemfile.rb +++ b/.template/variants/web/Gemfile.rb @@ -1,4 +1,4 @@ -insert_into_file 'Gemfile', after: %r{gem 'bootsnap'.*\n} do +insert_into_file 'Gemfile', after: %r{gem 'rails-i18n'.*\n} do <<~EOT gem 'i18n-js', '3.5.1' # A library to provide the I18n translations on the Javascript EOT @@ -8,8 +8,14 @@ <<~EOT # Assets - gem 'webpacker', '~>5.2.0' # Transpile app-like JavaScript - gem 'sass-rails' # SASS + gem 'webpacker', '5.4.3' # Transpile app-like JavaScript + gem 'sassc-rails' # Use Sass to process CSS + # gem 'turbo-rails' # Hotwire's SPA-like page accelerator + # gem 'stimulus-rails' # Hotwire's modest JavaScript framework + # gem 'sprockets-rails' # The original asset pipeline for Rails + # gem 'jsbundling-rails' # Bundle and transpile JavaScript + # gem 'cssbundling-rails' # Bundle and process CSS + # gem 'image_processing' # Use Active Storage variants EOT end @@ -17,16 +23,16 @@ # Group: :development, :test ############################ -insert_into_file 'Gemfile', after: %r{gem 'letter_opener'.*\n} do +insert_into_file 'Gemfile', after: %r{gem 'danger'.*\n} do <<-EOT - gem 'sassc-rails' # Gem to generate scss source maps. + gem 'danger-eslint' # ESLint + gem 'scss_lint' # SCSS lint EOT end -insert_into_file 'Gemfile', after: %r{gem 'danger'.*\n} do +insert_into_file 'Gemfile', after: %r{gem 'spring-watcher-listen'.*\n} do <<-EOT - gem 'danger-eslint' # ESLint - gem 'scss_lint' # SCSS lint + # gem 'web-console' # Use console on exceptions pages EOT end @@ -36,7 +42,8 @@ insert_into_file 'Gemfile', after: %r{gem 'rspec-retry'.*\n} do <<-EOT - gem 'capybara', '>= 2.15' # Integration testing + gem 'capybara' # Integration testing + gem 'selenium-webdriver' # Ruby bindings for Selenium/WebDriver gem 'webdrivers' # Run Selenium tests more easily with automatic installation and updates for all supported webdrivers EOT end diff --git a/.template/variants/web/Procfile.dev.rb b/.template/variants/web/Procfile.dev.rb new file mode 100644 index 00000000..cd43952d --- /dev/null +++ b/.template/variants/web/Procfile.dev.rb @@ -0,0 +1,5 @@ +append_to_file 'Procfile.dev' do + <<~EOT + webpack: yarn && bin/webpack-dev-server + EOT +end diff --git a/.template/variants/web/app/javascript/packs/application.js b/.template/variants/web/app/javascript/packs/application.js new file mode 100644 index 00000000..e3721d19 --- /dev/null +++ b/.template/variants/web/app/javascript/packs/application.js @@ -0,0 +1 @@ +// JavaScript entry file diff --git a/.template/variants/web/app/template.rb b/.template/variants/web/app/template.rb index b6b6661f..7f3eae72 100644 --- a/.template/variants/web/app/template.rb +++ b/.template/variants/web/app/template.rb @@ -2,9 +2,8 @@ directory 'app/javascript' if File.exist?('app/javascript/packs/application.js') - insert_into_file 'app/javascript/packs/application.js', after: %r{import "channels"\n} do + append_to_file 'app/javascript/packs/application.js' do <<~EOT - import 'core-js/stable'; import 'regenerator-runtime/runtime'; @@ -44,9 +43,16 @@ gsub_file 'app/views/layouts/application.html.erb', // do "" end + + insert_into_file 'app/views/layouts/application.html.erb', before: %r{} do + <<~EOT.indent(2) + <%= javascript_pack_tag 'application' %> + EOT + end else @template_errors.add <<~EOT Cannot insert the lang attribute into html tag into `app/views/layouts/application.html.erb` Content: + <%= javascript_pack_tag 'application' %> EOT end diff --git a/.template/variants/web/config/initializers/assets.rb b/.template/variants/web/config/initializers/assets.rb new file mode 100644 index 00000000..4f8bee4c --- /dev/null +++ b/.template/variants/web/config/initializers/assets.rb @@ -0,0 +1,7 @@ +append_to_file 'config/initializers/assets.rb' do + <<~EOT + + # Add Yarn node_modules folder to the asset load path. + Rails.application.config.assets.paths << Rails.root.join('node_modules') + EOT +end diff --git a/.template/variants/web/config/template.rb b/.template/variants/web/config/template.rb index af686cbd..90c8921d 100644 --- a/.template/variants/web/config/template.rb +++ b/.template/variants/web/config/template.rb @@ -3,3 +3,4 @@ copy_file 'config/i18n-js.yml' apply 'config/environments/test.rb' +apply 'config/initializers/assets.rb' diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index 7ad538a1..1dd5db04 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -1,22 +1,24 @@ +# Create package.json file +unless File.exist?('package.json') + create_file 'package.json', + <<~EOT + { + "name": "#{APP_NAME}", + "private": "true" + } + EOT +end + +# Install dependencies +run 'yarn add i18n-js@^3.8.0' +run 'yarn add --dev @nimblehq/eslint-config-nimble@^2.2.1' + +# Setup scripts insert_into_file 'package.json', after: %r{"private":.+\n} do - <<~EOT + <<~EOT.indent(2) "scripts": { "lint": "eslint . --color", "lint:fix": "eslint . --color --fix" }, EOT end - -insert_into_file 'package.json', after: %r{"@rails/ujs":.+\n} do - <<~EOT - "i18n-js": "3.8.0", - EOT -end - -insert_into_file 'package.json', before: %r{"version":.+\n} do - <<~EOT - "devDependencies": { - "@nimblehq/eslint-config-nimble": "2.1.1" - }, - EOT -end diff --git a/.template/variants/web/template.rb b/.template/variants/web/template.rb index 6b7bdfcb..729fe615 100644 --- a/.template/variants/web/template.rb +++ b/.template/variants/web/template.rb @@ -13,19 +13,22 @@ def apply_web_variant! apply 'config/template.rb' apply 'package.json.rb' apply 'Dangerfile.rb' + apply 'Procfile.dev.rb' # Add-ons - [Optional] apply '.template/addons/bootstrap/template.rb' if yes? install_addon_prompt 'Bootstrap' apply '.template/addons/slim/template.rb' if yes? install_addon_prompt 'Slim Template Engine' - remove_turbolinks - after_bundle do use_source_path __dir__ - # Use TypeScript by default + # Install Webpacker and Typescript + rails_command('webpacker:install') rails_command('webpacker:install:typescript') + # Generate translation file + run 'bin/rake i18n:js:export' + # Fix the default Rails template that does not put trailing commas run 'yarn run lint --fix' @@ -34,28 +37,4 @@ def apply_web_variant! end end -def remove_turbolinks - if File.exist?('app/views/layouts/application.html.erb') - gsub_file('app/views/layouts/application.html.erb', %r{, 'data-turbolinks-track': 'reload'}, '') - else - @template_errors.add <<~EOT - Cannot Remove turbolinks from `application.html.erb` file - Content: 'data-turbolinks-track': 'reload' - EOT - end - - if File.exist?('app/javascript/packs/application.js') - gsub_file('app/javascript/packs/application.js', %r{import Turbolinks from "turbolinks"\n}, '') - gsub_file('app/javascript/packs/application.js', %r{Turbolinks.start\(\)\n}, '') - else - @template_errors.add <<~EOT - Cannot Remove turbolinks from `app/javascript/packs/application.js` - Content: import Turbolinks from 'turbolinks'; - Content: Turbolinks.start(); - EOT - end - - gsub_file('package.json', %r{"turbolinks": .+\n}, '') -end - apply_web_variant! diff --git a/Gemfile.tt b/Gemfile.tt index e7c3a52c..72222663 100644 --- a/Gemfile.tt +++ b/Gemfile.tt @@ -2,16 +2,19 @@ source 'https://rubygems.org' ruby '<%= RUBY_VERSION %>' # Backend -gem 'rails', '6.1.3.1' # Latest stable +gem 'rails', '7.0.1' # Latest stable gem 'pg' # Use Postgresql as database gem 'puma' # Use Puma as the app server gem 'mini_magick' # A ruby wrapper for ImageMagick or GraphicsMagick command line gem 'pagy' # A pagination gem that is very light and fast gem 'discard' # Soft deletes for ActiveRecord -gem 'ffaker' # A library for generating fake data such as names, addresses, and phone numbers. -gem 'fabrication' # Fabrication generates objects in Ruby. Fabricators are schematics for your objects, and can be created as needed anywhere in your app or specs. gem 'sidekiq' # background processing for Ruby gem 'bootsnap', require: false # Reduces boot times through caching; required in config/boot.rb +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] # Windows does not include zoneinfo files, so bundle the tzinfo-data gem +# gem 'jbuilder' # Build JSON APIs with ease +# gem 'redis' # Use Redis adapter to run Action Cable in production +# gem 'kredis' # Use Kredis to get higher-level data types in Redis +# gem 'bcrypt' # Use Active Model has_secure_password # Authentications & Authorizations gem 'pundit' # Minimal authorization through OO design and pure Ruby classes @@ -31,19 +34,28 @@ group :development do end group :development, :test do - gem 'bullet' # help to kill N+1 queries and unused eager loading - gem 'figaro' # Simple Rails app configuration + # Debugging gem 'pry-rails' # Call 'binding.pry' anywhere in the code to stop execution and get a debugger console gem 'pry-byebug' # Step by step debugging and stack navigation in Pry + # gem 'debug', platforms: %i[ mri mingw x64_mingw ] # Official debug + + # Utilities + gem 'figaro' # Simple Rails app configuration gem 'listen', '3.1.5' # Listens to file modifications - gem 'letter_opener' # Preview mail in the browser instead of sending. - gem 'brakeman', require: false # A static analysis security vulnerability scanner for Ruby on Rails applications + gem 'letter_opener' # Preview mail in the browser instead of sending + gem 'ffaker' # A library for generating fake data such as names, addresses, and phone numbers + gem 'fabrication' # Fabrication generates objects in Ruby. Fabricators are schematics for your objects, and can be created as needed anywhere in your app or specs + + # Testing gem 'rspec-rails', '~> 4.0.1' # Rails testing engine + + # Code Analysis + gem 'bullet' # help to kill N+1 queries and unused eager loading + gem 'brakeman', require: false # A static analysis security vulnerability scanner for Ruby on Rails applications gem 'rubocop', require: false # A Ruby static code analyzer and formatter, based on the community Ruby style guide. gem 'rubocop-rails', require: false # A RuboCop extension focused on enforcing Rails best practices and coding conventions. gem 'rubocop-rspec', require: false # Code style checking for RSpec files gem 'rubocop-performance', require: false # An extension of RuboCop focused on code performance checks. - gem 'undercover' # Report missing test coverage in new changes gem 'danger' # Automated code review. gem 'danger-rubocop' # A Danger plugin for Rubocop. @@ -72,6 +84,3 @@ end group :production do gem 'rack-timeout' # Rack middleware which aborts requests that have been running for longer than a specified timeout. end - -# Windows does not include zoneinfo files, so bundle the tzinfo-data gem -gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] diff --git a/Makefile b/Makefile index 53bad892..cdbe841d 100644 --- a/Makefile +++ b/Makefile @@ -17,16 +17,16 @@ create_api: build: cd $(APP_NAME) && \ bin/docker-prepare && \ - docker-compose -f docker-compose.test.yml build + docker compose -f docker-compose.test.yml build build_production: cd $(APP_NAME) && \ bin/docker-prepare && \ - docker-compose build + docker compose build test_variant_app: cd $(APP_NAME) && \ - docker-compose -f docker-compose.test.yml run test + docker compose -f docker-compose.test.yml run test base_addon_spec = spec/addons/base/**/*_spec.rb web_addon_spec = spec/addons/variants/web/**/*_spec.rb @@ -38,9 +38,9 @@ api_spec = spec/variants/api/**/*_spec.rb test_template: cd $(APP_NAME) && \ - docker-compose -f docker-compose.test.yml up --detach db redis && \ - docker-compose -f docker-compose.test.yml run test bash -c "./bin/inject_port_into_nginx.sh && nginx -c /etc/nginx/conf.d/default.conf -t" && \ - docker-compose -f docker-compose.test.yml run --detach test bin/start.sh && \ + docker compose -f docker-compose.test.yml up --detach db redis && \ + docker compose -f docker-compose.test.yml run test bash -c "./bin/inject_port_into_nginx.sh && nginx -c /etc/nginx/conf.d/default.conf -t" && \ + docker compose -f docker-compose.test.yml run --detach test bin/start.sh && \ cd ../.template && \ bundle install; \ if [ $(VARIANT) = web ]; then \ @@ -52,4 +52,4 @@ test_template: cleanup: rm -rf $(APP_NAME) -.PHONY: create build run cleanup +.PHONY: create build run cleanup test_template diff --git a/Procfile.dev b/Procfile.dev index c449a81c..a16966c4 100644 --- a/Procfile.dev +++ b/Procfile.dev @@ -1,3 +1,2 @@ web: rails s -p 3000 -b '0.0.0.0' worker: bundle exec sidekiq -C config/sidekiq.yml -webpack: yarn && bin/webpack-dev-server diff --git a/README.md b/README.md index 06ba0915..14304fa5 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ with building complex applications over the years. ### Requirements - Install ruby and set your local ruby version to `2.7.2` -- Install rails > `6.0.0`, recommended version `6.1.3.1` +- Install rails `7.0.1` ### Use the template diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index 47a083f4..de18a28d 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -1,6 +1,10 @@ -gsub_file 'config/initializers/backtrace_silencers.rb', - "Rails.backtrace_cleaner.remove_silencers! if ENV[\"BACKTRACE\"]", - <<-EOT +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code +# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". Rails.backtrace_cleaner.remove_silencers! # Add backtrace silencer @@ -10,5 +14,3 @@ Rails.backtrace_cleaner.add_silencer do |line| !(Rails::BacktraceCleaner::APP_DIRS_PATTERN.match?(line) || /^engines/.match?(line)) end - - EOT diff --git a/config/template.rb b/config/template.rb index f0908e69..ed8b687b 100644 --- a/config/template.rb +++ b/config/template.rb @@ -8,3 +8,5 @@ apply 'config/environments/development.rb' apply 'config/environments/production.rb' apply 'config/environments/test.rb' + +copy_file 'config/initializers/backtrace_silencers.rb' diff --git a/template.rb b/template.rb index a604749e..ea6b0d37 100644 --- a/template.rb +++ b/template.rb @@ -31,8 +31,6 @@ def apply_template!(template_root) template 'Gemfile.tt', force: true - apply 'config/initializers/backtrace_silencers.rb' - copy_file '.flayignore' copy_file 'Dangerfile' copy_file '.rubocop.yml' From 0b0291c10c2a3ac7b20897fa0d8484edcb0404cf Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Mon, 24 Jan 2022 14:40:42 +0700 Subject: [PATCH 06/13] Upgrade to Ruby 3.0.1 (#312) * Set newer version of danger-undercover * Upgrade Ruby to version 3.0.1 * Update undercover config * Upgrade rspec gem * Upgrage setup-ruby version in the workflows * Update docker-api gem * Update danger-undercover dependency * Add .tool-versions config for asdf * Update test description --- .github/workflows/test_production_build.yml | 4 ++-- .github/workflows/test_variants.yml | 4 ++-- .template/Gemfile.lock | 6 +++--- .template/spec/base/template_spec.rb | 6 +++++- .template/spec/variants/web/tool_versions_spec.rb | 7 +++++++ .template/variants/web/.tool-versions.rb | 5 +++++ .template/variants/web/template.rb | 1 + .tool-versions.tt | 1 + Gemfile.tt | 5 +++-- README.md | 2 +- spec/support/simplecov.rb | 8 +++++++- template.rb | 7 ++++--- 12 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 .template/spec/variants/web/tool_versions_spec.rb create mode 100644 .template/variants/web/.tool-versions.rb create mode 100644 .tool-versions.tt diff --git a/.github/workflows/test_production_build.yml b/.github/workflows/test_production_build.yml index d5e6a4a4..342130cb 100644 --- a/.github/workflows/test_production_build.yml +++ b/.github/workflows/test_production_build.yml @@ -6,7 +6,7 @@ env: APP_NAME: rails_templates DOCKER_IMAGE: ${{ github.repository }} DOCKER_REGISTRY_HOST: ${{ secrets.DOCKER_REGISTRY_HOST }} - RUBY_VERSION: 2.7.2 + RUBY_VERSION: 3.0.1 NODE_VERSION: 14 RAILS_VERSION: 7.0.1 @@ -29,7 +29,7 @@ jobs: uses: nimblehq/branch-tag-action@v1.2 - name: Setup Ruby - uses: ruby/setup-ruby@v1.61.1 + uses: ruby/setup-ruby@v1 with: ruby-version: ${{ env.RUBY_VERSION }} bundler-cache: true diff --git a/.github/workflows/test_variants.yml b/.github/workflows/test_variants.yml index 979636d1..e32dd099 100644 --- a/.github/workflows/test_variants.yml +++ b/.github/workflows/test_variants.yml @@ -9,7 +9,7 @@ env: DOCKER_REGISTRY_HOST: ${{ secrets.DOCKER_REGISTRY_HOST }} DOCKER_REGISTRY_USERNAME: ${{ github.repository_owner }} DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_REGISTRY_TOKEN }} - RUBY_VERSION: 2.7.2 + RUBY_VERSION: 3.0.1 NODE_VERSION: 14 RAILS_VERSION: 7.0.1 @@ -32,7 +32,7 @@ jobs: uses: nimblehq/branch-tag-action@v1.2 - name: Setup Ruby - uses: ruby/setup-ruby@v1.61.1 + uses: ruby/setup-ruby@v1 with: ruby-version: ${{ env.RUBY_VERSION }} bundler-cache: true diff --git a/.template/Gemfile.lock b/.template/Gemfile.lock index 74b793c3..bc472589 100644 --- a/.template/Gemfile.lock +++ b/.template/Gemfile.lock @@ -2,10 +2,10 @@ GEM remote: https://rubygems.org/ specs: diff-lcs (1.4.4) - docker-api (1.34.2) + docker-api (2.2.0) excon (>= 0.47.0) multi_json - excon (0.75.0) + excon (0.90.0) multi_json (1.15.0) net-scp (3.0.0) net-ssh (>= 2.6.5, < 7.0.0) @@ -51,4 +51,4 @@ DEPENDENCIES serverspec BUNDLED WITH - 2.1.4 + 2.3.3 diff --git a/.template/spec/base/template_spec.rb b/.template/spec/base/template_spec.rb index 9e04595e..598d4922 100644 --- a/.template/spec/base/template_spec.rb +++ b/.template/spec/base/template_spec.rb @@ -3,11 +3,15 @@ expect(file('.rubocop.yml')).to exist end - it 'creates Ruby configuration files' do + it 'creates RVM configuration files' do expect(file('.ruby-gemset')).to exist expect(file('.ruby-version')).to exist end + it 'creates ASDF configuration files' do + expect(file('.tool-versions')).to exist + end + it 'creates editor configuration file' do expect(file('.editorconfig')).to exist end diff --git a/.template/spec/variants/web/tool_versions_spec.rb b/.template/spec/variants/web/tool_versions_spec.rb new file mode 100644 index 00000000..881625e7 --- /dev/null +++ b/.template/spec/variants/web/tool_versions_spec.rb @@ -0,0 +1,7 @@ +describe 'Web variant - .tool-versions' do + subject { file('.tool-versions') } + + it 'sets the Node.JS version' do + expect(subject).to contain('nodejs') + end +end diff --git a/.template/variants/web/.tool-versions.rb b/.template/variants/web/.tool-versions.rb new file mode 100644 index 00000000..d365065c --- /dev/null +++ b/.template/variants/web/.tool-versions.rb @@ -0,0 +1,5 @@ +append_to_file '.tool-versions' do + <<~EOT + nodejs #{NODE_VERSION} + EOT +end diff --git a/.template/variants/web/template.rb b/.template/variants/web/template.rb index 729fe615..aedcc834 100644 --- a/.template/variants/web/template.rb +++ b/.template/variants/web/template.rb @@ -7,6 +7,7 @@ def apply_web_variant! template '.nvmrc.tt' copy_file '.npmrc' + apply '.tool-versions.rb' apply 'Gemfile.rb' apply 'app/template.rb' diff --git a/.tool-versions.tt b/.tool-versions.tt new file mode 100644 index 00000000..eb5ab0c2 --- /dev/null +++ b/.tool-versions.tt @@ -0,0 +1 @@ +ruby <%= RUBY_VERSION %> diff --git a/Gemfile.tt b/Gemfile.tt index 72222663..b76f6cdd 100644 --- a/Gemfile.tt +++ b/Gemfile.tt @@ -41,17 +41,18 @@ group :development, :test do # Utilities gem 'figaro' # Simple Rails app configuration - gem 'listen', '3.1.5' # Listens to file modifications + gem 'listen' # Listens to file modifications gem 'letter_opener' # Preview mail in the browser instead of sending gem 'ffaker' # A library for generating fake data such as names, addresses, and phone numbers gem 'fabrication' # Fabrication generates objects in Ruby. Fabricators are schematics for your objects, and can be created as needed anywhere in your app or specs # Testing - gem 'rspec-rails', '~> 4.0.1' # Rails testing engine + gem 'rspec-rails', '~> 5.0.2' # Rails testing engine # Code Analysis gem 'bullet' # help to kill N+1 queries and unused eager loading gem 'brakeman', require: false # A static analysis security vulnerability scanner for Ruby on Rails applications + gem 'parser', '3.0.1.1' # Use correct parser version to avoid parser warnings gem 'rubocop', require: false # A Ruby static code analyzer and formatter, based on the community Ruby style guide. gem 'rubocop-rails', require: false # A RuboCop extension focused on enforcing Rails best practices and coding conventions. gem 'rubocop-rspec', require: false # Code style checking for RSpec files diff --git a/README.md b/README.md index 14304fa5..7c6be7cf 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ with building complex applications over the years. ### Requirements -- Install ruby and set your local ruby version to `2.7.2` +- Install ruby and set your local ruby version to `3.0.1` - Install rails `7.0.1` ### Use the template diff --git a/spec/support/simplecov.rb b/spec/support/simplecov.rb index 4658c4cf..23bbe98a 100644 --- a/spec/support/simplecov.rb +++ b/spec/support/simplecov.rb @@ -2,7 +2,13 @@ require 'simplecov-json' require 'simplecov-lcov' -formatters = [SimpleCov::Formatter::HTMLFormatter, SimpleCov::Formatter::JSONFormatter, SimpleCov::Formatter::LcovFormatter] +formatters = [ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::JSONFormatter, + SimpleCov::Formatter::LcovFormatter +] + +SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(formatters) if ENV['CIRCLE_ARTIFACTS'] diff --git a/template.rb b/template.rb index ea6b0d37..4ef71eeb 100644 --- a/template.rb +++ b/template.rb @@ -6,7 +6,7 @@ APP_NAME_HUMANIZED = app_name.split(/[-_]/).map(&:capitalize).join(' ').gsub(/ Web$/, '') DOCKER_REGISTRY_HOST = 'docker.io'.freeze DOCKER_IMAGE = "nimblehq/#{APP_NAME}".freeze -RUBY_VERSION = '2.7.2'.freeze +RUBY_VERSION = '3.0.1'.freeze POSTGRES_VERSION = '12.1'.freeze REDIS_VERSION = '5.0.7'.freeze # Variants @@ -20,8 +20,8 @@ }.freeze if WEB_VARIANT - NODE_VERSION='14.15.4'.freeze - NODE_SOURCE_VERSION='14'.freeze # Used in Dockerfile https://github.com/nodesource/distributions + NODE_VERSION='16.13.2'.freeze + NODE_SOURCE_VERSION='16'.freeze # Used in Dockerfile https://github.com/nodesource/distributions end def apply_template!(template_root) @@ -38,6 +38,7 @@ def apply_template!(template_root) template '.ruby-gemset.tt' template '.ruby-version.tt', force: true + template '.tool-versions.tt' copy_file '.editorconfig' copy_file 'Procfile' copy_file 'Procfile.dev' From 2a932635ca124da9c17f42806064e72daf7c168e Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Mon, 24 Jan 2022 15:07:35 +0700 Subject: [PATCH 07/13] Upgrade to Bootstrap 5 (#313) * Upgrade to Bootstrap 5 * Update tests --- .template/addons/bootstrap/application.js.rb | 2 +- .../addons/bootstrap/application.scss.rb | 2 +- .../bootstrap/javascript/bootstrap/index.js | 13 --------- .../javascript/vendor/bootstrap/index.js | 27 +++++++++++++++++++ .../bootstrap/javascript/vendor/index.js | 1 + .template/addons/bootstrap/package.json.rb | 4 +-- .../_bootstrap.scss} | 22 +++++++++------ .../bootstrap/stylesheets/vendor/index.scss | 1 + .template/addons/bootstrap/template.rb | 4 +-- .../web/bootstrap/application_js_spec.rb | 4 +-- .../web/bootstrap/application_scss_spec.rb | 4 +-- .../web/bootstrap/package_json_spec.rb | 8 +++--- .../variants/web/bootstrap/template_spec.rb | 17 ++++++++++++ .../app/assets/stylesheets/application.scss | 4 +-- .../assets/stylesheets/functions/index.scss | 1 + 15 files changed, 77 insertions(+), 37 deletions(-) delete mode 100644 .template/addons/bootstrap/javascript/bootstrap/index.js create mode 100644 .template/addons/bootstrap/javascript/vendor/bootstrap/index.js create mode 100644 .template/addons/bootstrap/javascript/vendor/index.js rename .template/addons/bootstrap/stylesheets/{bootstrap/bootstrap.scss.tt => vendor/_bootstrap.scss} (82%) create mode 100644 .template/addons/bootstrap/stylesheets/vendor/index.scss create mode 100644 .template/spec/addons/variants/web/bootstrap/template_spec.rb create mode 100644 .template/variants/web/app/assets/stylesheets/functions/index.scss diff --git a/.template/addons/bootstrap/application.js.rb b/.template/addons/bootstrap/application.js.rb index 0bc050d8..e888b8ca 100644 --- a/.template/addons/bootstrap/application.js.rb +++ b/.template/addons/bootstrap/application.js.rb @@ -2,6 +2,6 @@ insert_into_file 'app/javascript/packs/application.js', before: %r{import 'translations/translations'.+\n} do <<~JAVASCRIPT - import 'vendor/bootstrap'; + import 'vendor/'; JAVASCRIPT end diff --git a/.template/addons/bootstrap/application.scss.rb b/.template/addons/bootstrap/application.scss.rb index c7e807da..cc242bf2 100644 --- a/.template/addons/bootstrap/application.scss.rb +++ b/.template/addons/bootstrap/application.scss.rb @@ -2,6 +2,6 @@ insert_into_file 'app/assets/stylesheets/application.scss', after: /\/\/ Dependencies\n/ do <<~SCSS - @import 'vendor/bootstrap/bootstrap'; + @import './vendor'; SCSS end diff --git a/.template/addons/bootstrap/javascript/bootstrap/index.js b/.template/addons/bootstrap/javascript/bootstrap/index.js deleted file mode 100644 index 446ccadf..00000000 --- a/.template/addons/bootstrap/javascript/bootstrap/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import bootstrap from 'bootstrap.native/dist/bootstrap-native'; - -export const Alert = bootstrap.Alert; -export const Button = bootstrap.Button; -export const Carousel = bootstrap.Carousel; -export const Collapse = bootstrap.Collapse; -export const Dropdown = bootstrap.Dropdown; -export const Modal = bootstrap.Modal; -export const Popover = bootstrap.Popover; -export const ScrollSpy = bootstrap.ScrollSpy; -export const Tab = bootstrap.Tab; -export const Toast = bootstrap.Toast; -export const Tooltip = bootstrap.Tooltip; diff --git a/.template/addons/bootstrap/javascript/vendor/bootstrap/index.js b/.template/addons/bootstrap/javascript/vendor/bootstrap/index.js new file mode 100644 index 00000000..671fdbcd --- /dev/null +++ b/.template/addons/bootstrap/javascript/vendor/bootstrap/index.js @@ -0,0 +1,27 @@ +import Alert from 'bootstrap/js/dist/alert'; +import Button from 'bootstrap/js/dist/button'; +import Carousel from 'bootstrap/js/dist/carousel'; +import Collapse from 'bootstrap/js/dist/collapse'; +import Dropdown from 'bootstrap/js/dist/dropdown'; +import Modal from 'bootstrap/js/dist/modal'; +import Offcanvas from 'bootstrap/js/dist/offcanvas'; +import Popover from 'bootstrap/js/dist/popover'; +import ScrollSpy from 'bootstrap/js/dist/scrollspy'; +import Tab from 'bootstrap/js/dist/tab'; +import Toast from 'bootstrap/js/dist/toast'; +import Tooltip from 'bootstrap/js/dist/tooltip'; + +export default { + Alert, + Button, + Carousel, + Collapse, + Dropdown, + Modal, + Offcanvas, + Popover, + ScrollSpy, + Tab, + Toast, + Tooltip +}; diff --git a/.template/addons/bootstrap/javascript/vendor/index.js b/.template/addons/bootstrap/javascript/vendor/index.js new file mode 100644 index 00000000..e59d6a0a --- /dev/null +++ b/.template/addons/bootstrap/javascript/vendor/index.js @@ -0,0 +1 @@ +import './bootstrap'; diff --git a/.template/addons/bootstrap/package.json.rb b/.template/addons/bootstrap/package.json.rb index 1d373ca0..baefb76f 100644 --- a/.template/addons/bootstrap/package.json.rb +++ b/.template/addons/bootstrap/package.json.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true -run 'yarn add bootstrap@^4.5.2' -run 'yarn add bootstrap.native@^3.0.13' +run 'yarn add bootstrap@5.1.3' +run 'yarn add @popperjs/core@2.11.2' diff --git a/.template/addons/bootstrap/stylesheets/bootstrap/bootstrap.scss.tt b/.template/addons/bootstrap/stylesheets/vendor/_bootstrap.scss similarity index 82% rename from .template/addons/bootstrap/stylesheets/bootstrap/bootstrap.scss.tt rename to .template/addons/bootstrap/stylesheets/vendor/_bootstrap.scss index 3f52ecb0..aabbe2e8 100644 --- a/.template/addons/bootstrap/stylesheets/bootstrap/bootstrap.scss.tt +++ b/.template/addons/bootstrap/stylesheets/vendor/_bootstrap.scss @@ -3,34 +3,34 @@ // pick what the project requires // and comment out the rest. +// Configuration @import 'bootstrap/scss/functions'; @import 'bootstrap/scss/variables'; @import 'bootstrap/scss/mixins'; +@import 'bootstrap/scss/utilities'; + +// Layout & components @import 'bootstrap/scss/root'; @import 'bootstrap/scss/reboot'; @import 'bootstrap/scss/type'; -@import 'bootstrap/scss/utilities'; @import 'bootstrap/scss/images'; +@import 'bootstrap/scss/containers'; @import 'bootstrap/scss/grid'; +@import 'bootstrap/scss/tables'; @import 'bootstrap/scss/forms'; @import 'bootstrap/scss/buttons'; -@import 'bootstrap/scss/tables'; -@import 'bootstrap/scss/code'; @import 'bootstrap/scss/transitions'; @import 'bootstrap/scss/dropdown'; @import 'bootstrap/scss/button-group'; -@import 'bootstrap/scss/input-group'; -@import 'bootstrap/scss/custom-forms'; @import 'bootstrap/scss/nav'; @import 'bootstrap/scss/navbar'; @import 'bootstrap/scss/card'; +@import 'bootstrap/scss/accordion'; @import 'bootstrap/scss/breadcrumb'; @import 'bootstrap/scss/pagination'; @import 'bootstrap/scss/badge'; -@import 'bootstrap/scss/jumbotron'; @import 'bootstrap/scss/alert'; @import 'bootstrap/scss/progress'; -@import 'bootstrap/scss/media'; @import 'bootstrap/scss/list-group'; @import 'bootstrap/scss/close'; @import 'bootstrap/scss/toasts'; @@ -39,4 +39,10 @@ @import 'bootstrap/scss/popover'; @import 'bootstrap/scss/carousel'; @import 'bootstrap/scss/spinners'; -@import 'bootstrap/scss/print'; +@import 'bootstrap/scss/offcanvas'; + +// Helpers +@import 'bootstrap/scss/helpers'; + +// Utilities +@import 'bootstrap/scss/utilities/api'; diff --git a/.template/addons/bootstrap/stylesheets/vendor/index.scss b/.template/addons/bootstrap/stylesheets/vendor/index.scss new file mode 100644 index 00000000..bdef18b0 --- /dev/null +++ b/.template/addons/bootstrap/stylesheets/vendor/index.scss @@ -0,0 +1 @@ +@import './bootstrap'; diff --git a/.template/addons/bootstrap/template.rb b/.template/addons/bootstrap/template.rb index a7ec61cd..16d4f272 100644 --- a/.template/addons/bootstrap/template.rb +++ b/.template/addons/bootstrap/template.rb @@ -6,5 +6,5 @@ apply '.template/addons/bootstrap/package.json.rb' apply '.template/addons/bootstrap/application.js.rb' -directory('stylesheets/bootstrap', 'app/assets/stylesheets/vendor/bootstrap') -directory('javascript/bootstrap', 'app/javascript/vendor/bootstrap') +directory('stylesheets/vendor', 'app/assets/stylesheets/vendor') +directory('javascript/vendor', 'app/javascript/vendor') diff --git a/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb b/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb index 76e4765b..7bc7e4db 100644 --- a/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb @@ -1,7 +1,7 @@ describe 'Bootstrap Addon - application.js' do subject { file('app/javascript/packs/application.js') } - it 'imports bootstrap native' do - expect(subject).to contain("import 'vendor/bootstrap';") + it 'imports vendor scripts' do + expect(subject).to contain("import 'vendor/';") end end diff --git a/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb b/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb index b9c9aceb..c03d2cc2 100644 --- a/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb @@ -1,7 +1,7 @@ describe 'Bootstrap Addon - application.scss' do subject { file('app/assets/stylesheets/application.scss') } - it 'imports bootstrap stylesheets' do - expect(subject).to contain("@import 'vendor/bootstrap/bootstrap'") + it 'imports vendor stylesheets' do + expect(subject).to contain("@import './vendor';") end end diff --git a/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb b/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb index bbbcdf8c..5032baa9 100644 --- a/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb @@ -4,12 +4,12 @@ end describe 'Dependencies' do - it 'adds bootstrap.native dependency' do - expect(subject['dependencies']).to include('bootstrap.native') - end - it 'adds bootstrap dependency' do expect(subject['dependencies']).to include('bootstrap') end + + it 'adds @popperjs/core dependency' do + expect(subject['dependencies']).to include('@popperjs/core') + end end end diff --git a/.template/spec/addons/variants/web/bootstrap/template_spec.rb b/.template/spec/addons/variants/web/bootstrap/template_spec.rb new file mode 100644 index 00000000..df1ef16d --- /dev/null +++ b/.template/spec/addons/variants/web/bootstrap/template_spec.rb @@ -0,0 +1,17 @@ +describe 'Bootstrap addon - template' do + it 'creates app/assets/stylesheets/vendor/index.scss' do + expect(file('app/assets/stylesheets/vendor/index.scss')).to exist + end + + it 'creates app/assets/stylesheets/vendor/_bootstrap.scss' do + expect(file('app/assets/stylesheets/vendor/_bootstrap.scss')).to exist + end + + it 'creates javascript/vendor/index.js' do + expect(file('app/javascript/vendor/index.js')).to exist + end + + it 'creates app/javascript/vendor/bootstrap/index.js' do + expect(file('app/javascript/vendor/bootstrap/index.js')).to exist + end +end diff --git a/.template/variants/web/app/assets/stylesheets/application.scss b/.template/variants/web/app/assets/stylesheets/application.scss index 12c39992..1f0188d3 100644 --- a/.template/variants/web/app/assets/stylesheets/application.scss +++ b/.template/variants/web/app/assets/stylesheets/application.scss @@ -1,10 +1,10 @@ // Variables -@import 'variables'; +@import './variables'; // Dependencies // Functions -@import 'functions/sizing'; +@import './functions'; // Mixins diff --git a/.template/variants/web/app/assets/stylesheets/functions/index.scss b/.template/variants/web/app/assets/stylesheets/functions/index.scss new file mode 100644 index 00000000..9642f39c --- /dev/null +++ b/.template/variants/web/app/assets/stylesheets/functions/index.scss @@ -0,0 +1 @@ +@import './sizing'; From 7f805a65ff0ca0b6edc4584b354b5aa26f3c5a5c Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Mon, 31 Jan 2022 11:20:53 +0700 Subject: [PATCH 08/13] Integrate Rails CSS Bundling (#314) * Integrate cssbundling-rails * Update tests * Replace scss-lint gem with stylelint * Move stylelint to web variant and remove scss-lint config * Update docker compose command and fix tests * Update docker compose commands * Update .gitignore * Fix test description * Update command to start the server in README --- .github/workflows/test_production_build.yml | 2 +- .github/workflows/test_variants.yml | 6 +- .gitignore.rb | 4 - .../.github/workflows/deploy_heroku.yml.tt | 4 +- .../github/.github/workflows/test.yml.tt | 14 +- .../workflows/test_production_build.yml.tt | 2 +- .../.semaphore/promotion-production.yml.tt | 4 +- .../.semaphore/promotion-staging.yml.tt | 4 +- .../semaphore/.semaphore/semaphore.yml.tt | 16 +- .template/spec/base/bin/template_spec.rb | 12 +- .template/spec/variants/web/gemfile_spec.rb | 12 +- .../spec/variants/web/package_json_spec.rb | 37 +- .../spec/variants/web/proc_file_dev_spec.rb | 4 + .../web/spec/codebase/codebase_spec.rb | 4 +- .template/spec/variants/web/template_spec.rb | 26 +- .template/variants/web/.gitignore.rb | 10 + .template/variants/web/.scss-lint.yml | 447 ------------------ .template/variants/web/.stylelintignore | 1 + .template/variants/web/.stylelintrc | 12 + .template/variants/web/Gemfile.rb | 22 +- .template/variants/web/Procfile.dev.rb | 1 + .template/variants/web/app/template.rb | 4 + .template/variants/web/package.json.rb | 29 +- .../web/spec/codebase/codebase_spec.rb | 6 +- .template/variants/web/template.rb | 11 +- .tool-versions | 2 + README.md | 1 + README.md.tt | 10 +- bin/dev | 3 + bin/envsetup.sh | 2 +- bin/template.rb | 1 + 31 files changed, 174 insertions(+), 539 deletions(-) create mode 100644 .template/variants/web/.gitignore.rb delete mode 100644 .template/variants/web/.scss-lint.yml create mode 100644 .template/variants/web/.stylelintignore create mode 100644 .template/variants/web/.stylelintrc create mode 100644 .tool-versions create mode 100755 bin/dev diff --git a/.github/workflows/test_production_build.yml b/.github/workflows/test_production_build.yml index 342130cb..e0d999ec 100644 --- a/.github/workflows/test_production_build.yml +++ b/.github/workflows/test_production_build.yml @@ -7,7 +7,7 @@ env: DOCKER_IMAGE: ${{ github.repository }} DOCKER_REGISTRY_HOST: ${{ secrets.DOCKER_REGISTRY_HOST }} RUBY_VERSION: 3.0.1 - NODE_VERSION: 14 + NODE_VERSION: 16 RAILS_VERSION: 7.0.1 jobs: diff --git a/.github/workflows/test_variants.yml b/.github/workflows/test_variants.yml index e32dd099..7b9f40eb 100644 --- a/.github/workflows/test_variants.yml +++ b/.github/workflows/test_variants.yml @@ -10,7 +10,7 @@ env: DOCKER_REGISTRY_USERNAME: ${{ github.repository_owner }} DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_REGISTRY_TOKEN }} RUBY_VERSION: 3.0.1 - NODE_VERSION: 14 + NODE_VERSION: 16 RAILS_VERSION: 7.0.1 jobs: @@ -87,7 +87,7 @@ jobs: run: | export BRANCH_TAG=${{ env.BRANCH_TAG }}-${{ matrix.variant }} cd $APP_NAME - docker-compose pull test || true + docker compose pull test || true - name: Build docker image run: | @@ -98,7 +98,7 @@ jobs: run: | export BRANCH_TAG=${{ env.BRANCH_TAG }}-${{ matrix.variant }} cd $APP_NAME - docker-compose push test + docker compose push test - name: Test template run: | diff --git a/.gitignore.rb b/.gitignore.rb index 5bd5d713..13be93ac 100644 --- a/.gitignore.rb +++ b/.gitignore.rb @@ -1,10 +1,6 @@ append_to_file '.gitignore' do <<~EOT - # Ignore i18n.js generated files - # If deploy to heroku with git, please remove this as it prevents the files to be committed - /app/javascript/translations/translations.js - # Ignore folder information and IDE-specific files .DS_Store .idea/* diff --git a/.template/addons/github/.github/workflows/deploy_heroku.yml.tt b/.template/addons/github/.github/workflows/deploy_heroku.yml.tt index 036bb034..802c44b7 100644 --- a/.template/addons/github/.github/workflows/deploy_heroku.yml.tt +++ b/.template/addons/github/.github/workflows/deploy_heroku.yml.tt @@ -55,10 +55,10 @@ jobs: password: ${{ env.DOCKER_REGISTRY_TOKEN }} - name: Build Docker image - run: bin/docker-prepare && docker-compose build + run: bin/docker-prepare && docker compose build - name: Push Docker image - run: docker-compose push web + run: docker compose push web - name: Login to Heroku run: heroku container:login diff --git a/.template/addons/github/.github/workflows/test.yml.tt b/.template/addons/github/.github/workflows/test.yml.tt index e5e90ead..71dc7af6 100644 --- a/.template/addons/github/.github/workflows/test.yml.tt +++ b/.template/addons/github/.github/workflows/test.yml.tt @@ -35,13 +35,13 @@ jobs: - name: Pull Docker image if: ${{ env.BRANCH_TAG != 'latest' && env.BRANCH_TAG != 'development' }} - run: docker-compose pull test || true + run: docker compose pull test || true - name: Build Docker image - run: bin/docker-prepare && docker-compose build + run: bin/docker-prepare && docker compose build - name: Push Docker image - run: docker-compose push test + run: docker compose push test unit_tests: name: Unit tests @@ -61,10 +61,10 @@ jobs: password: ${{ env.DOCKER_REGISTRY_TOKEN }} - name: Pull Docker image - run: docker-compose pull test || true + run: docker compose pull test || true - name: Run unit tests - run: docker-compose run test bundle exec rspec --exclude-pattern "spec/systems/**/*_spec.rb" --profile + run: docker compose run test bundle exec rspec --exclude-pattern "spec/systems/**/*_spec.rb" --profile system_tests: name: System tests @@ -84,10 +84,10 @@ jobs: password: ${{ env.DOCKER_REGISTRY_TOKEN }} - name: Pull Docker image - run: docker-compose pull test || true + run: docker compose pull test || true - name: Run system tests - run: docker-compose run test bundle exec rspec spec/systems --profile + run: docker compose run test bundle exec rspec spec/systems --profile - name: Upload system tests screenshots artifact uses: actions/upload-artifact@v2 diff --git a/.template/addons/github/.github/workflows/test_production_build.yml.tt b/.template/addons/github/.github/workflows/test_production_build.yml.tt index 2e2b780a..1b7dd1ba 100644 --- a/.template/addons/github/.github/workflows/test_production_build.yml.tt +++ b/.template/addons/github/.github/workflows/test_production_build.yml.tt @@ -27,4 +27,4 @@ jobs: uses: nimblehq/branch-tag-action@v1.2 - name: Build Docker image - run: bin/docker-prepare && docker-compose build + run: bin/docker-prepare && docker compose build diff --git a/.template/addons/semaphore/.semaphore/promotion-production.yml.tt b/.template/addons/semaphore/.semaphore/promotion-production.yml.tt index 600e43c8..188cbbb5 100644 --- a/.template/addons/semaphore/.semaphore/promotion-production.yml.tt +++ b/.template/addons/semaphore/.semaphore/promotion-production.yml.tt @@ -27,8 +27,8 @@ blocks: - name: Build commands: - bin/docker-prepare - - docker-compose build - - docker-compose push web + - docker compose build + - docker compose push web - name: Deploy task: diff --git a/.template/addons/semaphore/.semaphore/promotion-staging.yml.tt b/.template/addons/semaphore/.semaphore/promotion-staging.yml.tt index 0f5bcb8e..ee100af3 100644 --- a/.template/addons/semaphore/.semaphore/promotion-staging.yml.tt +++ b/.template/addons/semaphore/.semaphore/promotion-staging.yml.tt @@ -27,8 +27,8 @@ blocks: - name: Build commands: - bin/docker-prepare - - docker-compose build - - docker-compose push web + - docker compose build + - docker compose push web - name: Deploy task: diff --git a/.template/addons/semaphore/.semaphore/semaphore.yml.tt b/.template/addons/semaphore/.semaphore/semaphore.yml.tt index eaccc410..79c56c93 100644 --- a/.template/addons/semaphore/.semaphore/semaphore.yml.tt +++ b/.template/addons/semaphore/.semaphore/semaphore.yml.tt @@ -29,31 +29,31 @@ blocks: commands: - >- if ([ $SEMAPHORE_GIT_BRANCH != 'master' ] && [ $SEMAPHORE_GIT_BRANCH != 'development' ]); - then (echo "Pulling built image for the branch"; docker-compose pull test || true); + then (echo "Pulling built image for the branch"; docker compose pull test || true); else (echo "Skipping docker pull"); fi || true - bin/docker-prepare - - docker-compose build - - docker-compose push test + - docker compose build + - docker compose push test - name: Tests task: prologue: commands: - - docker-compose pull + - docker compose pull jobs: - name: Linters commands: - - docker-compose run test yarn lint + - docker compose run test yarn lint - name: Nginx configuration validate commands: - - docker-compose run test nginx -c /etc/nginx/conf.d/default.conf -t + - docker compose run test nginx -c /etc/nginx/conf.d/default.conf -t - name: Unit tests commands: - - docker-compose run test bundle exec rspec --exclude-pattern "spec/systems/**/*_spec.rb" --profile + - docker compose run test bundle exec rspec --exclude-pattern "spec/systems/**/*_spec.rb" --profile - name: System tests commands: - - docker-compose run test bundle exec rspec spec/systems --profile + - docker compose run test bundle exec rspec spec/systems --profile epilogue: on_fail: commands: diff --git a/.template/spec/base/bin/template_spec.rb b/.template/spec/base/bin/template_spec.rb index 1c49f78e..687624a6 100644 --- a/.template/spec/base/bin/template_spec.rb +++ b/.template/spec/base/bin/template_spec.rb @@ -13,14 +13,24 @@ expect(file('bin/test.sh')).to exist expect(file('bin/test.sh')).to be_executable end - + it 'creates the worker script' do expect(file('bin/worker.sh')).to exist expect(file('bin/worker.sh')).to be_executable end + it 'creates the start dev server script' do + expect(file('bin/dev')).to exist + expect(file('bin/dev')).to be_executable + end + it 'creates the docker prepare script' do expect(file('bin/docker-prepare')).to exist expect(file('bin/docker-prepare')).to be_executable end + + it 'creates the docker asset precompile script' do + expect(file('bin/docker-assets-precompile')).to exist + expect(file('bin/docker-assets-precompile')).to be_executable + end end diff --git a/.template/spec/variants/web/gemfile_spec.rb b/.template/spec/variants/web/gemfile_spec.rb index d9e47291..111f3600 100644 --- a/.template/spec/variants/web/gemfile_spec.rb +++ b/.template/spec/variants/web/gemfile_spec.rb @@ -9,18 +9,18 @@ expect(subject).to contain('webpacker') end - it 'adds sassc-rails gem' do - expect(subject).to contain('sassc-rails') + it 'adds sprockets-rails gem' do + expect(subject).to contain('sprockets-rails') + end + + it 'adds cssbundling-rails gem' do + expect(subject).to contain('cssbundling-rails') end describe 'Development + Test Environment' do it 'adds danger-eslint gem' do expect(subject).to contain('danger-eslint').after('^group :development, :test') end - - it 'adds scss_lint gem' do - expect(subject).to contain('scss_lint').after('^group :development, :test') - end end describe 'Test Environment' do diff --git a/.template/spec/variants/web/package_json_spec.rb b/.template/spec/variants/web/package_json_spec.rb index 1927412d..ac655aca 100644 --- a/.template/spec/variants/web/package_json_spec.rb +++ b/.template/spec/variants/web/package_json_spec.rb @@ -3,9 +3,25 @@ JSON.parse(file('package.json').content) end - it 'adds the script for running eslint' do - expect(subject['scripts']).to include('lint') - expect(subject['scripts']).to include('lint:fix') + describe 'Scripts' do + it 'adds the script for running eslint' do + expect(subject['scripts']).to include('eslint') + expect(subject['scripts']).to include('eslint:fix') + end + + it 'adds the script for running stylelint' do + expect(subject['scripts']).to include('stylelint') + expect(subject['scripts']).to include('stylelint:fix') + end + + it 'adds the script for all lints' do + expect(subject['scripts']).to include('lint') + expect(subject['scripts']).to include('lint:fix') + end + + it 'adds the script for bundling css' do + expect(subject['scripts']).to include('build:css') + end end describe 'Dependencies' do @@ -17,11 +33,26 @@ expect(subject['dependencies']).to include('@babel/preset-typescript') expect(subject['dependencies']).to include('typescript') end + + it 'adds sass dependencies' do + expect(subject['dependencies']).to include('sass') + end end describe 'Development Dependencies' do it 'adds Nimble eslint config dependency' do expect(subject['devDependencies']).to include('@nimblehq/eslint-config-nimble') end + + it 'adds stylelint dependencies' do + expect(subject['devDependencies']).to include('stylelint') + expect(subject['devDependencies']).to include('stylelint-config-sass-guidelines') + expect(subject['devDependencies']).to include('stylelint-config-property-sort-order-smacss') + end + + it 'adds postcss 8 dependencies' do + expect(subject['devDependencies']).to include('postcss') + expect(subject['devDependencies']['postcss']).to eq('8.4.5') + end end end diff --git a/.template/spec/variants/web/proc_file_dev_spec.rb b/.template/spec/variants/web/proc_file_dev_spec.rb index f116b855..75870b46 100644 --- a/.template/spec/variants/web/proc_file_dev_spec.rb +++ b/.template/spec/variants/web/proc_file_dev_spec.rb @@ -4,4 +4,8 @@ it 'adds a webpack process' do expect(subject).to contain('webpack') end + + it 'adds a css process' do + expect(subject).to contain('css') + end end diff --git a/.template/spec/variants/web/spec/codebase/codebase_spec.rb b/.template/spec/variants/web/spec/codebase/codebase_spec.rb index fbf1ecf8..174278f1 100644 --- a/.template/spec/variants/web/spec/codebase/codebase_spec.rb +++ b/.template/spec/variants/web/spec/codebase/codebase_spec.rb @@ -13,8 +13,8 @@ def scss_lint_example <<~EOT - it 'does not offend scss-lint' do - expect(`scss-lint`).to be_empty + it 'does not offend stylelint' do + expect(`yarn run stylelint ./`).to be_empty end EOT end diff --git a/.template/spec/variants/web/template_spec.rb b/.template/spec/variants/web/template_spec.rb index 57e6669e..00ddc6eb 100644 --- a/.template/spec/variants/web/template_spec.rb +++ b/.template/spec/variants/web/template_spec.rb @@ -1,33 +1,29 @@ describe 'Web variant - template' do it 'creates the eslint configuration files' do - expect(file('.eslintignore')).to exist expect(file('.eslintrc')).to exist + expect(file('.eslintignore')).to exist end - it 'creates sass lint configuration file' do - expect(file('.scss-lint.yml')).to exist + it 'creates the stylelint configuration files' do + expect(file('.stylelintrc')).to exist + expect(file('.stylelintignore')).to exist end it 'creates the .nvmrc file' do - expect(file('.nvmrc')) + expect(file('.nvmrc')).to exist end it 'creates the npm configuration file' do - expect(file('.npmrc')) + expect(file('.npmrc')).to exist end it 'creates the TypeScript config file' do - expect(file('tsconfig.json')) + expect(file('tsconfig.json')).to exist end - context 'Turbolinks' do - it 'removes data-turbolinks-track attribute from the layout' do - expect(file('app/views/layouts/application.html.erb')).not_to contain('data-turbolinks-track') - end - - it 'removes Turbolinks package dependency' do - expect(file('app/javascript/packs/application.js')).not_to contain('turbolinks') - expect(file('package.json')).not_to contain('turbolinks') - end + it 'creates the asset manifest file' do + expect(file('app/assets/config/manifest.js')).to exist + expect(file('app/assets/config/manifest.js')).not_to contain('//= link_directory ../stylesheets .css') + expect(file('app/assets/config/manifest.js')).to contain('//= link_tree ../builds') end end diff --git a/.template/variants/web/.gitignore.rb b/.template/variants/web/.gitignore.rb new file mode 100644 index 00000000..478cd924 --- /dev/null +++ b/.template/variants/web/.gitignore.rb @@ -0,0 +1,10 @@ +append_to_file '.gitignore' do + <<~EOT + # Ignore i18n.js generated files + # If deploy to heroku with git, please remove this as it prevents the files to be committed + /app/javascript/translations/translations.js + + # Ignore asset builds + /app/assets/builds/* + EOT +end diff --git a/.template/variants/web/.scss-lint.yml b/.template/variants/web/.scss-lint.yml deleted file mode 100644 index c86c1fab..00000000 --- a/.template/variants/web/.scss-lint.yml +++ /dev/null @@ -1,447 +0,0 @@ -exclude: - - 'node_modules/**' - - 'coverage/**' - -linters: - BangFormat: - enabled: true - space_before_bang: true - space_after_bang: false - - BorderZero: - enabled: true - - ColorKeyword: - enabled: true - - Comment: - enabled: true - exclude: - - 'app/assets/stylesheets/application.css' - - DebugStatement: - enabled: true - - DeclarationOrder: - enabled: false - - DuplicateProperty: - enabled: true - - ElsePlacement: - enabled: true - style: same_line - - EmptyLineBetweenBlocks: - enabled: false - ignore_single_line_blocks: true - - EmptyRule: - enabled: true - - FinalNewline: - enabled: true - present: true - - HexLength: - enabled: true - style: short - - HexNotation: - enabled: true - style: lowercase - - HexValidation: - enabled: true - - IdSelector: - enabled: true - - ImportPath: - enabled: true - leading_underscore: false - filename_extension: false - - Indentation: - enabled: true - character: space - width: 2 - - LeadingZero: - enabled: false - style: exclude_zero - - MergeableSelector: - enabled: true - force_nesting: true - - NameFormat: - enabled: true - allow_leading_underscore: true - convention: hyphenated_lowercase # or 'BEM', or a regex pattern - - NestingDepth: - enabled: true - - PlaceholderInExtend: - enabled: false - - PropertySortOrder: - enabled: true - ignore_unspecified: false - severity: warning - order: [ - "position", - "top", - "right", - "bottom", - "left", - "z-index", - "display", - "float", - "width", - "min-width", - "max-width", - "height", - "min-height", - "max-height", - "-webkit-box-sizing", - "-moz-box-sizing", - "box-sizing", - "-webkit-appearance", - "flex", - "flex-direction", - "flex-flow", - "flex-order", - "flex-pack", - "flex-align", - "padding", - "padding-top", - "padding-right", - "padding-bottom", - "padding-left", - "margin", - "margin-top", - "margin-right", - "margin-bottom", - "margin-left", - "overflow", - "overflow-x", - "overflow-y", - "-webkit-overflow-scrolling", - "-ms-overflow-x", - "-ms-overflow-y", - "-ms-overflow-style", - "clip", - "clear", - "font", - "font-family", - "font-size", - "font-style", - "font-weight", - "font-variant", - "font-size-adjust", - "font-stretch", - "font-effect", - "font-emphasize", - "font-emphasize-position", - "font-emphasize-style", - "font-smooth", - "-webkit-hyphens", - "-moz-hyphens", - "hyphens", - "line-height", - "color", - "text-align", - "-webkit-text-align-last", - "-moz-text-align-last", - "-ms-text-align-last", - "text-align-last", - "text-emphasis", - "text-emphasis-color", - "text-emphasis-style", - "text-emphasis-position", - "text-decoration", - "text-indent", - "text-justify", - "text-outline", - "-ms-text-overflow", - "text-overflow", - "text-overflow-ellipsis", - "text-overflow-mode", - "text-shadow", - "text-transform", - "text-wrap", - "-webkit-text-size-adjust", - "-ms-text-size-adjust", - "letter-spacing", - "-ms-word-break", - "word-break", - "word-spacing", - "-ms-word-wrap", - "word-wrap", - "-moz-tab-size", - "-o-tab-size", - "tab-size", - "white-space", - "vertical-align", - "list-style", - "list-style-position", - "list-style-type", - "list-style-image", - "pointer-events", - "-ms-touch-action", - "touch-action", - "cursor", - "visibility", - "zoom", - "table-layout", - "empty-cells", - "caption-side", - "border-spacing", - "border-collapse", - "content", - "quotes", - "counter-reset", - "counter-increment", - "resize", - "-webkit-user-select", - "-moz-user-select", - "-ms-user-select", - "-o-user-select", - "user-select", - "nav-index", - "nav-up", - "nav-right", - "nav-down", - "nav-left", - "background", - "background-color", - "background-image", - "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient", - "filter:progid:DXImageTransform.Microsoft.gradient", - "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader", - "filter", - "background-repeat", - "background-attachment", - "background-position", - "background-position-x", - "background-position-y", - "-webkit-background-clip", - "-moz-background-clip", - "background-clip", - "background-origin", - "-webkit-background-size", - "-moz-background-size", - "-o-background-size", - "background-size", - "border", - "border-color", - "border-style", - "border-width", - "border-top", - "border-top-color", - "border-top-style", - "border-top-width", - "border-right", - "border-right-color", - "border-right-style", - "border-right-width", - "border-bottom", - "border-bottom-color", - "border-bottom-style", - "border-bottom-width", - "border-left", - "border-left-color", - "border-left-style", - "border-left-width", - "border-radius", - "border-top-left-radius", - "border-top-right-radius", - "border-bottom-right-radius", - "border-bottom-left-radius", - "-webkit-border-image", - "-moz-border-image", - "-o-border-image", - "border-image", - "-webkit-border-image-source", - "-moz-border-image-source", - "-o-border-image-source", - "border-image-source", - "-webkit-border-image-slice", - "-moz-border-image-slice", - "-o-border-image-slice", - "border-image-slice", - "-webkit-border-image-width", - "-moz-border-image-width", - "-o-border-image-width", - "border-image-width", - "-webkit-border-image-outset", - "-moz-border-image-outset", - "-o-border-image-outset", - "border-image-outset", - "-webkit-border-image-repeat", - "-moz-border-image-repeat", - "-o-border-image-repeat", - "border-image-repeat", - "outline", - "outline-width", - "outline-style", - "outline-color", - "outline-offset", - "-webkit-box-shadow", - "-moz-box-shadow", - "box-shadow", - "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity", - "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha", - "opacity", - "-ms-interpolation-mode", - "-webkit-transition", - "-moz-transition", - "-ms-transition", - "-o-transition", - "transition", - "-webkit-transition-delay", - "-moz-transition-delay", - "-ms-transition-delay", - "-o-transition-delay", - "transition-delay", - "-webkit-transition-timing-function", - "-moz-transition-timing-function", - "-ms-transition-timing-function", - "-o-transition-timing-function", - "transition-timing-function", - "-webkit-transition-duration", - "-moz-transition-duration", - "-ms-transition-duration", - "-o-transition-duration", - "transition-duration", - "-webkit-transition-property", - "-moz-transition-property", - "-ms-transition-property", - "-o-transition-property", - "transition-property", - "-webkit-transform", - "-moz-transform", - "-ms-transform", - "-o-transform", - "transform", - "-webkit-transform-origin", - "-moz-transform-origin", - "-ms-transform-origin", - "-o-transform-origin", - "transform-origin", - "-webkit-animation", - "-moz-animation", - "-ms-animation", - "-o-animation", - "animation", - "-webkit-animation-name", - "-moz-animation-name", - "-ms-animation-name", - "-o-animation-name", - "animation-name", - "-webkit-animation-duration", - "-moz-animation-duration", - "-ms-animation-duration", - "-o-animation-duration", - "animation-duration", - "-webkit-animation-play-state", - "-moz-animation-play-state", - "-ms-animation-play-state", - "-o-animation-play-state", - "animation-play-state", - "-webkit-animation-timing-function", - "-moz-animation-timing-function", - "-ms-animation-timing-function", - "-o-animation-timing-function", - "animation-timing-function", - "-webkit-animation-delay", - "-moz-animation-delay", - "-ms-animation-delay", - "-o-animation-delay", - "animation-delay", - "-webkit-animation-iteration-count", - "-moz-animation-iteration-count", - "-ms-animation-iteration-count", - "-o-animation-iteration-count", - "animation-iteration-count", - "-webkit-animation-direction", - "-moz-animation-direction", - "-ms-animation-direction", - "-o-animation-direction", - "animation-direction" - ] - - PropertySpelling: - enabled: true - extra_properties: [] - - QualifyingElement: - enabled: true - - SelectorDepth: - enabled: true - max_depth: 5 - - SelectorFormat: - enabled: true - convention: hyphenated_BEM - - Shorthand: - enabled: true - - SingleLinePerProperty: - enabled: true - allow_single_line_rule_sets: true - - SingleLinePerSelector: - enabled: true - - SpaceAfterComma: - enabled: true - - SpaceAfterPropertyColon: - enabled: true - style: at_least_one_space # or 'no_space', or 'at_least_one_space', or 'aligned' - - SpaceAfterPropertyName: - enabled: true - - SpaceBeforeBrace: - enabled: true - style: space - allow_single_line_padding: true - - SpaceBetweenParens: - enabled: true - spaces: 0 - - StringQuotes: - enabled: true - style: single_quotes - - TrailingSemicolon: - enabled: true - - TrailingZero: - enabled: true - - UnnecessaryMantissa: - enabled: true - - UnnecessaryParentReference: - enabled: true - - UrlFormat: - enabled: true - - UrlQuotes: - enabled: true - - VendorPrefix: - enabled: true - identifier_list: base - - ZeroUnit: - enabled: true diff --git a/.template/variants/web/.stylelintignore b/.template/variants/web/.stylelintignore new file mode 100644 index 00000000..2ed8d174 --- /dev/null +++ b/.template/variants/web/.stylelintignore @@ -0,0 +1 @@ +/node_modules/** diff --git a/.template/variants/web/.stylelintrc b/.template/variants/web/.stylelintrc new file mode 100644 index 00000000..e78dc46a --- /dev/null +++ b/.template/variants/web/.stylelintrc @@ -0,0 +1,12 @@ +{ + "extends": [ + "stylelint-config-sass-guidelines", + "stylelint-config-property-sort-order-smacss" + ], + "rules": { + "no-eol-whitespace": true, + "max-nesting-depth": 3, + "scss/at-extend-no-missing-placeholder": null, + "order/properties-alphabetical-order": null + } +} diff --git a/.template/variants/web/Gemfile.rb b/.template/variants/web/Gemfile.rb index 6aef075b..b51ac069 100644 --- a/.template/variants/web/Gemfile.rb +++ b/.template/variants/web/Gemfile.rb @@ -9,12 +9,11 @@ # Assets gem 'webpacker', '5.4.3' # Transpile app-like JavaScript - gem 'sassc-rails' # Use Sass to process CSS + gem 'sprockets-rails' # The original asset pipeline for Rails + gem 'cssbundling-rails' # Bundle and process CSS # gem 'turbo-rails' # Hotwire's SPA-like page accelerator # gem 'stimulus-rails' # Hotwire's modest JavaScript framework - # gem 'sprockets-rails' # The original asset pipeline for Rails # gem 'jsbundling-rails' # Bundle and transpile JavaScript - # gem 'cssbundling-rails' # Bundle and process CSS # gem 'image_processing' # Use Active Storage variants EOT end @@ -24,15 +23,14 @@ ############################ insert_into_file 'Gemfile', after: %r{gem 'danger'.*\n} do - <<-EOT - gem 'danger-eslint' # ESLint - gem 'scss_lint' # SCSS lint + <<~EOT.indent(2) + gem 'danger-eslint' # ESLint EOT end insert_into_file 'Gemfile', after: %r{gem 'spring-watcher-listen'.*\n} do - <<-EOT - # gem 'web-console' # Use console on exceptions pages + <<~EOT.indent(2) + # gem 'web-console' # Use console on exceptions pages EOT end @@ -41,9 +39,9 @@ ############## insert_into_file 'Gemfile', after: %r{gem 'rspec-retry'.*\n} do - <<-EOT - gem 'capybara' # Integration testing - gem 'selenium-webdriver' # Ruby bindings for Selenium/WebDriver - gem 'webdrivers' # Run Selenium tests more easily with automatic installation and updates for all supported webdrivers + <<~EOT.indent(2) + gem 'capybara' # Integration testing + gem 'selenium-webdriver' # Ruby bindings for Selenium/WebDriver + gem 'webdrivers' # Run Selenium tests more easily with automatic installation and updates for all supported webdrivers EOT end diff --git a/.template/variants/web/Procfile.dev.rb b/.template/variants/web/Procfile.dev.rb index cd43952d..367ee3c2 100644 --- a/.template/variants/web/Procfile.dev.rb +++ b/.template/variants/web/Procfile.dev.rb @@ -1,5 +1,6 @@ append_to_file 'Procfile.dev' do <<~EOT webpack: yarn && bin/webpack-dev-server + css: yarn build:css --watch EOT end diff --git a/.template/variants/web/app/template.rb b/.template/variants/web/app/template.rb index 7f3eae72..55c19831 100644 --- a/.template/variants/web/app/template.rb +++ b/.template/variants/web/app/template.rb @@ -30,6 +30,10 @@ remove_file 'app/assets/stylesheets/application.css' directory 'app/assets/stylesheets' +run 'yarn build:css' +gsub_file 'app/assets/config/manifest.js', "//= link_directory ../stylesheets .css\n", '' +append_to_file 'app/assets/config/manifest.js', '//= link_tree ../builds' + # Controllers directory 'app/controllers/concerns' inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController' do diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index 1dd5db04..89941ad6 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -10,15 +10,24 @@ end # Install dependencies -run 'yarn add i18n-js@^3.8.0' -run 'yarn add --dev @nimblehq/eslint-config-nimble@^2.2.1' +run 'yarn add i18n-js@3.8.0' +run 'yarn add sass' +run 'yarn add --dev @nimblehq/eslint-config-nimble@2.2.1' +run 'yarn add --dev stylelint' +run 'yarn add --dev stylelint-config-sass-guidelines' +run 'yarn add --dev stylelint-config-property-sort-order-smacss' +# TODO: Check again after removing Webpacker, need to use version 8 +# https://github.com/bjankord/stylelint-config-sass-guidelines/issues/203#issuecomment-955620774 +run 'yarn add --dev postcss@8.4.5' # Setup scripts -insert_into_file 'package.json', after: %r{"private":.+\n} do - <<~EOT.indent(2) - "scripts": { - "lint": "eslint . --color", - "lint:fix": "eslint . --color --fix" - }, - EOT -end +source_stylesheet = "./app/assets/stylesheets/application.scss" +bundled_stylesheet = "./app/assets/builds/application.css" + +run 'npm set-script eslint "eslint . --color"' +run 'npm set-script eslint:fix "eslint . --color --fix"' +run 'npm set-script stylelint "stylelint **/*.scss --color"' +run 'npm set-script stylelint:fix "stylelint **/*.scss --color --fix"' +run 'npm set-script lint "yarn eslint && yarn stylelint"' +run 'npm set-script lint:fix "yarn eslint:fix && yarn stylelint:fix"' +run %(npm set-script build:css "sass #{source_stylesheet} #{bundled_stylesheet} --no-source-map --load-path=node_modules") diff --git a/.template/variants/web/spec/codebase/codebase_spec.rb b/.template/variants/web/spec/codebase/codebase_spec.rb index 172b41fe..7c5d0a68 100644 --- a/.template/variants/web/spec/codebase/codebase_spec.rb +++ b/.template/variants/web/spec/codebase/codebase_spec.rb @@ -1,12 +1,12 @@ insert_into_file 'spec/codebase/codebase_spec.rb', before: %r{end\Z} do <<-EOT - it 'does not offend scss-lint' do - expect(`scss-lint`).to be_empty + it 'does not offend stylelint' do + expect(`yarn run stylelint`).to include 'Done' end it 'does not offend eslint' do - expect(`yarn run eslint ./`).to include 'Done' + expect(`yarn run eslint`).to include 'Done' end EOT end diff --git a/.template/variants/web/template.rb b/.template/variants/web/template.rb index aedcc834..91fcd838 100644 --- a/.template/variants/web/template.rb +++ b/.template/variants/web/template.rb @@ -1,21 +1,24 @@ def apply_web_variant! use_source_path __dir__ - copy_file '.eslintignore' copy_file '.eslintrc' - copy_file '.scss-lint.yml' + copy_file '.eslintignore' + copy_file '.stylelintrc' + copy_file '.stylelintignore' template '.nvmrc.tt' copy_file '.npmrc' apply '.tool-versions.rb' apply 'Gemfile.rb' + apply 'package.json.rb' apply 'app/template.rb' apply 'config/template.rb' - apply 'package.json.rb' apply 'Dangerfile.rb' apply 'Procfile.dev.rb' + apply '.gitignore.rb' + # Add-ons - [Optional] apply '.template/addons/bootstrap/template.rb' if yes? install_addon_prompt 'Bootstrap' apply '.template/addons/slim/template.rb' if yes? install_addon_prompt 'Slim Template Engine' @@ -31,7 +34,7 @@ def apply_web_variant! run 'bin/rake i18n:js:export' # Fix the default Rails template that does not put trailing commas - run 'yarn run lint --fix' + run 'yarn run lint:fix' apply 'config/webpack/template.rb' apply 'spec/template.rb' diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..7fcd1b3f --- /dev/null +++ b/.tool-versions @@ -0,0 +1,2 @@ +nodejs 16.13.2 +ruby 3.0.1 diff --git a/README.md b/README.md index 7c6be7cf..76d05196 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ with building complex applications over the years. - Install ruby and set your local ruby version to `3.0.1` - Install rails `7.0.1` +- Install node `16.13.2` (For creating web application) ### Use the template diff --git a/README.md.tt b/README.md.tt index 372feb64..da1bdaeb 100644 --- a/README.md.tt +++ b/README.md.tt @@ -36,7 +36,7 @@ - Run the Rails app ```sh -foreman start -f Procfile.dev +./bin/dev ``` ## Tests @@ -71,7 +71,7 @@ it first to leverage the `cache_from` settings of Docker Compose which avoids re - Build the Docker image: ```sh -./bin/docker-prepare && docker-compose -f docker-compose.test.yml build +./bin/docker-prepare && docker compose -f docker-compose.test.yml build ``` Upon the first build, the whole Docker image is built from the ground up and tagged using `$BRANCH_TAG`. @@ -85,7 +85,7 @@ docker push $DOCKER_IMAGE:$BRANCH_TAG - Setup the test database: ```sh -docker-compose -f docker-compose.test.yml run test bin/bundle exec rake db:test:prepare +docker compose -f docker-compose.test.yml run test bin/bundle exec rake db:test:prepare ``` #### Semaphore CI 2.0 @@ -102,7 +102,7 @@ To setup Github actions for the project, please follow [this guideline](.github/ ```sh # Docker way -docker-compose -f docker-compose.test.yml run test +docker compose -f docker-compose.test.yml run test # Non-Docker way rspec @@ -112,7 +112,7 @@ rspec ```sh # Docker way -docker-compose -f docker-compose.test.yml run test bin/bundle exec rspec [rspec-params] +docker compose -f docker-compose.test.yml run test bin/bundle exec rspec [rspec-params] # Non-Docker way rspec [rspec-params] diff --git a/bin/dev b/bin/dev new file mode 100755 index 00000000..f709c1f6 --- /dev/null +++ b/bin/dev @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +foreman start -f Procfile.dev diff --git a/bin/envsetup.sh b/bin/envsetup.sh index 772f54fd..cb2060da 100755 --- a/bin/envsetup.sh +++ b/bin/envsetup.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker-compose -f docker-compose.dev.yml up -d +docker compose -f docker-compose.dev.yml up -d diff --git a/bin/template.rb b/bin/template.rb index 908634ff..da1f69a5 100644 --- a/bin/template.rb +++ b/bin/template.rb @@ -2,5 +2,6 @@ copy_file 'bin/start.sh', mode: :preserve copy_file 'bin/test.sh', mode: :preserve copy_file 'bin/worker.sh', mode: :preserve +copy_file 'bin/dev', mode: :preserve copy_file 'bin/docker-prepare', mode: :preserve copy_file 'bin/docker-assets-precompile', mode: :preserve From ed3d36138d4608580dd8106c9ad4fed6cfc0f682 Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Wed, 9 Feb 2022 18:28:27 +0700 Subject: [PATCH 09/13] Integrate Rails JS bundling (#315) * Integrate with jsbundling * Fix i18n * Update tests * Extract build script * Remove packs from nginx config * Rename lint scripts to codebase --- .template/addons/bootstrap/application.js.rb | 4 +- .../nginx/config/nginx/app.conf.template.tt | 8 +-- .../web/bootstrap/application_js_spec.rb | 4 +- .../spec/variants/web/app/template_spec.rb | 71 +++++++++---------- .../web/config/webpack/environment_js_spec.rb | 24 ------- .../web/config/webpack/template_spec.rb | 5 -- .template/spec/variants/web/gemfile_spec.rb | 8 +-- .../spec/variants/web/package_json_spec.rb | 17 +++-- .../spec/variants/web/proc_file_dev_spec.rb | 4 +- .../spec/variants/web/spec/template_spec.rb | 1 - .template/spec/variants/web/template_spec.rb | 4 -- .template/variants/web/.eslintignore | 13 ++-- .template/variants/web/.gitignore.rb | 5 +- .template/variants/web/.stylelintignore | 1 + .template/variants/web/Gemfile.rb | 5 +- .template/variants/web/Procfile.dev.rb | 2 +- .../web/app/javascript/application.js | 5 ++ .../variants/web/app/javascript/build.js | 13 ++++ .../variants/web/app/javascript/global.js | 3 + .../web/app/javascript/initializers/.keep | 0 .../web/app/javascript/packs/application.js | 1 - .template/variants/web/app/template.rb | 38 +++------- .../web/config/webpack/environment.js.rb | 15 ---- .../variants/web/config/webpack/template.rb | 10 --- .template/variants/web/package.json.rb | 14 ++-- .../variants/web/spec/support/webpack.rb | 9 --- .template/variants/web/template.rb | 7 +- 27 files changed, 113 insertions(+), 178 deletions(-) delete mode 100644 .template/spec/variants/web/config/webpack/environment_js_spec.rb delete mode 100644 .template/spec/variants/web/config/webpack/template_spec.rb create mode 100644 .template/variants/web/app/javascript/application.js create mode 100644 .template/variants/web/app/javascript/build.js create mode 100644 .template/variants/web/app/javascript/global.js delete mode 100644 .template/variants/web/app/javascript/initializers/.keep delete mode 100644 .template/variants/web/app/javascript/packs/application.js delete mode 100644 .template/variants/web/config/webpack/environment.js.rb delete mode 100644 .template/variants/web/config/webpack/template.rb delete mode 100644 .template/variants/web/spec/support/webpack.rb diff --git a/.template/addons/bootstrap/application.js.rb b/.template/addons/bootstrap/application.js.rb index e888b8ca..86728f51 100644 --- a/.template/addons/bootstrap/application.js.rb +++ b/.template/addons/bootstrap/application.js.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -insert_into_file 'app/javascript/packs/application.js', before: %r{import 'translations/translations'.+\n} do +insert_into_file 'app/javascript/application.js', before: %r{import './translations/translations'.+\n} do <<~JAVASCRIPT - import 'vendor/'; + import './vendor/'; JAVASCRIPT end diff --git a/.template/addons/nginx/config/nginx/app.conf.template.tt b/.template/addons/nginx/config/nginx/app.conf.template.tt index 6a385b1a..73a76e48 100755 --- a/.template/addons/nginx/config/nginx/app.conf.template.tt +++ b/.template/addons/nginx/config/nginx/app.conf.template.tt @@ -49,9 +49,9 @@ http { server { server_name _; - + listen $PORT; - + root /<%= APP_NAME %>/public; proxy_set_header X-Real-IP $remote_addr; @@ -70,10 +70,10 @@ http { proxy_buffers 8 12k; proxy_busy_buffers_size 24k; } - + <%- if WEB_VARIANT -%> # Static files - location ~ ^\/(assets|packs)\/.* { + location ~ ^\/assets\/.* { gzip_static on; sendfile on; diff --git a/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb b/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb index 7bc7e4db..290f6f3f 100644 --- a/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb @@ -1,7 +1,7 @@ describe 'Bootstrap Addon - application.js' do - subject { file('app/javascript/packs/application.js') } + subject { file('app/javascript/application.js') } it 'imports vendor scripts' do - expect(subject).to contain("import 'vendor/';") + expect(subject).to contain("import './vendor/';") end end diff --git a/.template/spec/variants/web/app/template_spec.rb b/.template/spec/variants/web/app/template_spec.rb index bd06893d..c9730f25 100644 --- a/.template/spec/variants/web/app/template_spec.rb +++ b/.template/spec/variants/web/app/template_spec.rb @@ -10,47 +10,50 @@ expect(file('app/javascript/screens')).to be_directory end - it 'creates javascript entry file' do - expect(file('app/javascript/packs/application.js')).to exist + it 'creates build script' do + expect(file('app/javascript/build.js')).to exist end - context 'Initializers' do - it 'creates main initializer file' do - expect(file('app/javascript/initializers/index.js')).to exist + context 'Entry file' do + it 'creates javascript entry file' do + expect(file('app/javascript/application.js')).to exist end - it 'creates I18n initializer file' do - expect(file('app/javascript/initializers/i18n.js')).to exist + it 'loads the javascript entry file in the layout' do + expect(file('app/views/layouts/application.html.erb')).to contain('<%= javascript_include_tag "application"') end - end - context 'Screens' do - it 'creates main screens file' do - expect(file('app/javascript/screens/index.js')).to exist + it 'imports necessary modules' do + expect(file('app/javascript/application.js')).to contain('import \'./translations/translations\';') + + expect(file('app/javascript/application.js')).to contain('import \'./initializers/\';') + expect(file('app/javascript/application.js')).to contain('import \'./screens/\';') end end - context 'packs/application.js' do - it 'includes necessary modules' do - expect(file('app/javascript/packs/application.js')).to contain('import \'core-js/stable\';') - expect(file('app/javascript/packs/application.js')).to contain('import \'regenerator-runtime/runtime\';') - - expect(file('app/javascript/packs/application.js')).to contain('import \'translations/translations\';') + context 'Global file' do + it 'creates javascript global file' do + expect(file('app/javascript/global.js')).to exist + end - expect(file('app/javascript/packs/application.js')).to contain('import \'initializers/\';') - expect(file('app/javascript/packs/application.js')).to contain('import \'screens/\';') + it 'exports necessary global modules' do + expect(file('app/javascript/global.js')).to contain('I18n') end end - context 'packs/hello_typescript.ts' do - it 'creates the default pack file for TypeScript' do - expect(file('app/javascript/packs/hello_typescript.ts')).to exist + context 'Initializers' do + it 'creates main initializer file' do + expect(file('app/javascript/initializers/index.js')).to exist + end + + it 'creates I18n initializer file' do + expect(file('app/javascript/initializers/i18n.js')).to exist end end - context 'translations/translations.js' do - it 'creates the translation.js file' do - expect(file('app/javascript/translations/translations.js')).to exist + context 'Screens' do + it 'creates main screens file' do + expect(file('app/javascript/screens/index.js')).to exist end end end @@ -80,25 +83,21 @@ end end - context 'Controllers' do + context 'I18n' do + it 'creates the translation.js file' do + expect(file('app/javascript/translations/translations.js')).to exist + end + it 'creates the localization concern' do expect(file('app/controllers/concerns/localization.rb')).to exist end - context 'Application controller' do - it 'includes the localization concern' do - expect(file('app/controllers/application_controller.rb')).to contain('include Localization') - end + it 'includes the localization concern in the application controller' do + expect(file('app/controllers/application_controller.rb')).to contain('include Localization') end - end - context 'Views' do it 'modifies the html tag to attach the current locale' do expect(file('app/views/layouts/application.html.erb')).to contain("") end - - it 'loads the javascript entry file' do - expect(file('app/views/layouts/application.html.erb')).to contain("<%= javascript_pack_tag 'application' %>") - end end end diff --git a/.template/spec/variants/web/config/webpack/environment_js_spec.rb b/.template/spec/variants/web/config/webpack/environment_js_spec.rb deleted file mode 100644 index a4f9f8ff..00000000 --- a/.template/spec/variants/web/config/webpack/environment_js_spec.rb +++ /dev/null @@ -1,24 +0,0 @@ -describe 'Web variant - config/webpack/environment.js' do - subject { file('config/webpack/environment.js') } - - it 'configures the webpack' do - expect(subject).to contain(webpack_config) - end - - private - - def webpack_config - <<~EOT - const webpack = require('webpack'); - - const plugins = [ - new webpack.ProvidePlugin({ - // Translations - I18n: 'i18n-js', - }) - ]; - - environment.config.set('plugins', plugins); - EOT - end -end diff --git a/.template/spec/variants/web/config/webpack/template_spec.rb b/.template/spec/variants/web/config/webpack/template_spec.rb deleted file mode 100644 index 3b0bc325..00000000 --- a/.template/spec/variants/web/config/webpack/template_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -describe 'Web variant - /config/webpack template' do - it 'configures the webpack compilation in test environment to false' do - expect(file('config/webpacker.yml')).to contain("compile: false").from(/^test:$/).to(/^production:$/) - end -end diff --git a/.template/spec/variants/web/gemfile_spec.rb b/.template/spec/variants/web/gemfile_spec.rb index 111f3600..8f0f873a 100644 --- a/.template/spec/variants/web/gemfile_spec.rb +++ b/.template/spec/variants/web/gemfile_spec.rb @@ -5,10 +5,6 @@ expect(subject).to contain('i18n-js') end - it 'adds webpacker gem' do - expect(subject).to contain('webpacker') - end - it 'adds sprockets-rails gem' do expect(subject).to contain('sprockets-rails') end @@ -17,6 +13,10 @@ expect(subject).to contain('cssbundling-rails') end + it 'adds jsbundling-rails gem' do + expect(subject).to contain('jsbundling-rails') + end + describe 'Development + Test Environment' do it 'adds danger-eslint gem' do expect(subject).to contain('danger-eslint').after('^group :development, :test') diff --git a/.template/spec/variants/web/package_json_spec.rb b/.template/spec/variants/web/package_json_spec.rb index ac655aca..82c72041 100644 --- a/.template/spec/variants/web/package_json_spec.rb +++ b/.template/spec/variants/web/package_json_spec.rb @@ -15,8 +15,12 @@ end it 'adds the script for all lints' do - expect(subject['scripts']).to include('lint') - expect(subject['scripts']).to include('lint:fix') + expect(subject['scripts']).to include('codebase') + expect(subject['scripts']).to include('codebase:fix') + end + + it 'adds the script for bundling js' do + expect(subject['scripts']).to include('build') end it 'adds the script for bundling css' do @@ -29,14 +33,13 @@ expect(subject['dependencies']).to include('i18n-js') end - it 'adds typescript dependencies' do - expect(subject['dependencies']).to include('@babel/preset-typescript') - expect(subject['dependencies']).to include('typescript') - end - it 'adds sass dependencies' do expect(subject['dependencies']).to include('sass') end + + it 'adds esbuild dependencies' do + expect(subject['dependencies']).to include('esbuild') + end end describe 'Development Dependencies' do diff --git a/.template/spec/variants/web/proc_file_dev_spec.rb b/.template/spec/variants/web/proc_file_dev_spec.rb index 75870b46..a5e6567d 100644 --- a/.template/spec/variants/web/proc_file_dev_spec.rb +++ b/.template/spec/variants/web/proc_file_dev_spec.rb @@ -1,8 +1,8 @@ describe 'Web variant - Procfile.dev' do subject { file('Procfile.dev') } - it 'adds a webpack process' do - expect(subject).to contain('webpack') + it 'adds a js process' do + expect(subject).to contain('js') end it 'adds a css process' do diff --git a/.template/spec/variants/web/spec/template_spec.rb b/.template/spec/variants/web/spec/template_spec.rb index 5240ed95..8406f704 100644 --- a/.template/spec/variants/web/spec/template_spec.rb +++ b/.template/spec/variants/web/spec/template_spec.rb @@ -5,7 +5,6 @@ expect(file('spec/support/disable_animation.rb')).to exist expect(file('spec/support/system.rb')).to exist expect(file('spec/support/webdrivers.rb')).to exist - expect(file('spec/support/webpack.rb')).to exist expect(file('spec/support/sanitize.rb')).to exist end diff --git a/.template/spec/variants/web/template_spec.rb b/.template/spec/variants/web/template_spec.rb index 00ddc6eb..9cff4c7a 100644 --- a/.template/spec/variants/web/template_spec.rb +++ b/.template/spec/variants/web/template_spec.rb @@ -17,10 +17,6 @@ expect(file('.npmrc')).to exist end - it 'creates the TypeScript config file' do - expect(file('tsconfig.json')).to exist - end - it 'creates the asset manifest file' do expect(file('app/assets/config/manifest.js')).to exist expect(file('app/assets/config/manifest.js')).not_to contain('//= link_directory ../stylesheets .css') diff --git a/.template/variants/web/.eslintignore b/.template/variants/web/.eslintignore index 9f8c36be..8686ad3a 100644 --- a/.template/variants/web/.eslintignore +++ b/.template/variants/web/.eslintignore @@ -5,12 +5,11 @@ /tmp/** /vendor/** -postcss.config.js -babel.config.js +/app/assets/builds/** -app/javascript/channels/* -app/javascript/translations/translations.js +/app/javascript/channels/** +/app/javascript/translations/translations.js -engines/*/node_modules/** -engines/*/vendor/** -engines/*/app/javascript/*/translations/translations.js +/engines/*/node_modules/** +/engines/*/vendor/** +/engines/*/app/javascript/*/translations/translations.js diff --git a/.template/variants/web/.gitignore.rb b/.template/variants/web/.gitignore.rb index 478cd924..65e2ca70 100644 --- a/.template/variants/web/.gitignore.rb +++ b/.template/variants/web/.gitignore.rb @@ -2,9 +2,12 @@ <<~EOT # Ignore i18n.js generated files # If deploy to heroku with git, please remove this as it prevents the files to be committed - /app/javascript/translations/translations.js + /app/javascript/translations/* # Ignore asset builds /app/assets/builds/* + + # Ignore Node dependencies + /node_modules EOT end diff --git a/.template/variants/web/.stylelintignore b/.template/variants/web/.stylelintignore index 2ed8d174..42a32d80 100644 --- a/.template/variants/web/.stylelintignore +++ b/.template/variants/web/.stylelintignore @@ -1 +1,2 @@ /node_modules/** +/app/assets/builds/** diff --git a/.template/variants/web/Gemfile.rb b/.template/variants/web/Gemfile.rb index b51ac069..d670ac94 100644 --- a/.template/variants/web/Gemfile.rb +++ b/.template/variants/web/Gemfile.rb @@ -1,6 +1,6 @@ insert_into_file 'Gemfile', after: %r{gem 'rails-i18n'.*\n} do <<~EOT - gem 'i18n-js', '3.5.1' # A library to provide the I18n translations on the Javascript + gem 'i18n-js', '3.9.0' # A library to provide the I18n translations on the Javascript EOT end @@ -8,12 +8,11 @@ <<~EOT # Assets - gem 'webpacker', '5.4.3' # Transpile app-like JavaScript gem 'sprockets-rails' # The original asset pipeline for Rails gem 'cssbundling-rails' # Bundle and process CSS + gem 'jsbundling-rails' # Bundle and transpile JavaScript # gem 'turbo-rails' # Hotwire's SPA-like page accelerator # gem 'stimulus-rails' # Hotwire's modest JavaScript framework - # gem 'jsbundling-rails' # Bundle and transpile JavaScript # gem 'image_processing' # Use Active Storage variants EOT end diff --git a/.template/variants/web/Procfile.dev.rb b/.template/variants/web/Procfile.dev.rb index 367ee3c2..780aedfe 100644 --- a/.template/variants/web/Procfile.dev.rb +++ b/.template/variants/web/Procfile.dev.rb @@ -1,6 +1,6 @@ append_to_file 'Procfile.dev' do <<~EOT - webpack: yarn && bin/webpack-dev-server + js: yarn build --watch css: yarn build:css --watch EOT end diff --git a/.template/variants/web/app/javascript/application.js b/.template/variants/web/app/javascript/application.js new file mode 100644 index 00000000..31adb77b --- /dev/null +++ b/.template/variants/web/app/javascript/application.js @@ -0,0 +1,5 @@ +// JavaScript entry file +import './translations/translations'; + +import './initializers/'; +import './screens/'; diff --git a/.template/variants/web/app/javascript/build.js b/.template/variants/web/app/javascript/build.js new file mode 100644 index 00000000..50457fb7 --- /dev/null +++ b/.template/variants/web/app/javascript/build.js @@ -0,0 +1,13 @@ +const watch = process.argv.slice(2).includes('--watch'); + +require('esbuild').build({ + entryPoints: ['app/javascript/application.js'], + inject: ['app/javascript/global.js'], + bundle: true, + sourcemap: true, + watch: watch, + outdir: 'app/assets/builds', +}).catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/.template/variants/web/app/javascript/global.js b/.template/variants/web/app/javascript/global.js new file mode 100644 index 00000000..994e2cdc --- /dev/null +++ b/.template/variants/web/app/javascript/global.js @@ -0,0 +1,3 @@ +import I18n from 'i18n-js'; + +export { I18n }; diff --git a/.template/variants/web/app/javascript/initializers/.keep b/.template/variants/web/app/javascript/initializers/.keep deleted file mode 100644 index e69de29b..00000000 diff --git a/.template/variants/web/app/javascript/packs/application.js b/.template/variants/web/app/javascript/packs/application.js deleted file mode 100644 index e3721d19..00000000 --- a/.template/variants/web/app/javascript/packs/application.js +++ /dev/null @@ -1 +0,0 @@ -// JavaScript entry file diff --git a/.template/variants/web/app/template.rb b/.template/variants/web/app/template.rb index 55c19831..d68c6bab 100644 --- a/.template/variants/web/app/template.rb +++ b/.template/variants/web/app/template.rb @@ -1,28 +1,16 @@ # Javascript directory 'app/javascript' -if File.exist?('app/javascript/packs/application.js') - append_to_file 'app/javascript/packs/application.js' do - <<~EOT - import 'core-js/stable'; - import 'regenerator-runtime/runtime'; - - import 'translations/translations'; - - import 'initializers/'; - import 'screens/'; +if File.exist?('app/views/layouts/application.html.erb') + insert_into_file 'app/views/layouts/application.html.erb', before: %r{} do + <<~EOT.indent(2) + <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> EOT end else @template_errors.add <<~EOT - Cannot import the dependencies to `app/javascript/packs/application.js` - Content: import 'core-js/stable'; - import 'regenerator-runtime/runtime'; - - import 'translations/translations'; - - import 'initializers/'; - import 'screens/'; + Cannot include javascript into `app/views/layouts/application.html.erb` + Content: <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> EOT end @@ -34,29 +22,21 @@ gsub_file 'app/assets/config/manifest.js', "//= link_directory ../stylesheets .css\n", '' append_to_file 'app/assets/config/manifest.js', '//= link_tree ../builds' -# Controllers +# I18n directory 'app/controllers/concerns' inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController' do - <<-EOT - include Localization + <<~EOT.indent(2) + include Localization EOT end -# Views if File.exist?('app/views/layouts/application.html.erb') gsub_file 'app/views/layouts/application.html.erb', // do "" end - - insert_into_file 'app/views/layouts/application.html.erb', before: %r{} do - <<~EOT.indent(2) - <%= javascript_pack_tag 'application' %> - EOT - end else @template_errors.add <<~EOT Cannot insert the lang attribute into html tag into `app/views/layouts/application.html.erb` Content: - <%= javascript_pack_tag 'application' %> EOT end diff --git a/.template/variants/web/config/webpack/environment.js.rb b/.template/variants/web/config/webpack/environment.js.rb deleted file mode 100644 index 180b592f..00000000 --- a/.template/variants/web/config/webpack/environment.js.rb +++ /dev/null @@ -1,15 +0,0 @@ -# Add i18n-js plugin to webpack -insert_into_file 'config/webpack/environment.js', after: %r{const { environment } = require\('@rails/webpacker'\)\n} do - <<~EOT - const webpack = require('webpack'); - - const plugins = [ - new webpack.ProvidePlugin({ - // Translations - I18n: 'i18n-js', - }) - ]; - - environment.config.set('plugins', plugins); - EOT -end diff --git a/.template/variants/web/config/webpack/template.rb b/.template/variants/web/config/webpack/template.rb deleted file mode 100644 index ca5d3472..00000000 --- a/.template/variants/web/config/webpack/template.rb +++ /dev/null @@ -1,10 +0,0 @@ -# This template needs to be applied after bundle because it needs webpack to be installed first -apply 'config/webpack/environment.js.rb' - -gsub_file 'config/webpacker.yml', %r{\ntest:\n\s*<<: \*default\n\s*(compile: true)\n} do - <<~EOT - test: - <<: *default - compile: false - EOT -end diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index 89941ad6..0f594889 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -12,6 +12,8 @@ # Install dependencies run 'yarn add i18n-js@3.8.0' run 'yarn add sass' +run 'yarn add esbuild' + run 'yarn add --dev @nimblehq/eslint-config-nimble@2.2.1' run 'yarn add --dev stylelint' run 'yarn add --dev stylelint-config-sass-guidelines' @@ -21,13 +23,15 @@ run 'yarn add --dev postcss@8.4.5' # Setup scripts -source_stylesheet = "./app/assets/stylesheets/application.scss" -bundled_stylesheet = "./app/assets/builds/application.css" - run 'npm set-script eslint "eslint . --color"' run 'npm set-script eslint:fix "eslint . --color --fix"' run 'npm set-script stylelint "stylelint **/*.scss --color"' run 'npm set-script stylelint:fix "stylelint **/*.scss --color --fix"' -run 'npm set-script lint "yarn eslint && yarn stylelint"' -run 'npm set-script lint:fix "yarn eslint:fix && yarn stylelint:fix"' +run 'npm set-script codebase "yarn eslint && yarn stylelint"' +run 'npm set-script codebase:fix "yarn eslint:fix && yarn stylelint:fix"' + +source_stylesheet = 'app/assets/stylesheets/application.scss' +bundled_stylesheet = 'app/assets/builds/application.css' + +run %(npm set-script build "node app/javascript/build.js") run %(npm set-script build:css "sass #{source_stylesheet} #{bundled_stylesheet} --no-source-map --load-path=node_modules") diff --git a/.template/variants/web/spec/support/webpack.rb b/.template/variants/web/spec/support/webpack.rb deleted file mode 100644 index 42e09f75..00000000 --- a/.template/variants/web/spec/support/webpack.rb +++ /dev/null @@ -1,9 +0,0 @@ -RSpec.configure do |config| - config.when_first_matching_example_defined(type: :system) do - if ENV['TEST_SKIP_ASSET'].blank? - puts 'Prepare webpack assets for test environment' - - `RAILS_ENV=test NODE_ENV=test bin/webpack` - end - end -end diff --git a/.template/variants/web/template.rb b/.template/variants/web/template.rb index 91fcd838..d53af664 100644 --- a/.template/variants/web/template.rb +++ b/.template/variants/web/template.rb @@ -26,17 +26,12 @@ def apply_web_variant! after_bundle do use_source_path __dir__ - # Install Webpacker and Typescript - rails_command('webpacker:install') - rails_command('webpacker:install:typescript') - # Generate translation file run 'bin/rake i18n:js:export' # Fix the default Rails template that does not put trailing commas - run 'yarn run lint:fix' + run 'yarn run codebase:fix' - apply 'config/webpack/template.rb' apply 'spec/template.rb' end end From 3bf65e173b0f5603336571f7206aba95ade66d0f Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Wed, 16 Mar 2022 10:19:39 +0700 Subject: [PATCH 10/13] Add base Github wiki (#317) * Add base Github wiki * Make Github addon optional * Add instructions after project created * Update the addon name * Fix rubocop warnings * Add todo * Add Architecture secion * Fix wiki link * Correct message wording --- .../github/.github/wiki/Authentication.md | 1 + .template/addons/github/.github/wiki/Home.md | 1 + .../addons/github/.github/wiki/_Footer.md | 1 + .../addons/github/.github/wiki/_Sidebar.md | 16 +++++ .../github/.github/wiki/assets/images/.keep | 0 .../github/.github/workflows/README.md.tt | 2 +- .template/addons/github/template.rb | 34 ++++++++++ .../{template.rb => fix_rubocop.rb} | 2 +- .template/hooks/before_complete/report.rb | 27 ++++++++ .template/lib/template.rb | 4 ++ .template/lib/template/errors.rb | 22 +------ .template/lib/template/messages.rb | 19 ++++++ .../spec/addons/base/github/template_spec.rb | 65 +++++++++++++++++++ Makefile | 3 +- README.md.tt | 18 +++-- template.rb | 30 ++++----- 16 files changed, 193 insertions(+), 52 deletions(-) create mode 100644 .template/addons/github/.github/wiki/Authentication.md create mode 100644 .template/addons/github/.github/wiki/Home.md create mode 100644 .template/addons/github/.github/wiki/_Footer.md create mode 100644 .template/addons/github/.github/wiki/_Sidebar.md create mode 100644 .template/addons/github/.github/wiki/assets/images/.keep rename .template/hooks/before_complete/{template.rb => fix_rubocop.rb} (73%) create mode 100644 .template/hooks/before_complete/report.rb create mode 100644 .template/lib/template.rb create mode 100644 .template/lib/template/messages.rb diff --git a/.template/addons/github/.github/wiki/Authentication.md b/.template/addons/github/.github/wiki/Authentication.md new file mode 100644 index 00000000..88def943 --- /dev/null +++ b/.template/addons/github/.github/wiki/Authentication.md @@ -0,0 +1 @@ +> *Insert information about the app authentication here!* diff --git a/.template/addons/github/.github/wiki/Home.md b/.template/addons/github/.github/wiki/Home.md new file mode 100644 index 00000000..f5d995ea --- /dev/null +++ b/.template/addons/github/.github/wiki/Home.md @@ -0,0 +1 @@ +> *Insert information about your project here!* diff --git a/.template/addons/github/.github/wiki/_Footer.md b/.template/addons/github/.github/wiki/_Footer.md new file mode 100644 index 00000000..3eac4808 --- /dev/null +++ b/.template/addons/github/.github/wiki/_Footer.md @@ -0,0 +1 @@ +**Developed by [Nimble](https://nimblehq.co/)** diff --git a/.template/addons/github/.github/wiki/_Sidebar.md b/.template/addons/github/.github/wiki/_Sidebar.md new file mode 100644 index 00000000..ba66e2ec --- /dev/null +++ b/.template/addons/github/.github/wiki/_Sidebar.md @@ -0,0 +1,16 @@ +## Table of Contents + +- [[Home]] +- [[Getting Started]] + +## Architecture + +- [[Authentication]] + +## Infrastructure + +- [[CI/CD|CI CD]] + +## Operations + +- [[Testing]] diff --git a/.template/addons/github/.github/wiki/assets/images/.keep b/.template/addons/github/.github/wiki/assets/images/.keep new file mode 100644 index 00000000..e69de29b diff --git a/.template/addons/github/.github/workflows/README.md.tt b/.template/addons/github/.github/workflows/README.md.tt index 5a7b4974..2c9a2dd5 100644 --- a/.template/addons/github/.github/workflows/README.md.tt +++ b/.template/addons/github/.github/workflows/README.md.tt @@ -70,4 +70,4 @@ Once all setup, give it a try by running manually the GitHub Action 'Deploy Hero - Set up the following GitHub repository secrets - GH_EMAIL (an email to identify the bot that publish the wiki content in the git history) - GH_TOKEN (the above generated token) -- Creat a `.github/wiki` directory to store the documents to be published to Wiki. +- Create a `.github/wiki` directory to store the documents to be published to Wiki. diff --git a/.template/addons/github/template.rb b/.template/addons/github/template.rb index cd163e30..c74b169d 100644 --- a/.template/addons/github/template.rb +++ b/.template/addons/github/template.rb @@ -1,3 +1,37 @@ use_source_path __dir__ directory '.github' + +# Split README.md file to multiple wiki pages +original_readme = File.read 'README.md' + +create_file '.github/wiki/Getting-Started.md' do + get_content_between(original_readme, '## Getting Started', '## Testing') +end + +create_file '.github/wiki/Testing.md' do + get_content_between(original_readme, '## Testing', '## CI/CD') +end + +FileUtils.mv '.github/workflows/README.md', '.github/wiki/CI-CD.md' + +gsub_file 'README.md', /## Getting Started.*/m do + <<~README + ## Documentation + + Please check out full documentation on the [wiki](../../wiki). + README +end + +@template_instructions.add( + <<~INSTRUCTION + * Github wiki + + 1. On the repository, create an empty wiki page to init the wiki directory + 2. Pick an account to commit the wiki (your own account or a bot account) + 3. On the selected account, generate the Github token with `repo` scope + 4. Set up secrets + - `GH_EMAIL`: an email of the account + - `GH_TOKEN`: the generated Github token from step 3 + INSTRUCTION +) diff --git a/.template/hooks/before_complete/template.rb b/.template/hooks/before_complete/fix_rubocop.rb similarity index 73% rename from .template/hooks/before_complete/template.rb rename to .template/hooks/before_complete/fix_rubocop.rb index 0e2d8d26..ab77ff79 100644 --- a/.template/hooks/before_complete/template.rb +++ b/.template/hooks/before_complete/fix_rubocop.rb @@ -8,7 +8,7 @@ def fixing_rubocop Layout/EmptyLineAfterMagicComment ).join(',') - run "rubocop --only #{cops} --auto-correct-all" + run "rubocop --only #{cops} --auto-correct-all --out tmp/template_rubocop.txt" end end diff --git a/.template/hooks/before_complete/report.rb b/.template/hooks/before_complete/report.rb new file mode 100644 index 00000000..88c219df --- /dev/null +++ b/.template/hooks/before_complete/report.rb @@ -0,0 +1,27 @@ +def report + after_bundle do + say "\nšŸš€ The project has been successfully created šŸš€\n", :green + + # Report errors + unless @template_errors.empty? + print_separator + say "\nšŸ“ There were some errors when templating the application, please fix them manually:\n" + say_error "\n#{@template_errors}\n" + end + + # Report instructions + unless @template_instructions.empty? + print_separator + say "\nšŸ“ Please follow the instructions below to complete the setup:\n" + say "\n#{@template_instructions}\n" + end + + say "\n" + end +end + +def print_separator(color = nil) + say "\n#{'=' * 80}\n", color +end + +report diff --git a/.template/lib/template.rb b/.template/lib/template.rb new file mode 100644 index 00000000..313d6403 --- /dev/null +++ b/.template/lib/template.rb @@ -0,0 +1,4 @@ +module Template + require_relative 'template/messages' + require_relative 'template/errors' +end diff --git a/.template/lib/template/errors.rb b/.template/lib/template/errors.rb index 283614a9..87728b71 100644 --- a/.template/lib/template/errors.rb +++ b/.template/lib/template/errors.rb @@ -1,21 +1 @@ -module Template - class Errors - delegate :empty?, to: :errors - - def initialize - @errors = [] - end - - def add(error_message) - errors << error_message - end - - def to_s - errors.join("#{'-' * 80}\n") - end - - private - - attr_reader :errors - end -end +class Template::Errors < Template::Messages; end diff --git a/.template/lib/template/messages.rb b/.template/lib/template/messages.rb new file mode 100644 index 00000000..f90aee11 --- /dev/null +++ b/.template/lib/template/messages.rb @@ -0,0 +1,19 @@ +class Template::Messages + delegate :empty?, to: :messages + + def initialize + @messages = [] + end + + def add(message) + messages << message.chomp + end + + def to_s + messages.join("\n\n#{'-' * 80}\n\n") + end + + private + + attr_reader :messages +end diff --git a/.template/spec/addons/base/github/template_spec.rb b/.template/spec/addons/base/github/template_spec.rb index 53fd4bd9..e74d36d3 100644 --- a/.template/spec/addons/base/github/template_spec.rb +++ b/.template/spec/addons/base/github/template_spec.rb @@ -5,7 +5,72 @@ it 'creates Github actions workflows' do expect(file('.github/workflows/deploy_heroku.yml')).to exist + expect(file('.github/workflows/publish_wiki.yml')).to exist + expect(file('.github/workflows/review_code.yml')).to exist expect(file('.github/workflows/test_production_build.yml')).to exist expect(file('.github/workflows/test.yml')).to exist end + + it 'creates Github wiki structure' do + expect(file('.github/wiki/_Sidebar.md')).to exist + expect(file('.github/wiki/_Footer.md')).to exist + expect(file('.github/wiki/Home.md')).to exist + expect(file('.github/wiki/assets/images/.keep')).to exist + end + + # TODO: Can't test this as it is now ignored by `.dockerignore` + xit 'modifies the README.md' do + expect(file('README.md')).to contain("## Documentation") + + expect(file('README.md')).not_to contain("## Getting Started") + expect(file('README.md')).not_to contain("## Testing") + expect(file('README.md')).not_to contain("## CI/CD") + end + + describe '.github/wiki/Getting-Started.md' do + it 'exists' do + expect(file('.github/wiki/Getting-Started.md')).to exist + end + + it 'contains the correct content extracted from README.md' do + expect(file('.github/wiki/Getting-Started.md')).to contain("### Prerequisites") + expect(file('.github/wiki/Getting-Started.md')).to contain("### Docker") + expect(file('.github/wiki/Getting-Started.md')).to contain("### Development") + end + end + + describe '.github/wiki/Authentication.md' do + it 'exists' do + expect(file('.github/wiki/Authentication.md')).to exist + end + end + + describe '.github/wiki/CI-CD.md' do + it 'exists' do + expect(file('.github/wiki/CI-CD.md')).to exist + end + + it 'contains the correct content extracted from the workflow README.md' do + expect(file('.github/wiki/CI-CD.md')).to contain("## Test workflow") + expect(file('.github/wiki/CI-CD.md')).to contain("## Test production build workflow") + expect(file('.github/wiki/CI-CD.md')).to contain("## Deploy to Heroku workflow") + expect(file('.github/wiki/CI-CD.md')).to contain("## Publish to Wiki workflow") + end + + it 'deletes the workflow README.md' do + expect(file('.github/workflow/README.md')).not_to exist + end + end + + describe '.github/wiki/Testing.md' do + it 'exists' do + expect(file('.github/wiki/Testing.md')).to exist + end + + it 'contains the correct content extracted from README.md' do + expect(file('.github/wiki/Testing.md')).to contain("### Docker-based tests on the CI server") + expect(file('.github/wiki/Testing.md')).to contain("### Test") + expect(file('.github/wiki/Testing.md')).to contain("### Automated Code Review Setup") + end + end end diff --git a/Makefile b/Makefile index cdbe841d..2f08dcf8 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,9 @@ +# Y - in response to Would you like to add the Github addon? # Y - in response to Would you like to add the SemaphoreCI addon? # Y - in response to Would you like to add the Nginx addon? # Y - in response to Would you like to add the PhraseApp addon? # Y - in response to Would you like to add the Devise addon? -common_addon_prompts = Y\nY\nY\nY\n +common_addon_prompts = Y\nY\nY\nY\nY\n # Y - in response to Would you like to add the Bootstrap addon? # Y - in response to Would you like to add the Slim Template Engine addon? diff --git a/README.md.tt b/README.md.tt index da1bdaeb..88a215ff 100644 --- a/README.md.tt +++ b/README.md.tt @@ -4,7 +4,7 @@ > *App introduction goes here ...* -## Project Setup +## Getting Started ### Prerequisites @@ -39,7 +39,7 @@ ./bin/dev ``` -## Tests +## Testing ### Docker-based tests on the CI server @@ -88,14 +88,6 @@ docker push $DOCKER_IMAGE:$BRANCH_TAG docker compose -f docker-compose.test.yml run test bin/bundle exec rake db:test:prepare ``` -#### Semaphore CI 2.0 - -To setup the semaphore CI 2.0 for the project, please follow [this guideline](.semaphore/README.md) - -#### Github actions & Heroku Deployment - -To setup Github actions for the project, please follow [this guideline](.github/workflows/README.md) - ### Test - Run all tests: @@ -123,3 +115,9 @@ rspec [rspec-params] - Create a [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) from bot account with `public_repo` scope, and set it as `DANGER_GITHUB_API_TOKEN` secret on the CI Environment Settings. + +## CI/CD + +The project relies entirely on [Github Actions](https://github.com/features/actions) for CI/CD via multiple workflows located under the [`.github/workflows/`](.github/workflows) directory. + +Please check out the [`.github/workflows/README.md`](.github/workflows/README.md) file for further instructions. diff --git a/template.rb b/template.rb index 4ef71eeb..4aac99d4 100644 --- a/template.rb +++ b/template.rb @@ -15,8 +15,7 @@ # Addons DEFAULT_ADDONS = { docker: 'Docker', - heroku: 'Heroku', - github: 'Github along with Github Action' + heroku: 'Heroku' }.freeze if WEB_VARIANT @@ -66,6 +65,7 @@ def apply_template!(template_root) post_default_addons_install # Add-ons - [Optional] + apply '.template/addons/github/template.rb' if yes?(install_addon_prompt('Github Action and Wiki')) apply '.template/addons/semaphore/template.rb' if yes?(install_addon_prompt('SemaphoreCI')) apply '.template/addons/nginx/template.rb' if yes?(install_addon_prompt('Nginx')) apply '.template/addons/phrase_app/template.rb' if yes?(install_addon_prompt('PhraseApp')) @@ -76,7 +76,8 @@ def apply_template!(template_root) apply '.template/variants/web/template.rb' if WEB_VARIANT # A list necessary jobs that run before complete, ex: Fixing rubocop on Ruby files that generated by Rails - apply '.template/hooks/before_complete/template.rb' + apply '.template/hooks/before_complete/fix_rubocop.rb' + apply '.template/hooks/before_complete/report.rb' end # Set Thor::Actions source path for looking up the files @@ -115,17 +116,6 @@ def install_addon_prompt(addon) "Would you like to add the #{addon} addon? [Yn]" end -def print_error_message - puts <<~EOT - #{'=' * 80} - - There are some errors when templating the application, Please fix them manually: - - #{@template_errors} - #{'=' * 80} - EOT -end - def post_default_addons_install addons = "" DEFAULT_ADDONS.each_value do |addon| @@ -138,6 +128,10 @@ def post_default_addons_install EOT end +def get_content_between(content, string_start, string_end) + content[/#{Regexp.escape(string_start)}(.*)#{Regexp.escape(string_end)}/m, 1].strip +end + # Init the source path @source_paths ||= [] @@ -146,8 +140,10 @@ def post_default_addons_install template_root = __FILE__ =~ %r{\Ahttps?://} ? remote_repository : __dir__ use_source_path template_root -# Init the template errors -require "#{template_root}/.template/lib/template/errors" +# Init the template helpers +require "#{template_root}/.template/lib/template" + +@template_instructions = Template::Messages.new @template_errors = Template::Errors.new if ENV['ADDON'] @@ -159,5 +155,3 @@ def post_default_addons_install else apply_template!(template_root) end - -print_error_message unless @template_errors.empty? From 0e40c04eaee851257a4c19478a15337e1ba04086 Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Wed, 16 Mar 2022 10:41:15 +0700 Subject: [PATCH 11/13] Refactor heredoc (#319) * Refactor heredoc * Fix lint warning * Add README and update heredocs on the main template file --- .gitignore.rb | 14 +++--- .template/addons/devise/Gemfile.rb | 8 +-- .template/addons/devise/spec_support.rb | 12 ++--- .../nginx/bin/{start.sh => start.sh.rb} | 8 +-- .template/addons/nginx/bin/template.rb | 2 +- .template/addons/nginx/docker.rb | 8 +-- .../phrase_app/spec/codebase/codebase_spec.rb | 34 ++++++------- .template/addons/slim/Dangerfile.rb | 4 +- .template/addons/slim/Gemfile.rb | 8 +-- .../config/environments/development_spec.rb | 8 +-- .../config/environments/production_spec.rb | 20 ++++---- .../base/config/environments/test_spec.rb | 8 +-- .../web/spec/codebase/codebase_spec.rb | 8 +-- .template/variants/api/app/template.rb | 6 +-- .template/variants/web/.gitignore.rb | 4 +- .template/variants/web/.tool-versions.rb | 4 +- .template/variants/web/Dangerfile.rb | 4 +- .template/variants/web/Gemfile.rb | 20 ++++---- .template/variants/web/Procfile.dev.rb | 4 +- .template/variants/web/app/template.rb | 16 +++--- .template/variants/web/config/application.rb | 6 +-- .../variants/web/config/environments/test.rb | 18 +++---- .../web/config/initializers/assets.rb | 4 +- .template/variants/web/package.json.rb | 4 +- .../web/spec/codebase/codebase_spec.rb | 16 +++--- .../web/spec/support/disable_animation.rb | 49 +++++++++---------- README.md | 23 +++++++++ config/application.rb | 12 ++--- config/environments/development.rb | 38 +++++++------- config/environments/production.rb | 24 ++++----- config/environments/test.rb | 32 ++++++------ template.rb | 8 +-- 32 files changed, 227 insertions(+), 207 deletions(-) rename .template/addons/nginx/bin/{start.sh => start.sh.rb} (62%) diff --git a/.gitignore.rb b/.gitignore.rb index 13be93ac..afa2dbe0 100644 --- a/.gitignore.rb +++ b/.gitignore.rb @@ -1,11 +1,11 @@ append_to_file '.gitignore' do - <<~EOT + <<~IGNORE - # Ignore folder information and IDE-specific files - .DS_Store - .idea/* + # Ignore folder information and IDE-specific files + .DS_Store + .idea/* - # Ignore the test coverage results from SimpleCov - /coverage - EOT + # Ignore the test coverage results from SimpleCov + /coverage + IGNORE end diff --git a/.template/addons/devise/Gemfile.rb b/.template/addons/devise/Gemfile.rb index 888cce90..dc48a1bf 100644 --- a/.template/addons/devise/Gemfile.rb +++ b/.template/addons/devise/Gemfile.rb @@ -1,11 +1,11 @@ insert_into_file 'Gemfile', after: /# Authentications & Authorizations.*\n/ do - <<~GEM + <<~RUBY gem 'devise' # Authentication solution for Rails with Warden - GEM + RUBY end insert_into_file 'Gemfile', after: /# Translations.*\n/ do - <<~GEM + <<~RUBY # gem 'devise-i18n' # Translations for Devise - GEM + RUBY end diff --git a/.template/addons/devise/spec_support.rb b/.template/addons/devise/spec_support.rb index b0b0956b..c005273e 100644 --- a/.template/addons/devise/spec_support.rb +++ b/.template/addons/devise/spec_support.rb @@ -1,6 +1,6 @@ -file 'spec/support/devise.rb', <<-CODE -RSpec.configure do |config| - config.include Devise::Test::ControllerHelpers, type: :controller - config.include Devise::Test::ControllerHelpers, type: :view -end -CODE +file 'spec/support/devise.rb', <<~RUBY + RSpec.configure do |config| + config.include Devise::Test::ControllerHelpers, type: :controller + config.include Devise::Test::ControllerHelpers, type: :view + end +RUBY diff --git a/.template/addons/nginx/bin/start.sh b/.template/addons/nginx/bin/start.sh.rb similarity index 62% rename from .template/addons/nginx/bin/start.sh rename to .template/addons/nginx/bin/start.sh.rb index 8b66bbd5..9ea8cce4 100755 --- a/.template/addons/nginx/bin/start.sh +++ b/.template/addons/nginx/bin/start.sh.rb @@ -1,10 +1,10 @@ insert_into_file 'bin/start.sh', after: "fi\n" do - <<-EOT + <<~SHELL -./bin/inject_port_into_nginx.sh + ./bin/inject_port_into_nginx.sh -nginx -c /etc/nginx/conf.d/default.conf - EOT + nginx -c /etc/nginx/conf.d/default.conf + SHELL end gsub_file('bin/start.sh', 'bundle exec rails s -p $PORT -b 0.0.0.0', 'bundle exec rails s -p 3000 -b 0.0.0.0') diff --git a/.template/addons/nginx/bin/template.rb b/.template/addons/nginx/bin/template.rb index 6a5b6ee9..efb46c5b 100644 --- a/.template/addons/nginx/bin/template.rb +++ b/.template/addons/nginx/bin/template.rb @@ -1,4 +1,4 @@ use_source_path __dir__ -apply 'start.sh' +apply 'start.sh.rb' copy_file 'bin/inject_port_into_nginx.sh', mode: :preserve diff --git a/.template/addons/nginx/docker.rb b/.template/addons/nginx/docker.rb index c2d3c020..4ad76fe0 100644 --- a/.template/addons/nginx/docker.rb +++ b/.template/addons/nginx/docker.rb @@ -3,11 +3,11 @@ end insert_into_file 'Dockerfile', after: %r(WORKDIR.+\n) do - <<-EOT + <<~DOCKERFILE -# Nginx config -COPY config/nginx/app.conf.template /etc/nginx/conf.d/default.conf - EOT + # Nginx config + COPY config/nginx/app.conf.template /etc/nginx/conf.d/default.conf + DOCKERFILE end gsub_file 'Dockerfile', /PORT=80/ do diff --git a/.template/addons/phrase_app/spec/codebase/codebase_spec.rb b/.template/addons/phrase_app/spec/codebase/codebase_spec.rb index edd21fee..60352876 100644 --- a/.template/addons/phrase_app/spec/codebase/codebase_spec.rb +++ b/.template/addons/phrase_app/spec/codebase/codebase_spec.rb @@ -1,21 +1,21 @@ insert_into_file 'spec/codebase/codebase_spec.rb', before: %r{end\Z} do - <<-EOT + <<~RUBY.indent(2) - # rubocop:disable RSpec/ExampleLength - it 'does not offend PhraseApp Pull configuration' do - locale_tags = Dir[File.expand_path(Rails.root.join('config', 'locales', '*.yml'))] - .map { |path| path.split('/').last } # ["campaign.en.yml", "article.en.yml", "campaign.th.yml"] - .map { |path| path.split('.').first } # ["campaign", "article", "campaign"] - .uniq # ["campaign", "article"] - .sort # ["article", "campaign"] - phrase_app_pull_tags = YAML - .load_file(Rails.root.join('.phraseapp.yml')) - .dig('phraseapp', 'pull', 'targets') - .map { |target| target.dig('params', 'tags') } - .sort + # rubocop:disable RSpec/ExampleLength + it 'does not offend PhraseApp Pull configuration' do + locale_tags = Dir[File.expand_path(Rails.root.join('config', 'locales', '*.yml'))] + .map { |path| path.split('/').last } # ["campaign.en.yml", "article.en.yml", "campaign.th.yml"] + .map { |path| path.split('.').first } # ["campaign", "article", "campaign"] + .uniq # ["campaign", "article"] + .sort # ["article", "campaign"] + phrase_app_pull_tags = YAML + .load_file(Rails.root.join('.phraseapp.yml')) + .dig('phraseapp', 'pull', 'targets') + .map { |target| target.dig('params', 'tags') } + .sort - expect(phrase_app_pull_tags).to eq locale_tags - end - # rubocop:enable RSpec/ExampleLength - EOT + expect(phrase_app_pull_tags).to eq locale_tags + end + # rubocop:enable RSpec/ExampleLength + RUBY end diff --git a/.template/addons/slim/Dangerfile.rb b/.template/addons/slim/Dangerfile.rb index 52fbdcf0..291eda92 100644 --- a/.template/addons/slim/Dangerfile.rb +++ b/.template/addons/slim/Dangerfile.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true insert_into_file 'Dangerfile', after: /eslint.lint.*\n/ do - <<~DANGER_PLUGIN + <<~RUBY # Runs slim-lint on modified and added files in the PR slim_lint.lint - DANGER_PLUGIN + RUBY end diff --git a/.template/addons/slim/Gemfile.rb b/.template/addons/slim/Gemfile.rb index 82b54af1..879265d5 100644 --- a/.template/addons/slim/Gemfile.rb +++ b/.template/addons/slim/Gemfile.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true insert_into_file 'Gemfile', after: /gem 'pundit'.*\n/ do - <<~GEM + <<~RUBY # Templating gem 'slim' # light weight template engine - GEM + RUBY end ############################ @@ -13,7 +13,7 @@ ############################ insert_into_file 'Gemfile', after: /gem 'danger'.*\n/ do - <<~GEM.indent(2) + <<~RUBY.indent(2) gem 'danger-slim_lint' # Lint slim files. - GEM + RUBY end diff --git a/.template/spec/base/config/environments/development_spec.rb b/.template/spec/base/config/environments/development_spec.rb index 949e6907..5743b4da 100644 --- a/.template/spec/base/config/environments/development_spec.rb +++ b/.template/spec/base/config/environments/development_spec.rb @@ -20,16 +20,16 @@ private def mailer_default_url_config - <<~EOT + <<~RUBY config.action_mailer.default_url_options = { host: ENV.fetch('MAILER_DEFAULT_HOST'), port: ENV.fetch('MAILER_DEFAULT_PORT') } - EOT + RUBY end def bullet_config - <<~EOT + <<~RUBY # Configure Bullet gem to detect N+1 queries config.after_initialize do Bullet.enable = true @@ -38,6 +38,6 @@ def bullet_config Bullet.rails_logger = true Bullet.add_footer = true end - EOT + RUBY end end diff --git a/.template/spec/base/config/environments/production_spec.rb b/.template/spec/base/config/environments/production_spec.rb index 5a43eb00..003ab918 100644 --- a/.template/spec/base/config/environments/production_spec.rb +++ b/.template/spec/base/config/environments/production_spec.rb @@ -8,36 +8,36 @@ it 'configures the mailer default url options' do expect(subject).to contain(mailer_default_url_config) end - + it 'adds the i18n configuration' do expect(subject).to contain(i18n_config) end - + it 'removes the config.i18n.fallbacks = true' do expect(subject).not_to contain("config.i18n.fallbacks = true") end - + private def mailer_default_url_config - <<~EOT + <<~RUBY config.action_mailer.default_url_options = { host: ENV.fetch('MAILER_DEFAULT_HOST'), port: ENV.fetch('MAILER_DEFAULT_PORT') } - EOT + RUBY end - + def i18n_config - <<~EOT + <<~RUBY # eg: AVAILABLE_LOCALES = 'en,th' config.i18n.available_locales = ENV.fetch('AVAILABLE_LOCALES').split(',') - + # eg: DEFAULT_LOCALE = 'en' config.i18n.default_locale = ENV.fetch('DEFAULT_LOCALE') - + # eg: FALLBACK_LOCALES = 'en,th' config.i18n.fallbacks = ENV.fetch('FALLBACK_LOCALES').split(',') - EOT + RUBY end end diff --git a/.template/spec/base/config/environments/test_spec.rb b/.template/spec/base/config/environments/test_spec.rb index 5b9fe64c..70d9df39 100644 --- a/.template/spec/base/config/environments/test_spec.rb +++ b/.template/spec/base/config/environments/test_spec.rb @@ -12,16 +12,16 @@ private def mailer_default_url_config - <<~EOT + <<~RUBY config.action_mailer.default_url_options = { host: ENV.fetch('MAILER_DEFAULT_HOST'), port: ENV.fetch('MAILER_DEFAULT_PORT') } - EOT + RUBY end def bullet_config - <<~EOT + <<~RUBY # Configure Bullet gem to detect N+1 queries config.after_initialize do Bullet.enable = true @@ -29,6 +29,6 @@ def bullet_config Bullet.raise = true Bullet.unused_eager_loading_enable = false end - EOT + RUBY end end diff --git a/.template/spec/variants/web/spec/codebase/codebase_spec.rb b/.template/spec/variants/web/spec/codebase/codebase_spec.rb index 174278f1..43adf8ec 100644 --- a/.template/spec/variants/web/spec/codebase/codebase_spec.rb +++ b/.template/spec/variants/web/spec/codebase/codebase_spec.rb @@ -12,18 +12,18 @@ private def scss_lint_example - <<~EOT + <<~RUBY it 'does not offend stylelint' do expect(`yarn run stylelint ./`).to be_empty end - EOT + RUBY end def eslint_example - <<~EOT + <<~RUBY it 'does not offend eslint' do expect(`yarn run eslint ./`).to include 'Done' end - EOT + RUBY end end diff --git a/.template/variants/api/app/template.rb b/.template/variants/api/app/template.rb index 79eacc3c..e5e5006c 100644 --- a/.template/variants/api/app/template.rb +++ b/.template/variants/api/app/template.rb @@ -1,7 +1,7 @@ # Controllers directory 'app/controllers/concerns' inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController' do - <<-EOT - include Localization - EOT + <<~RUBY.indent(2) + include Localization + RUBY end diff --git a/.template/variants/web/.gitignore.rb b/.template/variants/web/.gitignore.rb index 65e2ca70..3a8e1f0e 100644 --- a/.template/variants/web/.gitignore.rb +++ b/.template/variants/web/.gitignore.rb @@ -1,5 +1,5 @@ append_to_file '.gitignore' do - <<~EOT + <<~IGNORE # Ignore i18n.js generated files # If deploy to heroku with git, please remove this as it prevents the files to be committed /app/javascript/translations/* @@ -9,5 +9,5 @@ # Ignore Node dependencies /node_modules - EOT + IGNORE end diff --git a/.template/variants/web/.tool-versions.rb b/.template/variants/web/.tool-versions.rb index d365065c..1b7ca2b1 100644 --- a/.template/variants/web/.tool-versions.rb +++ b/.template/variants/web/.tool-versions.rb @@ -1,5 +1,5 @@ append_to_file '.tool-versions' do - <<~EOT + <<~TOOL_VERSION nodejs #{NODE_VERSION} - EOT + TOOL_VERSION end diff --git a/.template/variants/web/Dangerfile.rb b/.template/variants/web/Dangerfile.rb index 82d6d52f..dda7c829 100644 --- a/.template/variants/web/Dangerfile.rb +++ b/.template/variants/web/Dangerfile.rb @@ -1,7 +1,7 @@ insert_into_file 'Dangerfile', after: %r{suggester.suggest.*\n} do - <<~EOT + <<~RUBY # Runs ESLint on modified and added files in the PR eslint.lint - EOT + RUBY end diff --git a/.template/variants/web/Gemfile.rb b/.template/variants/web/Gemfile.rb index d670ac94..bcbedf77 100644 --- a/.template/variants/web/Gemfile.rb +++ b/.template/variants/web/Gemfile.rb @@ -1,11 +1,11 @@ insert_into_file 'Gemfile', after: %r{gem 'rails-i18n'.*\n} do - <<~EOT + <<~RUBY gem 'i18n-js', '3.9.0' # A library to provide the I18n translations on the Javascript - EOT + RUBY end insert_into_file 'Gemfile', after: %r{gem 'pundit'.*\n} do - <<~EOT + <<~RUBY # Assets gem 'sprockets-rails' # The original asset pipeline for Rails @@ -14,7 +14,7 @@ # gem 'turbo-rails' # Hotwire's SPA-like page accelerator # gem 'stimulus-rails' # Hotwire's modest JavaScript framework # gem 'image_processing' # Use Active Storage variants - EOT + RUBY end ############################ @@ -22,15 +22,15 @@ ############################ insert_into_file 'Gemfile', after: %r{gem 'danger'.*\n} do - <<~EOT.indent(2) + <<~RUBY.indent(2) gem 'danger-eslint' # ESLint - EOT + RUBY end insert_into_file 'Gemfile', after: %r{gem 'spring-watcher-listen'.*\n} do - <<~EOT.indent(2) + <<~RUBY.indent(2) # gem 'web-console' # Use console on exceptions pages - EOT + RUBY end ############## @@ -38,9 +38,9 @@ ############## insert_into_file 'Gemfile', after: %r{gem 'rspec-retry'.*\n} do - <<~EOT.indent(2) + <<~RUBY.indent(2) gem 'capybara' # Integration testing gem 'selenium-webdriver' # Ruby bindings for Selenium/WebDriver gem 'webdrivers' # Run Selenium tests more easily with automatic installation and updates for all supported webdrivers - EOT + RUBY end diff --git a/.template/variants/web/Procfile.dev.rb b/.template/variants/web/Procfile.dev.rb index 780aedfe..ea2c2e0a 100644 --- a/.template/variants/web/Procfile.dev.rb +++ b/.template/variants/web/Procfile.dev.rb @@ -1,6 +1,6 @@ append_to_file 'Procfile.dev' do - <<~EOT + <<~PROCFILE js: yarn build --watch css: yarn build:css --watch - EOT + PROCFILE end diff --git a/.template/variants/web/app/template.rb b/.template/variants/web/app/template.rb index d68c6bab..3ce9983c 100644 --- a/.template/variants/web/app/template.rb +++ b/.template/variants/web/app/template.rb @@ -3,15 +3,15 @@ if File.exist?('app/views/layouts/application.html.erb') insert_into_file 'app/views/layouts/application.html.erb', before: %r{} do - <<~EOT.indent(2) + <<~ERB.indent(2) <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> - EOT + ERB end else - @template_errors.add <<~EOT + @template_errors.add <<~ERROR Cannot include javascript into `app/views/layouts/application.html.erb` Content: <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %> - EOT + ERROR end # Stylesheets @@ -25,9 +25,9 @@ # I18n directory 'app/controllers/concerns' inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController' do - <<~EOT.indent(2) + <<~RUBY.indent(2) include Localization - EOT + RUBY end if File.exist?('app/views/layouts/application.html.erb') @@ -35,8 +35,8 @@ "" end else - @template_errors.add <<~EOT + @template_errors.add <<~ERROR Cannot insert the lang attribute into html tag into `app/views/layouts/application.html.erb` Content: - EOT + ERROR end diff --git a/.template/variants/web/config/application.rb b/.template/variants/web/config/application.rb index d46b1307..52bea7fa 100644 --- a/.template/variants/web/config/application.rb +++ b/.template/variants/web/config/application.rb @@ -1,7 +1,7 @@ -insert_into_file 'config/application.rb', before: %r{end\nend\Z} do - <<-EOT +insert_into_file 'config/application.rb', before: %r{ end\nend\Z} do + <<~RUBY.indent(4) # Automatically generate the `translation.js` files config.middleware.use I18n::JS::Middleware - EOT + RUBY end diff --git a/.template/variants/web/config/environments/test.rb b/.template/variants/web/config/environments/test.rb index 1464794b..4320779c 100644 --- a/.template/variants/web/config/environments/test.rb +++ b/.template/variants/web/config/environments/test.rb @@ -1,17 +1,17 @@ insert_into_file 'config/environments/test.rb', before: %r{Rails.application.configure do} do - <<~EOT - require_relative '../../spec/support/disable_animation' + <<~RUBY + require_relative '../../spec/support/disable_animation' - EOT + RUBY end insert_into_file 'config/environments/test.rb', before: %r{^end} do - <<-EOT + <<~RUBY.indent(2) - # Disable all animation during tests - config.middleware.use Rack::NoAnimations + # Disable all animation during tests + config.middleware.use Rack::NoAnimations - # Do not fallback to assets pipeline if a precompiled asset is missing. - config.assets.compile = false - EOT + # Do not fallback to assets pipeline if a precompiled asset is missing. + config.assets.compile = false + RUBY end diff --git a/.template/variants/web/config/initializers/assets.rb b/.template/variants/web/config/initializers/assets.rb index 4f8bee4c..9e7adc5d 100644 --- a/.template/variants/web/config/initializers/assets.rb +++ b/.template/variants/web/config/initializers/assets.rb @@ -1,7 +1,7 @@ append_to_file 'config/initializers/assets.rb' do - <<~EOT + <<~RUBY # Add Yarn node_modules folder to the asset load path. Rails.application.config.assets.paths << Rails.root.join('node_modules') - EOT + RUBY end diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index 0f594889..d124d820 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -1,12 +1,12 @@ # Create package.json file unless File.exist?('package.json') create_file 'package.json', - <<~EOT + <<~JSON { "name": "#{APP_NAME}", "private": "true" } - EOT + JSON end # Install dependencies diff --git a/.template/variants/web/spec/codebase/codebase_spec.rb b/.template/variants/web/spec/codebase/codebase_spec.rb index 7c5d0a68..707a5905 100644 --- a/.template/variants/web/spec/codebase/codebase_spec.rb +++ b/.template/variants/web/spec/codebase/codebase_spec.rb @@ -1,12 +1,12 @@ insert_into_file 'spec/codebase/codebase_spec.rb', before: %r{end\Z} do - <<-EOT + <<~RUBY.indent(2) - it 'does not offend stylelint' do - expect(`yarn run stylelint`).to include 'Done' - end + it 'does not offend stylelint' do + expect(`yarn run stylelint`).to include 'Done' + end - it 'does not offend eslint' do - expect(`yarn run eslint`).to include 'Done' - end - EOT + it 'does not offend eslint' do + expect(`yarn run eslint`).to include 'Done' + end + RUBY end diff --git a/.template/variants/web/spec/support/disable_animation.rb b/.template/variants/web/spec/support/disable_animation.rb index 00632a31..2427969b 100644 --- a/.template/variants/web/spec/support/disable_animation.rb +++ b/.template/variants/web/spec/support/disable_animation.rb @@ -27,35 +27,32 @@ def html? end # rubocop:disable Metrics/MethodLength - # rubocop:disable Naming/HeredocDelimiterNaming - # rubocop:disable Layout/HeredocIndentation def inject(fragment) - disable_animations = <<-EOF - - - EOF + disable_animations = <<~HTML + + + HTML + fragment.gsub(%r{}, "#{disable_animations}") end # rubocop:enable Metrics/MethodLength - # rubocop:enable Naming/HeredocDelimiterNaming - # rubocop:enable Layout/HeredocIndentation end end diff --git a/README.md b/README.md index 76d05196..fda3d101 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,29 @@ Test files are located under `.template/spec` folder ā”‚ ā”‚ ā”‚ ā”‚ ā””ā”€ā”€ template_spec.rb ``` +### Template Strings + +When using template string with heredoc, use the proper name following the file type / content. + +This provides the meaningful context to the content and some IDEs also support to highlight the content depending on the type. + +- `DOCKERFILE` +- `ERB` +- `HTML` +- `IGNORE` - For any ignore file e.g. `.gitignore`, `.eslintignore` +- `JAVASCRIPT` +- `JSON` +- `PROCFILE` +- `RUBY` +- `SCSS` +- `SHELL` + +For other files that are not fit the types above, use the extension as the name +e.g. `TOOL_VERSION` for `.tool-version` file. + +For the normal string, name it after the content +e.g. `ERROR` for template error message. + ## License This project is Copyright (c) 2014 and onwards. It is free software, diff --git a/config/application.rb b/config/application.rb index 94eeae75..a0257e42 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,8 +1,8 @@ -insert_into_file 'config/application.rb', before: %r{end\nend\Z} do - <<-EOT - +insert_into_file 'config/application.rb', before: %r{ end\nend\Z} do + <<~RUBY.indent(4) + # Set the queuing backend to `Sidekiq` - # + # # Be sure to have the adapter's gem in your Gemfile # and follow the adapter's specific installation # and deployment instructions. @@ -10,8 +10,8 @@ # Prefix the queue name of all jobs with Rails ENV config.active_job.queue_name_prefix = Rails.env - + # Compress the responses to reduce the size of html/json controller responses. config.middleware.use Rack::Deflater - EOT + RUBY end diff --git a/config/environments/development.rb b/config/environments/development.rb index 3b6a6e1e..1ce84222 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,27 +1,27 @@ insert_into_file 'config/environments/development.rb', after: %r{config.action_mailer.perform_caching.+\n} do - <<-EOT + <<~RUBY.indent(2) - config.action_mailer.delivery_method = :letter_opener + config.action_mailer.delivery_method = :letter_opener - config.action_mailer.asset_host = ENV.fetch('MAILER_DEFAULT_HOST') + config.action_mailer.asset_host = ENV.fetch('MAILER_DEFAULT_HOST') - config.action_mailer.default_url_options = { - host: ENV.fetch('MAILER_DEFAULT_HOST'), - port: ENV.fetch('MAILER_DEFAULT_PORT') - } - EOT + config.action_mailer.default_url_options = { + host: ENV.fetch('MAILER_DEFAULT_HOST'), + port: ENV.fetch('MAILER_DEFAULT_PORT') + } + RUBY end insert_into_file 'config/environments/development.rb', before: %r{^end} do - <<-EOT - - # Configure Bullet gem to detect N+1 queries - config.after_initialize do - Bullet.enable = true - Bullet.bullet_logger = true - Bullet.console = true - Bullet.rails_logger = true - Bullet.add_footer = true - end - EOT + <<~RUBY.indent(2) + + # Configure Bullet gem to detect N+1 queries + config.after_initialize do + Bullet.enable = true + Bullet.bullet_logger = true + Bullet.console = true + Bullet.rails_logger = true + Bullet.add_footer = true + end + RUBY end diff --git a/config/environments/production.rb b/config/environments/production.rb index 92555b19..30c0023c 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -2,15 +2,15 @@ gsub_file('config/environments/production.rb', "ENV['RAILS_SERVE_STATIC_FILES'].present?", 'true') insert_into_file 'config/environments/production.rb', after: %r{config.action_mailer.perform_caching.+\n} do - <<-EOT + <<~RUBY.indent(2) - config.action_mailer.asset_host = ENV.fetch('MAILER_DEFAULT_HOST') + config.action_mailer.asset_host = ENV.fetch('MAILER_DEFAULT_HOST') - config.action_mailer.default_url_options = { - host: ENV.fetch('MAILER_DEFAULT_HOST'), - port: ENV.fetch('MAILER_DEFAULT_PORT') - } - EOT + config.action_mailer.default_url_options = { + host: ENV.fetch('MAILER_DEFAULT_HOST'), + port: ENV.fetch('MAILER_DEFAULT_PORT') + } + RUBY end # Remove the incorrect fallback configuration (was generated by Rails) @@ -19,15 +19,15 @@ # Adding the correct fallback configuration along with default locale and available locales environment do - <<~EOT + <<~RUBY # eg: AVAILABLE_LOCALES = 'en,th' config.i18n.available_locales = ENV.fetch('AVAILABLE_LOCALES').split(',') - + # eg: DEFAULT_LOCALE = 'en' config.i18n.default_locale = ENV.fetch('DEFAULT_LOCALE') - + # eg: FALLBACK_LOCALES = 'en,th' config.i18n.fallbacks = ENV.fetch('FALLBACK_LOCALES').split(',') - - EOT + + RUBY end diff --git a/config/environments/test.rb b/config/environments/test.rb index fd019fb9..b9b7d50c 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,22 +1,22 @@ insert_into_file 'config/environments/test.rb', after: %r{config.action_mailer.perform_caching.+\n} do - <<-EOT + <<~RUBY.indent(2) - config.action_mailer.default_url_options = { - host: ENV.fetch('MAILER_DEFAULT_HOST'), - port: ENV.fetch('MAILER_DEFAULT_PORT') - } - EOT + config.action_mailer.default_url_options = { + host: ENV.fetch('MAILER_DEFAULT_HOST'), + port: ENV.fetch('MAILER_DEFAULT_PORT') + } + RUBY end insert_into_file 'config/environments/test.rb', before: %r{^end} do - <<-EOT - - # Configure Bullet gem to detect N+1 queries - config.after_initialize do - Bullet.enable = true - Bullet.bullet_logger = true - Bullet.raise = true - Bullet.unused_eager_loading_enable = false - end - EOT + <<~RUBY.indent(2) + + # Configure Bullet gem to detect N+1 queries + config.after_initialize do + Bullet.enable = true + Bullet.bullet_logger = true + Bullet.raise = true + Bullet.unused_eager_loading_enable = false + end + RUBY end diff --git a/template.rb b/template.rb index 4aac99d4..1e3eecf3 100644 --- a/template.rb +++ b/template.rb @@ -122,10 +122,10 @@ def post_default_addons_install addons << "* #{addon}\n " end - puts <<-EOT - These default addons were installed: - #{addons} - EOT + puts <<~INFO + These default addons were installed: + #{addons} + INFO end def get_content_between(content, string_start, string_end) From 43311cb2077d765399c03115543ce1063f1e8832 Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Mon, 21 Mar 2022 14:00:23 +0700 Subject: [PATCH 12/13] Set up Rubocop for the template (#320) * Setup rubocop and fix warnings * Add template rubocop script * Fix rubocop warnings and adjust rubocop config * wip * Fix failed tests * Update readme * Revert workflow trigger * Update readme * Update target ruby version to 3 * Update readme --- .bundle/config | 2 + .github/workflows/test_template.yml | 42 +++++++++++++++ .rubocop.yml | 4 +- .template/.rubocop.yml | 53 +++++++++++++++++++ .template/Gemfile | 3 +- .template/Gemfile.lock | 21 ++++++++ .template/addons/nginx/docker.rb | 2 +- .template/addons/phrase_app/template.rb | 2 +- .template/bin/rubocop | 3 ++ .../hooks/before_complete/fix_rubocop.rb | 4 +- .template/lib/template/errors.rb | 2 + .template/lib/template/messages.rb | 2 + .../spec/addons/base/github/template_spec.rb | 28 +++++----- .../spec/addons/base/phrase_app/template.rb | 2 +- .../controllers/concerns/localization_spec.rb | 2 +- .../config/environments/production_spec.rb | 2 +- .template/variants/web/.gitignore.rb | 14 ++--- .template/variants/web/package.json.rb | 9 +++- README.md | 21 +++++++- bin/docker-prepare | 4 +- spec/rails_helper.rb | 2 +- template.rb | 8 +-- 22 files changed, 191 insertions(+), 41 deletions(-) create mode 100644 .bundle/config create mode 100644 .github/workflows/test_template.yml create mode 100644 .template/.rubocop.yml create mode 100755 .template/bin/rubocop diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 00000000..9c6dba45 --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_GEMFILE: ".template/Gemfile" diff --git a/.github/workflows/test_template.yml b/.github/workflows/test_template.yml new file mode 100644 index 00000000..20ae608a --- /dev/null +++ b/.github/workflows/test_template.yml @@ -0,0 +1,42 @@ +name: Test Template + +on: push + +env: + RUBY_VERSION: 3.0.1 + +jobs: + test: + name: Test template + runs-on: ubuntu-latest + + steps: + - name: Cancel previous runs + uses: styfle/cancel-workflow-action@0.6.0 + with: + access_token: ${{ github.token }} + + - name: Checkout Repository + uses: actions/checkout@v2.3.4 + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ env.RUBY_VERSION }} + bundler-cache: true + + - name: Cache gems + uses: actions/cache@v2 + with: + path: vendor/bundle + key: ${{ runner.os }}-template-${{ env.RUBY_VERSION }}-${{ hashFiles('**/Gemfile.lock') }} + restore-keys: | + ${{ runner.os }}-template-${{ env.RUBY_VERSION }}- + + - name: Install gems + run: | + bundle config path vendor/bundle + bundle install --jobs 4 --retry 3 + + - name: Run RuboCop + run: bundle exec rubocop --config .template/.rubocop.yml --parallel diff --git a/.rubocop.yml b/.rubocop.yml index b60c529c..db34c042 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,4 @@ -require: +require: - rubocop-rails - rubocop-rspec - rubocop-performance @@ -15,7 +15,7 @@ AllCops: - 'node_modules/**/*' - 'config/**/*' - 'tmp/**/*' - TargetRubyVersion: 2.7 + TargetRubyVersion: 3 NewCops: enable Style/Documentation: diff --git a/.template/.rubocop.yml b/.template/.rubocop.yml new file mode 100644 index 00000000..a7831f9c --- /dev/null +++ b/.template/.rubocop.yml @@ -0,0 +1,53 @@ +AllCops: + NewCops: enable + TargetRubyVersion: 3 + Exclude: + - 'vendor/**/*' + +Lint/NonDeterministicRequireOrder: + Exclude: + - '../spec/rails_helper.rb' + +Metrics/MethodLength: + Exclude: + - '../template.rb' + - '**/template.rb' + - 'hooks/**/*' + +Metrics/AbcSize: + Enabled: false + +Metrics/BlockLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Exclude: + - '../template.rb' + - '**/template.rb' + +Metrics/PerceivedComplexity: + Exclude: + - '../template.rb' + - '**/template.rb' + +Naming/FileName: + Enabled: false + +Style/Documentation: + Enabled: false + +Style/FrozenStringLiteralComment: + Enabled: false + +# TODO: Enable this rule later +Style/GlobalVars: + Enabled: false + +# TODO: Enable this rule later +Style/RegexpLiteral: + Enabled: false + +Style/TrivialAccessors: + Exclude: + - '../template.rb' + - '**/template.rb' diff --git a/.template/Gemfile b/.template/Gemfile index 06558bb4..9bf79d1f 100644 --- a/.template/Gemfile +++ b/.template/Gemfile @@ -1,6 +1,7 @@ source 'https://rubygems.org' +gem 'docker-api' # A lightweight Ruby client for the Docker Remote API gem 'rspec' # BDD for Ruby gem 'rspec-wait' # Wait for conditions in RSpec +gem 'rubocop', require: false # A Ruby static code analyzer and formatter, based on the community Ruby style guide. gem 'serverspec' # RSpec tests for your servers -gem 'docker-api' # A lightweight Ruby client for the Docker Remote API diff --git a/.template/Gemfile.lock b/.template/Gemfile.lock index bc472589..0b460254 100644 --- a/.template/Gemfile.lock +++ b/.template/Gemfile.lock @@ -1,6 +1,7 @@ GEM remote: https://rubygems.org/ specs: + ast (2.4.2) diff-lcs (1.4.4) docker-api (2.2.0) excon (>= 0.47.0) @@ -11,6 +12,12 @@ GEM net-ssh (>= 2.6.5, < 7.0.0) net-ssh (6.1.0) net-telnet (0.1.1) + parallel (1.21.0) + parser (3.1.0.0) + ast (~> 2.4.1) + rainbow (3.1.1) + regexp_parser (2.2.0) + rexml (3.2.5) rspec (3.9.0) rspec-core (~> 3.9.0) rspec-expectations (~> 3.9.0) @@ -29,6 +36,18 @@ GEM rspec-support (3.9.3) rspec-wait (0.0.9) rspec (>= 3, < 4) + rubocop (1.25.0) + parallel (~> 1.10) + parser (>= 3.1.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.15.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.15.1) + parser (>= 3.0.1.1) + ruby-progressbar (1.11.0) serverspec (2.41.5) multi_json rspec (~> 3.0) @@ -40,6 +59,7 @@ GEM net-ssh (>= 2.7) net-telnet (= 0.1.1) sfl + unicode-display_width (2.1.0) PLATFORMS ruby @@ -48,6 +68,7 @@ DEPENDENCIES docker-api rspec rspec-wait + rubocop serverspec BUNDLED WITH diff --git a/.template/addons/nginx/docker.rb b/.template/addons/nginx/docker.rb index 4ad76fe0..a389ff3b 100644 --- a/.template/addons/nginx/docker.rb +++ b/.template/addons/nginx/docker.rb @@ -2,7 +2,7 @@ 'nginx ' end -insert_into_file 'Dockerfile', after: %r(WORKDIR.+\n) do +insert_into_file 'Dockerfile', after: %r{WORKDIR.+\n} do <<~DOCKERFILE # Nginx config diff --git a/.template/addons/phrase_app/template.rb b/.template/addons/phrase_app/template.rb index d7a29f98..383dd400 100644 --- a/.template/addons/phrase_app/template.rb +++ b/.template/addons/phrase_app/template.rb @@ -1,6 +1,6 @@ after_bundle do use_source_path __dir__ - + copy_file '.phraseapp.yml' apply 'spec/template.rb' end diff --git a/.template/bin/rubocop b/.template/bin/rubocop new file mode 100755 index 00000000..8c983bad --- /dev/null +++ b/.template/bin/rubocop @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +bundle exec rubocop --config .template/.rubocop.yml $@ diff --git a/.template/hooks/before_complete/fix_rubocop.rb b/.template/hooks/before_complete/fix_rubocop.rb index ab77ff79..5d29b324 100644 --- a/.template/hooks/before_complete/fix_rubocop.rb +++ b/.template/hooks/before_complete/fix_rubocop.rb @@ -2,11 +2,11 @@ def fixing_rubocop after_bundle do use_source_path __dir__ - cops = %w( + cops = %w[ Style/FrozenStringLiteralComment Style/StringLiterals Layout/EmptyLineAfterMagicComment - ).join(',') + ].join(',') run "rubocop --only #{cops} --auto-correct-all --out tmp/template_rubocop.txt" end diff --git a/.template/lib/template/errors.rb b/.template/lib/template/errors.rb index 87728b71..47f99445 100644 --- a/.template/lib/template/errors.rb +++ b/.template/lib/template/errors.rb @@ -1 +1,3 @@ +# rubocop:todo Style/ClassAndModuleChildren class Template::Errors < Template::Messages; end +# rubocop:enable Style/ClassAndModuleChildren diff --git a/.template/lib/template/messages.rb b/.template/lib/template/messages.rb index f90aee11..53d9eee8 100644 --- a/.template/lib/template/messages.rb +++ b/.template/lib/template/messages.rb @@ -1,3 +1,4 @@ +# rubocop:todo Style/ClassAndModuleChildren class Template::Messages delegate :empty?, to: :messages @@ -17,3 +18,4 @@ def to_s attr_reader :messages end +# rubocop:enable Style/ClassAndModuleChildren diff --git a/.template/spec/addons/base/github/template_spec.rb b/.template/spec/addons/base/github/template_spec.rb index e74d36d3..2d48d911 100644 --- a/.template/spec/addons/base/github/template_spec.rb +++ b/.template/spec/addons/base/github/template_spec.rb @@ -20,11 +20,11 @@ # TODO: Can't test this as it is now ignored by `.dockerignore` xit 'modifies the README.md' do - expect(file('README.md')).to contain("## Documentation") + expect(file('README.md')).to contain('## Documentation') - expect(file('README.md')).not_to contain("## Getting Started") - expect(file('README.md')).not_to contain("## Testing") - expect(file('README.md')).not_to contain("## CI/CD") + expect(file('README.md')).not_to contain('## Getting Started') + expect(file('README.md')).not_to contain('## Testing') + expect(file('README.md')).not_to contain('## CI/CD') end describe '.github/wiki/Getting-Started.md' do @@ -33,9 +33,9 @@ end it 'contains the correct content extracted from README.md' do - expect(file('.github/wiki/Getting-Started.md')).to contain("### Prerequisites") - expect(file('.github/wiki/Getting-Started.md')).to contain("### Docker") - expect(file('.github/wiki/Getting-Started.md')).to contain("### Development") + expect(file('.github/wiki/Getting-Started.md')).to contain('### Prerequisites') + expect(file('.github/wiki/Getting-Started.md')).to contain('### Docker') + expect(file('.github/wiki/Getting-Started.md')).to contain('### Development') end end @@ -51,10 +51,10 @@ end it 'contains the correct content extracted from the workflow README.md' do - expect(file('.github/wiki/CI-CD.md')).to contain("## Test workflow") - expect(file('.github/wiki/CI-CD.md')).to contain("## Test production build workflow") - expect(file('.github/wiki/CI-CD.md')).to contain("## Deploy to Heroku workflow") - expect(file('.github/wiki/CI-CD.md')).to contain("## Publish to Wiki workflow") + expect(file('.github/wiki/CI-CD.md')).to contain('## Test workflow') + expect(file('.github/wiki/CI-CD.md')).to contain('## Test production build workflow') + expect(file('.github/wiki/CI-CD.md')).to contain('## Deploy to Heroku workflow') + expect(file('.github/wiki/CI-CD.md')).to contain('## Publish to Wiki workflow') end it 'deletes the workflow README.md' do @@ -68,9 +68,9 @@ end it 'contains the correct content extracted from README.md' do - expect(file('.github/wiki/Testing.md')).to contain("### Docker-based tests on the CI server") - expect(file('.github/wiki/Testing.md')).to contain("### Test") - expect(file('.github/wiki/Testing.md')).to contain("### Automated Code Review Setup") + expect(file('.github/wiki/Testing.md')).to contain('### Docker-based tests on the CI server') + expect(file('.github/wiki/Testing.md')).to contain('### Test') + expect(file('.github/wiki/Testing.md')).to contain('### Automated Code Review Setup') end end end diff --git a/.template/spec/addons/base/phrase_app/template.rb b/.template/spec/addons/base/phrase_app/template.rb index 1285f34d..505ad730 100644 --- a/.template/spec/addons/base/phrase_app/template.rb +++ b/.template/spec/addons/base/phrase_app/template.rb @@ -2,7 +2,7 @@ it 'creates .phraseapp.yml file' do expect(file('.phraseapp.yml')).to exist end - + it 'adds PhraseApp to codebase_spec' do expect(file('spec/codebase/codebase_spec.rb')).to contain("it 'does not offend PhraseApp Pull configuration' do") end diff --git a/.template/spec/base/app/controllers/concerns/localization_spec.rb b/.template/spec/base/app/controllers/concerns/localization_spec.rb index 8c7b1254..48087414 100644 --- a/.template/spec/base/app/controllers/concerns/localization_spec.rb +++ b/.template/spec/base/app/controllers/concerns/localization_spec.rb @@ -1,6 +1,6 @@ describe 'localization concern' do subject { file('app/controllers/concerns/localization.rb') } - + it 'contains the around_action' do expect(subject).to contain('around_action :switch_locale') end diff --git a/.template/spec/base/config/environments/production_spec.rb b/.template/spec/base/config/environments/production_spec.rb index 003ab918..2e18306e 100644 --- a/.template/spec/base/config/environments/production_spec.rb +++ b/.template/spec/base/config/environments/production_spec.rb @@ -14,7 +14,7 @@ end it 'removes the config.i18n.fallbacks = true' do - expect(subject).not_to contain("config.i18n.fallbacks = true") + expect(subject).not_to contain('config.i18n.fallbacks = true') end private diff --git a/.template/variants/web/.gitignore.rb b/.template/variants/web/.gitignore.rb index 3a8e1f0e..60fe5dce 100644 --- a/.template/variants/web/.gitignore.rb +++ b/.template/variants/web/.gitignore.rb @@ -1,13 +1,13 @@ append_to_file '.gitignore' do <<~IGNORE - # Ignore i18n.js generated files - # If deploy to heroku with git, please remove this as it prevents the files to be committed - /app/javascript/translations/* + # Ignore i18n.js generated files + # If deploy to heroku with git, please remove this as it prevents the files to be committed + /app/javascript/translations/* - # Ignore asset builds - /app/assets/builds/* + # Ignore asset builds + /app/assets/builds/* - # Ignore Node dependencies - /node_modules + # Ignore Node dependencies + /node_modules IGNORE end diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index d124d820..86f4851b 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -32,6 +32,13 @@ source_stylesheet = 'app/assets/stylesheets/application.scss' bundled_stylesheet = 'app/assets/builds/application.css' +bundled_stylesheet_options = [ + '--no-source-map', + '--load-path=node_modules' +] run %(npm set-script build "node app/javascript/build.js") -run %(npm set-script build:css "sass #{source_stylesheet} #{bundled_stylesheet} --no-source-map --load-path=node_modules") +run %( + npm set-script build:css \ + "sass #{source_stylesheet} #{bundled_stylesheet} #{bundled_stylesheet_options.join(' ')}" +) diff --git a/README.md b/README.md index fda3d101..f0212198 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,13 @@ with building complex applications over the years. - Install rails `7.0.1` - Install node `16.13.2` (For creating web application) +> šŸ“ If running on Apple M1, to build docker image, please make sure to set platform to AMD64 by `export DOCKER_DEFAULT_PLATFORM=linux/amd64` + ### Use the template In order to use the template, initialize a new app with the following parameters: -``` +```sh rails new -m https://raw.githubusercontent.com/nimblehq/rails-templates/master/template.rb ``` @@ -33,7 +35,7 @@ Supported template options: To apply the template on an existing application, run following rails command: -``` +```sh rails app:template LOCATION=https://raw.githubusercontent.com/nimblehq/rails-templates/master/template.rb # To apply on an api application @@ -172,6 +174,21 @@ e.g. `TOOL_VERSION` for `.tool-version` file. For the normal string, name it after the content e.g. `ERROR` for template error message. +## Testing the Template + +To run [RuboCop](https://github.com/rubocop/rubocop) against the template: + +```sh +.template/bin/rubocop +``` + +Any RuboCop command options can be passed: + +```sh +# Run RuboCop with auto correct +.template/bin/rubocop -a +``` + ## License This project is Copyright (c) 2014 and onwards. It is free software, diff --git a/bin/docker-prepare b/bin/docker-prepare index 03c05e88..ef2819dc 100755 --- a/bin/docker-prepare +++ b/bin/docker-prepare @@ -2,8 +2,8 @@ require 'fileutils' # Copy the project dependencies to build the docker image -DOCKER_TMP_FOLDER = 'tmp/docker' -ENGINES_DIRECTORY = 'engines' +DOCKER_TMP_FOLDER = 'tmp/docker'.freeze +ENGINES_DIRECTORY = 'engines'.freeze FileUtils.rm_rf DOCKER_TMP_FOLDER FileUtils.mkdir DOCKER_TMP_FOLDER diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 7c8e0f31..6efafcdd 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -6,7 +6,7 @@ require 'json_matchers/rspec' require 'pundit/rspec' -Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f } +Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f } ActiveRecord::Migration.maintain_test_schema! diff --git a/template.rb b/template.rb index 1e3eecf3..2b7eb8c0 100644 --- a/template.rb +++ b/template.rb @@ -19,8 +19,8 @@ }.freeze if WEB_VARIANT - NODE_VERSION='16.13.2'.freeze - NODE_SOURCE_VERSION='16'.freeze # Used in Dockerfile https://github.com/nodesource/distributions + NODE_VERSION = '16.13.2'.freeze + NODE_SOURCE_VERSION = '16'.freeze # Used in Dockerfile https://github.com/nodesource/distributions end def apply_template!(template_root) @@ -59,7 +59,7 @@ def apply_template!(template_root) # Add-ons - [Default] DEFAULT_ADDONS.each_key do |addon| - apply ".template/addons/#{addon.to_s}/template.rb" + apply ".template/addons/#{addon}/template.rb" end post_default_addons_install @@ -117,7 +117,7 @@ def install_addon_prompt(addon) end def post_default_addons_install - addons = "" + addons = '' DEFAULT_ADDONS.each_value do |addon| addons << "* #{addon}\n " end From 7810d17896f9e5ba185adbf6e136d6bd237d5785 Mon Sep 17 00:00:00 2001 From: Rossukhon Leagmongkol Date: Mon, 21 Mar 2022 14:24:05 +0700 Subject: [PATCH 13/13] Set up Rubocop for the template - Enable cop rules (#324) * Enable regex literal style * Enable global var style * Enable frozen string literal style * Enable filename naming * Fix default addon message --- .gitignore.rb | 2 ++ .template/.rubocop.yml | 17 ++++--------- .template/Gemfile | 2 ++ .../addons/bootstrap/application.scss.rb | 2 +- .template/addons/devise/Gemfile.rb | 2 ++ .template/addons/devise/spec_support.rb | 2 ++ .template/addons/devise/template.rb | 2 ++ .template/addons/docker/template.rb | 2 ++ .template/addons/github/template.rb | 2 ++ .template/addons/heroku/template.rb | 2 ++ .template/addons/nginx/bin/start.sh.rb | 2 ++ .template/addons/nginx/bin/template.rb | 2 ++ .../nginx/config/environments/production.rb | 2 ++ .template/addons/nginx/config/template.rb | 2 ++ .template/addons/nginx/docker.rb | 4 ++- .template/addons/nginx/template.rb | 2 ++ .../phrase_app/spec/codebase/codebase_spec.rb | 4 ++- .template/addons/phrase_app/spec/template.rb | 2 ++ .template/addons/phrase_app/template.rb | 2 ++ .template/addons/semaphore/template.rb | 2 ++ .template/addons/slim/template.rb | 2 ++ .../hooks/before_complete/fix_rubocop.rb | 2 ++ .template/hooks/before_complete/report.rb | 2 ++ .template/lib/template.rb | 2 ++ .template/lib/template/errors.rb | 2 ++ .template/lib/template/messages.rb | 2 ++ .../spec/addons/base/devise/gemfile_spec.rb | 2 ++ .../spec/addons/base/devise/template_spec.rb | 2 ++ .../spec/addons/base/docker/template_spec.rb | 2 ++ .../spec/addons/base/github/template_spec.rb | 2 ++ .../spec/addons/base/nginx/template_spec.rb | 2 ++ .../spec/addons/base/phrase_app/template.rb | 2 ++ .../addons/base/semaphore/template_spec.rb | 2 ++ .../variants/api/nginx/template_spec.rb | 2 ++ .../web/bootstrap/application_js_spec.rb | 2 ++ .../web/bootstrap/application_scss_spec.rb | 2 ++ .../web/bootstrap/package_json_spec.rb | 2 ++ .../variants/web/bootstrap/template_spec.rb | 2 ++ .../variants/web/nginx/template_spec.rb | 2 ++ .../variants/web/slim/dangerfile_spec.rb | 2 ++ .../addons/variants/web/slim/gemfile_spec.rb | 2 ++ .../controllers/concerns/localization_spec.rb | 2 ++ .template/spec/base/application_spec.rb | 2 ++ .template/spec/base/bin/template_spec.rb | 2 ++ .../spec/base/config/application_spec.rb | 2 ++ .../config/environments/development_spec.rb | 2 ++ .../config/environments/production_spec.rb | 2 ++ .../base/config/environments/test_spec.rb | 2 ++ .template/spec/base/config/template_spec.rb | 2 ++ .template/spec/base/spec/template_spec.rb | 2 ++ .template/spec/base/template_spec.rb | 2 ++ .template/spec/spec_helper.rb | 2 ++ .template/spec/support/serverspec.rb | 25 +++++++++++++------ .template/spec/variants/api/template_spec.rb | 2 ++ .../spec/variants/web/app/template_spec.rb | 2 ++ .../variants/web/config/application_spec.rb | 2 ++ .../web/config/environments/test_spec.rb | 2 ++ .../web/config/initializers/assets_spec.rb | 2 ++ .../spec/variants/web/config/template_spec.rb | 2 ++ .../spec/variants/web/dangerfile_spec.rb | 2 ++ .../spec/variants/web/docker_image_spec.rb | 2 ++ .template/spec/variants/web/gemfile_spec.rb | 2 ++ .../spec/variants/web/package_json_spec.rb | 2 ++ .../spec/variants/web/proc_file_dev_spec.rb | 2 ++ .../web/spec/codebase/codebase_spec.rb | 2 ++ .../spec/variants/web/spec/template_spec.rb | 2 ++ .template/spec/variants/web/template_spec.rb | 2 ++ .../spec/variants/web/tool_versions_spec.rb | 2 ++ .../app/controllers/concerns/localization.rb | 2 ++ .template/variants/api/app/template.rb | 2 ++ .template/variants/api/template.rb | 2 ++ .template/variants/web/.gitignore.rb | 2 ++ .template/variants/web/.tool-versions.rb | 2 ++ .template/variants/web/Dangerfile.rb | 4 ++- .template/variants/web/Gemfile.rb | 12 +++++---- .template/variants/web/Procfile.dev.rb | 2 ++ .../app/controllers/concerns/localization.rb | 2 ++ .template/variants/web/app/template.rb | 2 ++ .template/variants/web/config/application.rb | 4 ++- .../variants/web/config/environments/test.rb | 6 +++-- .../web/config/initializers/assets.rb | 2 ++ .template/variants/web/config/template.rb | 2 ++ .template/variants/web/package.json.rb | 2 ++ .../web/spec/codebase/codebase_spec.rb | 4 ++- .template/variants/web/spec/support/assets.rb | 2 ++ .../variants/web/spec/support/capybara.rb | 2 ++ .../web/spec/support/disable_animation.rb | 2 ++ .template/variants/web/spec/support/system.rb | 2 ++ .../variants/web/spec/support/webdrivers.rb | 2 ++ .template/variants/web/spec/template.rb | 2 ++ .template/variants/web/template.rb | 2 ++ bin/docker-assets-precompile | 1 + bin/docker-prepare | 6 +++-- bin/template.rb | 2 ++ config/application.rb | 4 ++- config/environments/development.rb | 6 +++-- config/environments/production.rb | 4 ++- config/environments/test.rb | 6 +++-- config/initializers/backtrace_silencers.rb | 2 ++ config/template.rb | 2 ++ spec/codebase/codebase_spec.rb | 2 ++ spec/rails_helper.rb | 2 ++ spec/spec_helper.rb | 2 ++ spec/support/bullet.rb | 2 ++ spec/support/database_cleaner.rb | 2 ++ spec/support/request_helpers.rb | 2 ++ spec/support/retry.rb | 2 ++ spec/support/shoulda_matchers.rb | 2 ++ spec/support/sidekiq.rb | 2 ++ spec/support/simplecov.rb | 2 ++ spec/support/vcr.rb | 2 ++ spec/template.rb | 2 ++ template.rb | 21 +++++++--------- 113 files changed, 270 insertions(+), 52 deletions(-) diff --git a/.gitignore.rb b/.gitignore.rb index afa2dbe0..b5698e0a 100644 --- a/.gitignore.rb +++ b/.gitignore.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + append_to_file '.gitignore' do <<~IGNORE diff --git a/.template/.rubocop.yml b/.template/.rubocop.yml index a7831f9c..3337c306 100644 --- a/.template/.rubocop.yml +++ b/.template/.rubocop.yml @@ -31,22 +31,15 @@ Metrics/PerceivedComplexity: - '**/template.rb' Naming/FileName: - Enabled: false + Exclude: + - '**/.tool-versions.rb' + - '**/Dangerfile.rb' + - '**/Gemfile.rb' + - '**/Procfile.dev.rb' Style/Documentation: Enabled: false -Style/FrozenStringLiteralComment: - Enabled: false - -# TODO: Enable this rule later -Style/GlobalVars: - Enabled: false - -# TODO: Enable this rule later -Style/RegexpLiteral: - Enabled: false - Style/TrivialAccessors: Exclude: - '../template.rb' diff --git a/.template/Gemfile b/.template/Gemfile index 9bf79d1f..031f0c89 100644 --- a/.template/Gemfile +++ b/.template/Gemfile @@ -1,3 +1,5 @@ +# frozen_string_literal: true + source 'https://rubygems.org' gem 'docker-api' # A lightweight Ruby client for the Docker Remote API diff --git a/.template/addons/bootstrap/application.scss.rb b/.template/addons/bootstrap/application.scss.rb index cc242bf2..ac4043f9 100644 --- a/.template/addons/bootstrap/application.scss.rb +++ b/.template/addons/bootstrap/application.scss.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -insert_into_file 'app/assets/stylesheets/application.scss', after: /\/\/ Dependencies\n/ do +insert_into_file 'app/assets/stylesheets/application.scss', after: %r{// Dependencies\n} do <<~SCSS @import './vendor'; SCSS diff --git a/.template/addons/devise/Gemfile.rb b/.template/addons/devise/Gemfile.rb index dc48a1bf..95c28674 100644 --- a/.template/addons/devise/Gemfile.rb +++ b/.template/addons/devise/Gemfile.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + insert_into_file 'Gemfile', after: /# Authentications & Authorizations.*\n/ do <<~RUBY gem 'devise' # Authentication solution for Rails with Warden diff --git a/.template/addons/devise/spec_support.rb b/.template/addons/devise/spec_support.rb index c005273e..344129dc 100644 --- a/.template/addons/devise/spec_support.rb +++ b/.template/addons/devise/spec_support.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + file 'spec/support/devise.rb', <<~RUBY RSpec.configure do |config| config.include Devise::Test::ControllerHelpers, type: :controller diff --git a/.template/addons/devise/template.rb b/.template/addons/devise/template.rb index 3182b8e0..6ba72bf3 100644 --- a/.template/addons/devise/template.rb +++ b/.template/addons/devise/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + apply '.template/addons/devise/Gemfile.rb' apply '.template/addons/devise/spec_support.rb' diff --git a/.template/addons/docker/template.rb b/.template/addons/docker/template.rb index 9b9b8081..18b65679 100644 --- a/.template/addons/docker/template.rb +++ b/.template/addons/docker/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ template 'Dockerfile.tt' diff --git a/.template/addons/github/template.rb b/.template/addons/github/template.rb index c74b169d..713bf7db 100644 --- a/.template/addons/github/template.rb +++ b/.template/addons/github/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ directory '.github' diff --git a/.template/addons/heroku/template.rb b/.template/addons/heroku/template.rb index 69279f80..c459ce52 100644 --- a/.template/addons/heroku/template.rb +++ b/.template/addons/heroku/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ template 'Dockerfile.web.tt' diff --git a/.template/addons/nginx/bin/start.sh.rb b/.template/addons/nginx/bin/start.sh.rb index 9ea8cce4..34339fc8 100755 --- a/.template/addons/nginx/bin/start.sh.rb +++ b/.template/addons/nginx/bin/start.sh.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + insert_into_file 'bin/start.sh', after: "fi\n" do <<~SHELL diff --git a/.template/addons/nginx/bin/template.rb b/.template/addons/nginx/bin/template.rb index efb46c5b..89d606e8 100644 --- a/.template/addons/nginx/bin/template.rb +++ b/.template/addons/nginx/bin/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ apply 'start.sh.rb' diff --git a/.template/addons/nginx/config/environments/production.rb b/.template/addons/nginx/config/environments/production.rb index dda1c379..56efacd8 100644 --- a/.template/addons/nginx/config/environments/production.rb +++ b/.template/addons/nginx/config/environments/production.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + gsub_file( 'config/environments/production.rb', /config.public_file_server.enabled.*/, diff --git a/.template/addons/nginx/config/template.rb b/.template/addons/nginx/config/template.rb index abf6ad99..c6ecff8d 100644 --- a/.template/addons/nginx/config/template.rb +++ b/.template/addons/nginx/config/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ apply 'config/environments/production.rb' diff --git a/.template/addons/nginx/docker.rb b/.template/addons/nginx/docker.rb index a389ff3b..b4bea228 100644 --- a/.template/addons/nginx/docker.rb +++ b/.template/addons/nginx/docker.rb @@ -1,8 +1,10 @@ +# frozen_string_literal: true + insert_into_file 'Dockerfile', after: 'unzip ' do 'nginx ' end -insert_into_file 'Dockerfile', after: %r{WORKDIR.+\n} do +insert_into_file 'Dockerfile', after: /WORKDIR.+\n/ do <<~DOCKERFILE # Nginx config diff --git a/.template/addons/nginx/template.rb b/.template/addons/nginx/template.rb index ffd07127..819ab84f 100644 --- a/.template/addons/nginx/template.rb +++ b/.template/addons/nginx/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ apply 'bin/template.rb' diff --git a/.template/addons/phrase_app/spec/codebase/codebase_spec.rb b/.template/addons/phrase_app/spec/codebase/codebase_spec.rb index 60352876..e463639d 100644 --- a/.template/addons/phrase_app/spec/codebase/codebase_spec.rb +++ b/.template/addons/phrase_app/spec/codebase/codebase_spec.rb @@ -1,4 +1,6 @@ -insert_into_file 'spec/codebase/codebase_spec.rb', before: %r{end\Z} do +# frozen_string_literal: true + +insert_into_file 'spec/codebase/codebase_spec.rb', before: /end\Z/ do <<~RUBY.indent(2) # rubocop:disable RSpec/ExampleLength diff --git a/.template/addons/phrase_app/spec/template.rb b/.template/addons/phrase_app/spec/template.rb index 27903cf8..1101859e 100644 --- a/.template/addons/phrase_app/spec/template.rb +++ b/.template/addons/phrase_app/spec/template.rb @@ -1 +1,3 @@ +# frozen_string_literal: true + apply 'spec/codebase/codebase_spec.rb' diff --git a/.template/addons/phrase_app/template.rb b/.template/addons/phrase_app/template.rb index 383dd400..39cd904e 100644 --- a/.template/addons/phrase_app/template.rb +++ b/.template/addons/phrase_app/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + after_bundle do use_source_path __dir__ diff --git a/.template/addons/semaphore/template.rb b/.template/addons/semaphore/template.rb index 325fe67c..263e4e32 100644 --- a/.template/addons/semaphore/template.rb +++ b/.template/addons/semaphore/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ directory '.semaphore' diff --git a/.template/addons/slim/template.rb b/.template/addons/slim/template.rb index 41be028b..3a26f631 100644 --- a/.template/addons/slim/template.rb +++ b/.template/addons/slim/template.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + apply '.template/addons/slim/Gemfile.rb' apply '.template/addons/slim/Dangerfile.rb' diff --git a/.template/hooks/before_complete/fix_rubocop.rb b/.template/hooks/before_complete/fix_rubocop.rb index 5d29b324..cba75fa8 100644 --- a/.template/hooks/before_complete/fix_rubocop.rb +++ b/.template/hooks/before_complete/fix_rubocop.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + def fixing_rubocop after_bundle do use_source_path __dir__ diff --git a/.template/hooks/before_complete/report.rb b/.template/hooks/before_complete/report.rb index 88c219df..310e8436 100644 --- a/.template/hooks/before_complete/report.rb +++ b/.template/hooks/before_complete/report.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + def report after_bundle do say "\nšŸš€ The project has been successfully created šŸš€\n", :green diff --git a/.template/lib/template.rb b/.template/lib/template.rb index 313d6403..5be49684 100644 --- a/.template/lib/template.rb +++ b/.template/lib/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Template require_relative 'template/messages' require_relative 'template/errors' diff --git a/.template/lib/template/errors.rb b/.template/lib/template/errors.rb index 47f99445..8da677e1 100644 --- a/.template/lib/template/errors.rb +++ b/.template/lib/template/errors.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # rubocop:todo Style/ClassAndModuleChildren class Template::Errors < Template::Messages; end # rubocop:enable Style/ClassAndModuleChildren diff --git a/.template/lib/template/messages.rb b/.template/lib/template/messages.rb index 53d9eee8..d61546cd 100644 --- a/.template/lib/template/messages.rb +++ b/.template/lib/template/messages.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # rubocop:todo Style/ClassAndModuleChildren class Template::Messages delegate :empty?, to: :messages diff --git a/.template/spec/addons/base/devise/gemfile_spec.rb b/.template/spec/addons/base/devise/gemfile_spec.rb index 2e08d356..aff52bf1 100644 --- a/.template/spec/addons/base/devise/gemfile_spec.rb +++ b/.template/spec/addons/base/devise/gemfile_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Devise Addon - Gemfile' do subject { file('Gemfile') } diff --git a/.template/spec/addons/base/devise/template_spec.rb b/.template/spec/addons/base/devise/template_spec.rb index 8ce33de2..cce913b6 100644 --- a/.template/spec/addons/base/devise/template_spec.rb +++ b/.template/spec/addons/base/devise/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Devise addon - template' do it 'creates the Devise spec support file' do expect(file('spec/support/devise.rb')).to exist diff --git a/.template/spec/addons/base/docker/template_spec.rb b/.template/spec/addons/base/docker/template_spec.rb index 50926936..208b3741 100644 --- a/.template/spec/addons/base/docker/template_spec.rb +++ b/.template/spec/addons/base/docker/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Docker addon - template' do it 'creates the Dockerfile' do expect(file('Dockerfile')).to exist diff --git a/.template/spec/addons/base/github/template_spec.rb b/.template/spec/addons/base/github/template_spec.rb index 2d48d911..0baff3a5 100644 --- a/.template/spec/addons/base/github/template_spec.rb +++ b/.template/spec/addons/base/github/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Github addon - template' do it 'creates the PULL_REQUEST_TEMPLATE file' do expect(file('.github/PULL_REQUEST_TEMPLATE.md')).to exist diff --git a/.template/spec/addons/base/nginx/template_spec.rb b/.template/spec/addons/base/nginx/template_spec.rb index 1bae78cf..b69c92f8 100644 --- a/.template/spec/addons/base/nginx/template_spec.rb +++ b/.template/spec/addons/base/nginx/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Nginx addon - template' do it 'creates the inject_port_into_nginx script' do expect(file('bin/inject_port_into_nginx.sh')).to exist diff --git a/.template/spec/addons/base/phrase_app/template.rb b/.template/spec/addons/base/phrase_app/template.rb index 505ad730..596ff8ba 100644 --- a/.template/spec/addons/base/phrase_app/template.rb +++ b/.template/spec/addons/base/phrase_app/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'PhraseApp addon - template' do it 'creates .phraseapp.yml file' do expect(file('.phraseapp.yml')).to exist diff --git a/.template/spec/addons/base/semaphore/template_spec.rb b/.template/spec/addons/base/semaphore/template_spec.rb index bf19cb26..94e2f11f 100644 --- a/.template/spec/addons/base/semaphore/template_spec.rb +++ b/.template/spec/addons/base/semaphore/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Semaphore addon - template' do it 'creates the Dockerfile.web' do expect(file('Dockerfile.web')).to exist diff --git a/.template/spec/addons/variants/api/nginx/template_spec.rb b/.template/spec/addons/variants/api/nginx/template_spec.rb index 467792bf..13d0d442 100644 --- a/.template/spec/addons/variants/api/nginx/template_spec.rb +++ b/.template/spec/addons/variants/api/nginx/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Nginx addon - template' do it 'creates config/nginx/app.conf.template file' do expect(file('config/nginx/app.conf.template')).not_to contain('gzip on;') diff --git a/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb b/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb index 290f6f3f..cf40b054 100644 --- a/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/application_js_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Bootstrap Addon - application.js' do subject { file('app/javascript/application.js') } diff --git a/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb b/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb index c03d2cc2..8fcdeb59 100644 --- a/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/application_scss_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Bootstrap Addon - application.scss' do subject { file('app/assets/stylesheets/application.scss') } diff --git a/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb b/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb index 5032baa9..994e9081 100644 --- a/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/package_json_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Bootstrap addon - package.json' do subject do JSON.parse(file('package.json').content) diff --git a/.template/spec/addons/variants/web/bootstrap/template_spec.rb b/.template/spec/addons/variants/web/bootstrap/template_spec.rb index df1ef16d..9b989d1f 100644 --- a/.template/spec/addons/variants/web/bootstrap/template_spec.rb +++ b/.template/spec/addons/variants/web/bootstrap/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Bootstrap addon - template' do it 'creates app/assets/stylesheets/vendor/index.scss' do expect(file('app/assets/stylesheets/vendor/index.scss')).to exist diff --git a/.template/spec/addons/variants/web/nginx/template_spec.rb b/.template/spec/addons/variants/web/nginx/template_spec.rb index 2ad3b332..0ad010ed 100644 --- a/.template/spec/addons/variants/web/nginx/template_spec.rb +++ b/.template/spec/addons/variants/web/nginx/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Nginx addon - template' do it 'creates config/nginx/app.conf.template file' do expect(file('config/nginx/app.conf.template')).to contain('gzip on;') diff --git a/.template/spec/addons/variants/web/slim/dangerfile_spec.rb b/.template/spec/addons/variants/web/slim/dangerfile_spec.rb index c122ab57..9960bcee 100644 --- a/.template/spec/addons/variants/web/slim/dangerfile_spec.rb +++ b/.template/spec/addons/variants/web/slim/dangerfile_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Slim Addon - Dangerfile' do subject { file('Dangerfile') } diff --git a/.template/spec/addons/variants/web/slim/gemfile_spec.rb b/.template/spec/addons/variants/web/slim/gemfile_spec.rb index 0f130698..85951c7b 100644 --- a/.template/spec/addons/variants/web/slim/gemfile_spec.rb +++ b/.template/spec/addons/variants/web/slim/gemfile_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Slim Addon - Gemfile' do subject { file('Gemfile') } diff --git a/.template/spec/base/app/controllers/concerns/localization_spec.rb b/.template/spec/base/app/controllers/concerns/localization_spec.rb index 48087414..4ad9bbfa 100644 --- a/.template/spec/base/app/controllers/concerns/localization_spec.rb +++ b/.template/spec/base/app/controllers/concerns/localization_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'localization concern' do subject { file('app/controllers/concerns/localization.rb') } diff --git a/.template/spec/base/application_spec.rb b/.template/spec/base/application_spec.rb index f9a7f631..bbe692d1 100644 --- a/.template/spec/base/application_spec.rb +++ b/.template/spec/base/application_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Application' do it 'is listening on port 80' do # Config the wait time to 1 minute in case if the container has not fully started. diff --git a/.template/spec/base/bin/template_spec.rb b/.template/spec/base/bin/template_spec.rb index 687624a6..d5e7e629 100644 --- a/.template/spec/base/bin/template_spec.rb +++ b/.template/spec/base/bin/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe '/bin template' do it 'creates the envsetup script' do expect(file('bin/envsetup.sh')).to exist diff --git a/.template/spec/base/config/application_spec.rb b/.template/spec/base/config/application_spec.rb index 45170c36..7ed2733a 100644 --- a/.template/spec/base/config/application_spec.rb +++ b/.template/spec/base/config/application_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'config/application.rb' do subject { file('config/application.rb') } diff --git a/.template/spec/base/config/environments/development_spec.rb b/.template/spec/base/config/environments/development_spec.rb index 5743b4da..762528c8 100644 --- a/.template/spec/base/config/environments/development_spec.rb +++ b/.template/spec/base/config/environments/development_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'config/environments/development.rb' do subject { file('config/environments/development.rb') } diff --git a/.template/spec/base/config/environments/production_spec.rb b/.template/spec/base/config/environments/production_spec.rb index 2e18306e..2aed5269 100644 --- a/.template/spec/base/config/environments/production_spec.rb +++ b/.template/spec/base/config/environments/production_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'config/environments/production.rb' do subject { file('config/environments/production.rb') } diff --git a/.template/spec/base/config/environments/test_spec.rb b/.template/spec/base/config/environments/test_spec.rb index 70d9df39..37b9970d 100644 --- a/.template/spec/base/config/environments/test_spec.rb +++ b/.template/spec/base/config/environments/test_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'config/environments/test.rb' do subject { file('config/environments/test.rb') } diff --git a/.template/spec/base/config/template_spec.rb b/.template/spec/base/config/template_spec.rb index 2a039d5e..9ea75fe2 100644 --- a/.template/spec/base/config/template_spec.rb +++ b/.template/spec/base/config/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe '/config template' do it 'creates the Figaro configuration for application variables' do expect(file('config/application.yml')).to exist diff --git a/.template/spec/base/spec/template_spec.rb b/.template/spec/base/spec/template_spec.rb index b61c537f..62459810 100644 --- a/.template/spec/base/spec/template_spec.rb +++ b/.template/spec/base/spec/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe '/spec template' do it 'creates the base spec directory' do expect(file('spec/codebase')).to be_directory diff --git a/.template/spec/base/template_spec.rb b/.template/spec/base/template_spec.rb index 598d4922..430f1fef 100644 --- a/.template/spec/base/template_spec.rb +++ b/.template/spec/base/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Base template' do it 'creates Rubocop configuration files' do expect(file('.rubocop.yml')).to exist diff --git a/.template/spec/spec_helper.rb b/.template/spec/spec_helper.rb index ff1b80be..8e2225e3 100644 --- a/.template/spec/spec_helper.rb +++ b/.template/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rspec/wait' Dir[[__dir__, 'support', '**', '*.rb'].join('/')].each { |f| require f } diff --git a/.template/spec/support/serverspec.rb b/.template/spec/support/serverspec.rb index 99864ca1..03527d6e 100644 --- a/.template/spec/support/serverspec.rb +++ b/.template/spec/support/serverspec.rb @@ -1,20 +1,31 @@ +# frozen_string_literal: true + require 'serverspec' require 'docker-api' +module ServerSpecHelpers + # Prebuild and run docker image before running the test + # Because the docker api does not support docker compose + def self.test_container + container_id = `docker ps -qf "name=#{ENV.fetch('APP_NAME')}_test"` + + Docker::Container.get(container_id.strip) + end +end + RSpec.configure do |config| config.before(:suite) do - # Prebuild and run docker image before running the test - # Because the docker api does not support docker compose - container_id = `docker ps -qf "name=#{ENV.fetch('APP_NAME')}_test"` - $container = Docker::Container.get(container_id.strip) + container = ServerSpecHelpers.test_container set :os, family: :debian set :backend, :docker - set :docker_container, $container.id + set :docker_container, container.id end config.after(:suite) do - $container.stop - $container.remove(force: true) + container = ServerSpecHelpers.test_container + + container.stop + container.remove(force: true) end end diff --git a/.template/spec/variants/api/template_spec.rb b/.template/spec/variants/api/template_spec.rb index 05a05449..5657f7d2 100644 --- a/.template/spec/variants/api/template_spec.rb +++ b/.template/spec/variants/api/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Api variant - template' do context 'Controllers' do it 'creates the localization concern' do diff --git a/.template/spec/variants/web/app/template_spec.rb b/.template/spec/variants/web/app/template_spec.rb index c9730f25..6e2e756a 100644 --- a/.template/spec/variants/web/app/template_spec.rb +++ b/.template/spec/variants/web/app/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - /app template' do context 'Javascript' do it 'creates base javascript directory' do diff --git a/.template/spec/variants/web/config/application_spec.rb b/.template/spec/variants/web/config/application_spec.rb index fcaf2f09..b4a59877 100644 --- a/.template/spec/variants/web/config/application_spec.rb +++ b/.template/spec/variants/web/config/application_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - config/application.rb' do subject { file('config/application.rb') } diff --git a/.template/spec/variants/web/config/environments/test_spec.rb b/.template/spec/variants/web/config/environments/test_spec.rb index 14ff7abf..dcf10690 100644 --- a/.template/spec/variants/web/config/environments/test_spec.rb +++ b/.template/spec/variants/web/config/environments/test_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - config/environments/test.rb' do subject { file('config/environments/test.rb') } diff --git a/.template/spec/variants/web/config/initializers/assets_spec.rb b/.template/spec/variants/web/config/initializers/assets_spec.rb index 0aa86b96..ca86215a 100644 --- a/.template/spec/variants/web/config/initializers/assets_spec.rb +++ b/.template/spec/variants/web/config/initializers/assets_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - config/initializers/assets.rb' do subject { file('config/initializers/assets.rb') } diff --git a/.template/spec/variants/web/config/template_spec.rb b/.template/spec/variants/web/config/template_spec.rb index 46c09c04..39ad7bf9 100644 --- a/.template/spec/variants/web/config/template_spec.rb +++ b/.template/spec/variants/web/config/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - /config template' do it 'creates i18n-js configuration file' do expect(file('config/i18n-js.yml')).to exist diff --git a/.template/spec/variants/web/dangerfile_spec.rb b/.template/spec/variants/web/dangerfile_spec.rb index bb8f0b5a..14ccb0d7 100644 --- a/.template/spec/variants/web/dangerfile_spec.rb +++ b/.template/spec/variants/web/dangerfile_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - Dangerfile' do subject { file('Dangerfile') } diff --git a/.template/spec/variants/web/docker_image_spec.rb b/.template/spec/variants/web/docker_image_spec.rb index 5c331480..c8405423 100644 --- a/.template/spec/variants/web/docker_image_spec.rb +++ b/.template/spec/variants/web/docker_image_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - Docker image' do it 'installs yarn package' do expect(package('yarn')).to be_installed diff --git a/.template/spec/variants/web/gemfile_spec.rb b/.template/spec/variants/web/gemfile_spec.rb index 8f0f873a..b959fa3f 100644 --- a/.template/spec/variants/web/gemfile_spec.rb +++ b/.template/spec/variants/web/gemfile_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - Gemfile' do subject { file('Gemfile') } diff --git a/.template/spec/variants/web/package_json_spec.rb b/.template/spec/variants/web/package_json_spec.rb index 82c72041..1d2890b5 100644 --- a/.template/spec/variants/web/package_json_spec.rb +++ b/.template/spec/variants/web/package_json_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - package.json' do subject do JSON.parse(file('package.json').content) diff --git a/.template/spec/variants/web/proc_file_dev_spec.rb b/.template/spec/variants/web/proc_file_dev_spec.rb index a5e6567d..9dfe5e20 100644 --- a/.template/spec/variants/web/proc_file_dev_spec.rb +++ b/.template/spec/variants/web/proc_file_dev_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - Procfile.dev' do subject { file('Procfile.dev') } diff --git a/.template/spec/variants/web/spec/codebase/codebase_spec.rb b/.template/spec/variants/web/spec/codebase/codebase_spec.rb index 43adf8ec..a0e59f2f 100644 --- a/.template/spec/variants/web/spec/codebase/codebase_spec.rb +++ b/.template/spec/variants/web/spec/codebase/codebase_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - spec/codebase/codebase_spec.rb' do subject { file('spec/codebase/codebase_spec.rb') } diff --git a/.template/spec/variants/web/spec/template_spec.rb b/.template/spec/variants/web/spec/template_spec.rb index 8406f704..9d199579 100644 --- a/.template/spec/variants/web/spec/template_spec.rb +++ b/.template/spec/variants/web/spec/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - /spec template' do it 'creates spec support files' do expect(file('spec/support/assets.rb')).to exist diff --git a/.template/spec/variants/web/template_spec.rb b/.template/spec/variants/web/template_spec.rb index 9cff4c7a..811025c5 100644 --- a/.template/spec/variants/web/template_spec.rb +++ b/.template/spec/variants/web/template_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - template' do it 'creates the eslint configuration files' do expect(file('.eslintrc')).to exist diff --git a/.template/spec/variants/web/tool_versions_spec.rb b/.template/spec/variants/web/tool_versions_spec.rb index 881625e7..cd159c95 100644 --- a/.template/spec/variants/web/tool_versions_spec.rb +++ b/.template/spec/variants/web/tool_versions_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe 'Web variant - .tool-versions' do subject { file('.tool-versions') } diff --git a/.template/variants/api/app/controllers/concerns/localization.rb b/.template/variants/api/app/controllers/concerns/localization.rb index 5850a5e3..ca66277d 100644 --- a/.template/variants/api/app/controllers/concerns/localization.rb +++ b/.template/variants/api/app/controllers/concerns/localization.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Localization extend ActiveSupport::Concern diff --git a/.template/variants/api/app/template.rb b/.template/variants/api/app/template.rb index e5e5006c..7e49d911 100644 --- a/.template/variants/api/app/template.rb +++ b/.template/variants/api/app/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Controllers directory 'app/controllers/concerns' inject_into_class 'app/controllers/application_controller.rb', 'ApplicationController' do diff --git a/.template/variants/api/template.rb b/.template/variants/api/template.rb index 2b34cfe8..83bc120f 100644 --- a/.template/variants/api/template.rb +++ b/.template/variants/api/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + use_source_path __dir__ apply 'app/template.rb' diff --git a/.template/variants/web/.gitignore.rb b/.template/variants/web/.gitignore.rb index 60fe5dce..b4cc828c 100644 --- a/.template/variants/web/.gitignore.rb +++ b/.template/variants/web/.gitignore.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + append_to_file '.gitignore' do <<~IGNORE # Ignore i18n.js generated files diff --git a/.template/variants/web/.tool-versions.rb b/.template/variants/web/.tool-versions.rb index 1b7ca2b1..21e58185 100644 --- a/.template/variants/web/.tool-versions.rb +++ b/.template/variants/web/.tool-versions.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + append_to_file '.tool-versions' do <<~TOOL_VERSION nodejs #{NODE_VERSION} diff --git a/.template/variants/web/Dangerfile.rb b/.template/variants/web/Dangerfile.rb index dda7c829..0fbc09ed 100644 --- a/.template/variants/web/Dangerfile.rb +++ b/.template/variants/web/Dangerfile.rb @@ -1,4 +1,6 @@ -insert_into_file 'Dangerfile', after: %r{suggester.suggest.*\n} do +# frozen_string_literal: true + +insert_into_file 'Dangerfile', after: /suggester.suggest.*\n/ do <<~RUBY # Runs ESLint on modified and added files in the PR diff --git a/.template/variants/web/Gemfile.rb b/.template/variants/web/Gemfile.rb index bcbedf77..98a0fd81 100644 --- a/.template/variants/web/Gemfile.rb +++ b/.template/variants/web/Gemfile.rb @@ -1,10 +1,12 @@ -insert_into_file 'Gemfile', after: %r{gem 'rails-i18n'.*\n} do +# frozen_string_literal: true + +insert_into_file 'Gemfile', after: /gem 'rails-i18n'.*\n/ do <<~RUBY gem 'i18n-js', '3.9.0' # A library to provide the I18n translations on the Javascript RUBY end -insert_into_file 'Gemfile', after: %r{gem 'pundit'.*\n} do +insert_into_file 'Gemfile', after: /gem 'pundit'.*\n/ do <<~RUBY # Assets @@ -21,13 +23,13 @@ # Group: :development, :test ############################ -insert_into_file 'Gemfile', after: %r{gem 'danger'.*\n} do +insert_into_file 'Gemfile', after: /gem 'danger'.*\n/ do <<~RUBY.indent(2) gem 'danger-eslint' # ESLint RUBY end -insert_into_file 'Gemfile', after: %r{gem 'spring-watcher-listen'.*\n} do +insert_into_file 'Gemfile', after: /gem 'spring-watcher-listen'.*\n/ do <<~RUBY.indent(2) # gem 'web-console' # Use console on exceptions pages RUBY @@ -37,7 +39,7 @@ # Group: :test ############## -insert_into_file 'Gemfile', after: %r{gem 'rspec-retry'.*\n} do +insert_into_file 'Gemfile', after: /gem 'rspec-retry'.*\n/ do <<~RUBY.indent(2) gem 'capybara' # Integration testing gem 'selenium-webdriver' # Ruby bindings for Selenium/WebDriver diff --git a/.template/variants/web/Procfile.dev.rb b/.template/variants/web/Procfile.dev.rb index ea2c2e0a..1199488c 100644 --- a/.template/variants/web/Procfile.dev.rb +++ b/.template/variants/web/Procfile.dev.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + append_to_file 'Procfile.dev' do <<~PROCFILE js: yarn build --watch diff --git a/.template/variants/web/app/controllers/concerns/localization.rb b/.template/variants/web/app/controllers/concerns/localization.rb index 9097fab5..bc32227e 100644 --- a/.template/variants/web/app/controllers/concerns/localization.rb +++ b/.template/variants/web/app/controllers/concerns/localization.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Localization extend ActiveSupport::Concern diff --git a/.template/variants/web/app/template.rb b/.template/variants/web/app/template.rb index 3ce9983c..d498d280 100644 --- a/.template/variants/web/app/template.rb +++ b/.template/variants/web/app/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Javascript directory 'app/javascript' diff --git a/.template/variants/web/config/application.rb b/.template/variants/web/config/application.rb index 52bea7fa..6f94e0f8 100644 --- a/.template/variants/web/config/application.rb +++ b/.template/variants/web/config/application.rb @@ -1,4 +1,6 @@ -insert_into_file 'config/application.rb', before: %r{ end\nend\Z} do +# frozen_string_literal: true + +insert_into_file 'config/application.rb', before: / end\nend\Z/ do <<~RUBY.indent(4) # Automatically generate the `translation.js` files diff --git a/.template/variants/web/config/environments/test.rb b/.template/variants/web/config/environments/test.rb index 4320779c..e19924de 100644 --- a/.template/variants/web/config/environments/test.rb +++ b/.template/variants/web/config/environments/test.rb @@ -1,11 +1,13 @@ -insert_into_file 'config/environments/test.rb', before: %r{Rails.application.configure do} do +# frozen_string_literal: true + +insert_into_file 'config/environments/test.rb', before: /Rails.application.configure do/ do <<~RUBY require_relative '../../spec/support/disable_animation' RUBY end -insert_into_file 'config/environments/test.rb', before: %r{^end} do +insert_into_file 'config/environments/test.rb', before: /^end/ do <<~RUBY.indent(2) # Disable all animation during tests diff --git a/.template/variants/web/config/initializers/assets.rb b/.template/variants/web/config/initializers/assets.rb index 9e7adc5d..9cebc86b 100644 --- a/.template/variants/web/config/initializers/assets.rb +++ b/.template/variants/web/config/initializers/assets.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + append_to_file 'config/initializers/assets.rb' do <<~RUBY diff --git a/.template/variants/web/config/template.rb b/.template/variants/web/config/template.rb index 90c8921d..ed8047b3 100644 --- a/.template/variants/web/config/template.rb +++ b/.template/variants/web/config/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + apply 'config/application.rb' copy_file 'config/i18n-js.yml' diff --git a/.template/variants/web/package.json.rb b/.template/variants/web/package.json.rb index 86f4851b..4f09de38 100644 --- a/.template/variants/web/package.json.rb +++ b/.template/variants/web/package.json.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Create package.json file unless File.exist?('package.json') create_file 'package.json', diff --git a/.template/variants/web/spec/codebase/codebase_spec.rb b/.template/variants/web/spec/codebase/codebase_spec.rb index 707a5905..33643fd1 100644 --- a/.template/variants/web/spec/codebase/codebase_spec.rb +++ b/.template/variants/web/spec/codebase/codebase_spec.rb @@ -1,4 +1,6 @@ -insert_into_file 'spec/codebase/codebase_spec.rb', before: %r{end\Z} do +# frozen_string_literal: true + +insert_into_file 'spec/codebase/codebase_spec.rb', before: /end\Z/ do <<~RUBY.indent(2) it 'does not offend stylelint' do diff --git a/.template/variants/web/spec/support/assets.rb b/.template/variants/web/spec/support/assets.rb index 5b88b129..85f0ba24 100644 --- a/.template/variants/web/spec/support/assets.rb +++ b/.template/variants/web/spec/support/assets.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.configure do |config| config.when_first_matching_example_defined(type: :system) do # On CI we use Docker and the assets are precompiled (in the Dockerfile) already diff --git a/.template/variants/web/spec/support/capybara.rb b/.template/variants/web/spec/support/capybara.rb index a611d511..318e13ee 100644 --- a/.template/variants/web/spec/support/capybara.rb +++ b/.template/variants/web/spec/support/capybara.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'selenium-webdriver' require 'capybara' require 'capybara/rspec' diff --git a/.template/variants/web/spec/support/disable_animation.rb b/.template/variants/web/spec/support/disable_animation.rb index 2427969b..4a3c0856 100644 --- a/.template/variants/web/spec/support/disable_animation.rb +++ b/.template/variants/web/spec/support/disable_animation.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Rack # disable CSS3 and jQuery animations in test mode for speed, consistency and avoiding timing issues. # Usage for Rails: diff --git a/.template/variants/web/spec/support/system.rb b/.template/variants/web/spec/support/system.rb index 146560fd..5001ae78 100644 --- a/.template/variants/web/spec/support/system.rb +++ b/.template/variants/web/spec/support/system.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.configure do |config| config.before(:each, type: :system) do # use headless_chrome, by default diff --git a/.template/variants/web/spec/support/webdrivers.rb b/.template/variants/web/spec/support/webdrivers.rb index 00d8bb1f..e0b9bcf9 100644 --- a/.template/variants/web/spec/support/webdrivers.rb +++ b/.template/variants/web/spec/support/webdrivers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Configure VCR and WebMock to work with webdrivers # https://github.com/titusfortner/webdrivers/wiki/Using-with-VCR-or-WebMock if defined?(VCR) diff --git a/.template/variants/web/spec/template.rb b/.template/variants/web/spec/template.rb index 6c9aceb0..b3da2a76 100644 --- a/.template/variants/web/spec/template.rb +++ b/.template/variants/web/spec/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + apply 'spec/codebase/codebase_spec.rb' directory 'spec/support' diff --git a/.template/variants/web/template.rb b/.template/variants/web/template.rb index d53af664..d1b20bae 100644 --- a/.template/variants/web/template.rb +++ b/.template/variants/web/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + def apply_web_variant! use_source_path __dir__ diff --git a/bin/docker-assets-precompile b/bin/docker-assets-precompile index 531cfd35..4db7630d 100755 --- a/bin/docker-assets-precompile +++ b/bin/docker-assets-precompile @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true # For building production docker image # diff --git a/bin/docker-prepare b/bin/docker-prepare index ef2819dc..c100ca0b 100755 --- a/bin/docker-prepare +++ b/bin/docker-prepare @@ -1,9 +1,11 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + require 'fileutils' # Copy the project dependencies to build the docker image -DOCKER_TMP_FOLDER = 'tmp/docker'.freeze -ENGINES_DIRECTORY = 'engines'.freeze +DOCKER_TMP_FOLDER = 'tmp/docker' +ENGINES_DIRECTORY = 'engines' FileUtils.rm_rf DOCKER_TMP_FOLDER FileUtils.mkdir DOCKER_TMP_FOLDER diff --git a/bin/template.rb b/bin/template.rb index da1f69a5..5750ea87 100644 --- a/bin/template.rb +++ b/bin/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + copy_file 'bin/envsetup.sh', mode: :preserve copy_file 'bin/start.sh', mode: :preserve copy_file 'bin/test.sh', mode: :preserve diff --git a/config/application.rb b/config/application.rb index a0257e42..3bd14b1b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,4 +1,6 @@ -insert_into_file 'config/application.rb', before: %r{ end\nend\Z} do +# frozen_string_literal: true + +insert_into_file 'config/application.rb', before: / end\nend\Z/ do <<~RUBY.indent(4) # Set the queuing backend to `Sidekiq` diff --git a/config/environments/development.rb b/config/environments/development.rb index 1ce84222..007a8aa5 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,4 +1,6 @@ -insert_into_file 'config/environments/development.rb', after: %r{config.action_mailer.perform_caching.+\n} do +# frozen_string_literal: true + +insert_into_file 'config/environments/development.rb', after: /config.action_mailer.perform_caching.+\n/ do <<~RUBY.indent(2) config.action_mailer.delivery_method = :letter_opener @@ -12,7 +14,7 @@ RUBY end -insert_into_file 'config/environments/development.rb', before: %r{^end} do +insert_into_file 'config/environments/development.rb', before: /^end/ do <<~RUBY.indent(2) # Configure Bullet gem to detect N+1 queries diff --git a/config/environments/production.rb b/config/environments/production.rb index 30c0023c..5f8fc7a0 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + # Allow Rails serve static file by default, this can be disable on Nginx addon gsub_file('config/environments/production.rb', "ENV['RAILS_SERVE_STATIC_FILES'].present?", 'true') -insert_into_file 'config/environments/production.rb', after: %r{config.action_mailer.perform_caching.+\n} do +insert_into_file 'config/environments/production.rb', after: /config.action_mailer.perform_caching.+\n/ do <<~RUBY.indent(2) config.action_mailer.asset_host = ENV.fetch('MAILER_DEFAULT_HOST') diff --git a/config/environments/test.rb b/config/environments/test.rb index b9b7d50c..38046c58 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,4 +1,6 @@ -insert_into_file 'config/environments/test.rb', after: %r{config.action_mailer.perform_caching.+\n} do +# frozen_string_literal: true + +insert_into_file 'config/environments/test.rb', after: /config.action_mailer.perform_caching.+\n/ do <<~RUBY.indent(2) config.action_mailer.default_url_options = { @@ -8,7 +10,7 @@ RUBY end -insert_into_file 'config/environments/test.rb', before: %r{^end} do +insert_into_file 'config/environments/test.rb', before: /^end/ do <<~RUBY.indent(2) # Configure Bullet gem to detect N+1 queries diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb index de18a28d..066f3929 100644 --- a/config/initializers/backtrace_silencers.rb +++ b/config/initializers/backtrace_silencers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Be sure to restart your server when you modify this file. # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. diff --git a/config/template.rb b/config/template.rb index ed8b687b..d73f28f8 100644 --- a/config/template.rb +++ b/config/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + apply 'config/application.rb' template 'config/application.yml.tt' diff --git a/spec/codebase/codebase_spec.rb b/spec/codebase/codebase_spec.rb index 0b53376c..fc457818 100644 --- a/spec/codebase/codebase_spec.rb +++ b/spec/codebase/codebase_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rails_helper' describe 'Codebase', codebase: true do diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 6efafcdd..4522b79a 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../config/environment', __dir__) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 71120aa1..b3e3304c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.configure do |config| config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true diff --git a/spec/support/bullet.rb b/spec/support/bullet.rb index a5912183..14ef20aa 100644 --- a/spec/support/bullet.rb +++ b/spec/support/bullet.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.configure do |config| if Bullet.enable? config.before(:each) do diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb index 4bb9ae82..a5ec2145 100644 --- a/spec/support/database_cleaner.rb +++ b/spec/support/database_cleaner.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.configure do |config| config.before(:suite) do DatabaseCleaner.strategy = :transaction diff --git a/spec/support/request_helpers.rb b/spec/support/request_helpers.rb index dcd1b0e0..589bacd4 100644 --- a/spec/support/request_helpers.rb +++ b/spec/support/request_helpers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Request module JsonHelpers def json_response diff --git a/spec/support/retry.rb b/spec/support/retry.rb index 798b00ac..f2cf40b0 100644 --- a/spec/support/retry.rb +++ b/spec/support/retry.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'rspec/retry' RSpec.configure do |config| diff --git a/spec/support/shoulda_matchers.rb b/spec/support/shoulda_matchers.rb index 7d045f35..edcf9dd8 100644 --- a/spec/support/shoulda_matchers.rb +++ b/spec/support/shoulda_matchers.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Shoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec diff --git a/spec/support/sidekiq.rb b/spec/support/sidekiq.rb index bba06318..501579fd 100644 --- a/spec/support/sidekiq.rb +++ b/spec/support/sidekiq.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'sidekiq/testing' RSpec.configure do |config| diff --git a/spec/support/simplecov.rb b/spec/support/simplecov.rb index 23bbe98a..ad5168b3 100644 --- a/spec/support/simplecov.rb +++ b/spec/support/simplecov.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'simplecov' require 'simplecov-json' require 'simplecov-lcov' diff --git a/spec/support/vcr.rb b/spec/support/vcr.rb index 1cfe6119..3b21a09f 100644 --- a/spec/support/vcr.rb +++ b/spec/support/vcr.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'vcr' VCR.configure do |c| diff --git a/spec/template.rb b/spec/template.rb index 31cafa8c..31fcc24d 100644 --- a/spec/template.rb +++ b/spec/template.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + generate 'rspec:install' directory 'spec', exclude_pattern: 'template.rb', force: true diff --git a/template.rb b/template.rb index 2b7eb8c0..541d2bd8 100644 --- a/template.rb +++ b/template.rb @@ -1,14 +1,16 @@ +# frozen_string_literal: true + require 'shellwords' # Variables APP_NAME = app_name # Transform the app name from slug to human-readable name e.g. nimble-web -> Nimble APP_NAME_HUMANIZED = app_name.split(/[-_]/).map(&:capitalize).join(' ').gsub(/ Web$/, '') -DOCKER_REGISTRY_HOST = 'docker.io'.freeze +DOCKER_REGISTRY_HOST = 'docker.io' DOCKER_IMAGE = "nimblehq/#{APP_NAME}".freeze -RUBY_VERSION = '3.0.1'.freeze -POSTGRES_VERSION = '12.1'.freeze -REDIS_VERSION = '5.0.7'.freeze +RUBY_VERSION = '3.0.1' +POSTGRES_VERSION = '12.1' +REDIS_VERSION = '5.0.7' # Variants API_VARIANT = options[:api] || ENV['API'] == 'true' WEB_VARIANT = !API_VARIANT @@ -19,8 +21,8 @@ }.freeze if WEB_VARIANT - NODE_VERSION = '16.13.2'.freeze - NODE_SOURCE_VERSION = '16'.freeze # Used in Dockerfile https://github.com/nodesource/distributions + NODE_VERSION = '16.13.2' + NODE_SOURCE_VERSION = '16' # Used in Dockerfile https://github.com/nodesource/distributions end def apply_template!(template_root) @@ -117,14 +119,9 @@ def install_addon_prompt(addon) end def post_default_addons_install - addons = '' - DEFAULT_ADDONS.each_value do |addon| - addons << "* #{addon}\n " - end - puts <<~INFO These default addons were installed: - #{addons} + #{DEFAULT_ADDONS.values.map { |addon| "* #{addon}" }.join("\n")} INFO end