From 383cda469331afca9fdc725bf233c0bf20665ea6 Mon Sep 17 00:00:00 2001 From: Steve Polito Date: Sun, 14 Apr 2024 15:49:58 -0400 Subject: [PATCH] Introduce `suspenders:install:web` generator and application template (#1152) Create generator to invoke all necessary generators. We add it to the `install` namespace to provide flexibility should we add other installation options, such as ones for API Only applications. Introduces [template][] as a means to invoke `suspenders:install:web` when creating a new application. This serves as an alternative to the system executable that was removed. We call `db:prepare` in the template to ensure `bin/setup` works as expected. This is because we overrode that file to use `dev:prime`, which assume the database has been created. [template]: https://guides.rubyonrails.org/rails_application_templates.html --- NEWS.md | 1 + README.md | 12 +++- .../suspenders/install/web_generator.rb | 67 +++++++++++++++++++ lib/install/web.rb | 32 +++++++++ .../suspenders/install/web_generator_test.rb | 43 ++++++++++++ 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 lib/generators/suspenders/install/web_generator.rb create mode 100644 lib/install/web.rb create mode 100644 test/generators/suspenders/install/web_generator_test.rb diff --git a/NEWS.md b/NEWS.md index ffbcd6a04..a0d4f187b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,7 @@ Unreleased * Introduce `suspenders:environments:production` generator * Introduce `suspenders:environments:test` generator * Introduce `suspenders:environments:development` generator +* Introduce `suspenders:install:web` generator 20230113.0 (January, 13, 2023) diff --git a/README.md b/README.md index 211ade75a..a56c457e9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ if you like missing deadlines. ## Usage +### Existing Rails Applications + ``` group :development, :test do gem "suspenders" @@ -16,7 +18,15 @@ end ``` ``` -bin/rails g suspenders:all +bin/rails g suspenders:install:web +``` + +### New Rails Applications + +``` +rails new my_app \ +-d=postgresql \ +-m=https://raw.githubusercontent.com/thoughtbot/suspenders/lib/install/web.rb ``` ## Generators diff --git a/lib/generators/suspenders/install/web_generator.rb b/lib/generators/suspenders/install/web_generator.rb new file mode 100644 index 000000000..83427ca6d --- /dev/null +++ b/lib/generators/suspenders/install/web_generator.rb @@ -0,0 +1,67 @@ +module Suspenders + module Generators + module Install + class WebGenerator < Rails::Generators::Base + include Suspenders::Generators::APIAppUnsupported + include Suspenders::Generators::DatabaseUnsupported + + desc <<~MARKDOWN + Invokes all necessary generators for new Rails applications generated with Suspenders. + + This generatator is intended to be invoked as part of an [application template][]. + + ``` + rails new suspenders_qa \ + --skip-test \ + -d=postgresql \ + -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb + ``` + + [application template]: https://guides.rubyonrails.org/rails_application_templates.html + MARKDOWN + + def invoke_generators + # This needs to go first, since it configures `.node-version` + generate "suspenders:prerequisites" + + generate "suspenders:accessibility" + generate "suspenders:advisories" + generate "suspenders:email" + generate "suspenders:factories" + generate "suspenders:inline_svg" + generate "suspenders:lint" + generate "suspenders:rake" + generate "suspenders:setup" + generate "suspenders:tasks" + generate "suspenders:testing" + generate "suspenders:views" + + # suspenders:jobs needs to be invoked before suspenders:styles, since + # suspenders:styles generator creates Procfile.dev + generate "suspenders:styles" + generate "suspenders:jobs" + + # Needs to run after other generators, since some touch the + # configuration files. + generate "suspenders:environments:test" + generate "suspenders:environments:development" + generate "suspenders:environments:production" + + # Needs to be run last since it depends on lint, testing, and + # advisories + generate "suspenders:ci" + end + + def cleanup + rake "suspenders:cleanup:organize_gemfile" + rake "suspenders:cleanup:generate_readme" + end + + def lint + run "yarn run fix:prettier" + run "bundle exec rake standard:fix_unsafely" + end + end + end + end +end diff --git a/lib/install/web.rb b/lib/install/web.rb new file mode 100644 index 000000000..fb28332ee --- /dev/null +++ b/lib/install/web.rb @@ -0,0 +1,32 @@ +def apply_template! + if options[:database] == "postgresql" && options[:skip_test] + after_bundle do + gem_group :development, :test do + # TODO: Update once in `main` + gem "suspenders", github: "thoughtbot/suspenders", branch: "suspenders-3-0-0" + end + + run "bundle install" + + generate "suspenders:install:web" + rails_command "db:prepare" + + say "\nCongratulations! You just pulled our suspenders." + end + else + message = <<~ERROR + + + === Please use the correct options === + + rails new \\ + --skip-test \\ + -d=postgresql \\ + -m=https://raw.githubusercontent.com/thoughtbot/suspenders/main/lib/install/web.rb + ERROR + + fail Rails::Generators::Error, message + end +end + +apply_template! diff --git a/test/generators/suspenders/install/web_generator_test.rb b/test/generators/suspenders/install/web_generator_test.rb new file mode 100644 index 000000000..5c7ff4be1 --- /dev/null +++ b/test/generators/suspenders/install/web_generator_test.rb @@ -0,0 +1,43 @@ +require "test_helper" +require "generators/suspenders/install/web_generator" + +module Suspenders + module Generators + module Install + class WebGeneratorTest < Rails::Generators::TestCase + include Suspenders::TestHelpers + + tests Suspenders::Generators::Install::WebGenerator + destination Rails.root + setup :prepare_destination + teardown :restore_destination + + test "raises if API only application" do + within_api_only_app do + assert_raises Suspenders::Generators::APIAppUnsupported::Error do + run_generator + end + end + end + + test "raises if PostgreSQL is not the adapter" do + with_database "unsupported" do + assert_raises Suspenders::Generators::DatabaseUnsupported::Error do + run_generator + end + end + end + + private + + def prepare_destination + touch "Gemfile" + end + + def restore_destination + remove_file_if_exists "Gemfile" + end + end + end + end +end