From ff9e7e2c4824882aac2f1faa6fdda3c80fc95a79 Mon Sep 17 00:00:00 2001 From: Steve Polito Date: Fri, 10 Nov 2023 10:00:11 -0500 Subject: [PATCH] Introduce `suspenders:rake` generator Closes #1138 Closes #1143 Consolidates logic from the existing [advisories][] and [lint][] generators to create a default Rake task that audits and lints the codebase. We do this because it's simpler to bundle this configuration together, rather than have two separate generators compete to modify the default Rake task, since those generators can be run independently. [advisories]: https://github.com/thoughtbot/suspenders/blob/main/lib/suspenders/generators/advisories_generator.rb [lint]: https://github.com/thoughtbot/suspenders/blob/main/lib/suspenders/generators/lint_generator.rb --- lib/generators/suspenders/rake_generator.rb | 22 +++++ .../templates/rake/bundler_audit.rake | 4 + .../suspenders/rake_generator_test.rb | 91 +++++++++++++++++++ test/test_helper.rb | 2 - 4 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 lib/generators/suspenders/rake_generator.rb create mode 100644 lib/generators/templates/rake/bundler_audit.rake create mode 100644 test/generators/suspenders/rake_generator_test.rb diff --git a/lib/generators/suspenders/rake_generator.rb b/lib/generators/suspenders/rake_generator.rb new file mode 100644 index 000000000..fb3aa05cb --- /dev/null +++ b/lib/generators/suspenders/rake_generator.rb @@ -0,0 +1,22 @@ +module Suspenders + module Generators + class RakeGenerator < Rails::Generators::Base + source_root File.expand_path("../../templates/rake", __FILE__) + + def add_bundler_audit_and_standard + gem_group :development, :test do + gem "bundler-audit", ">= 0.7.0", require: false + gem "standard" + end + Bundler.with_unbundled_env { run "bundle install" } + end + + def configurea_rake_task + copy_file "bundler_audit.rake", "lib/tasks/bundler_audit.rake" + + insert_into_file "Rakefile", "\nrequire \"standard\/rake\"", after: "require_relative \"config\/application\"" + append_file "Rakefile", %(\ntask default: %i[bundle:audit standard]\n) + end + end + end +end diff --git a/lib/generators/templates/rake/bundler_audit.rake b/lib/generators/templates/rake/bundler_audit.rake new file mode 100644 index 000000000..72f6b5120 --- /dev/null +++ b/lib/generators/templates/rake/bundler_audit.rake @@ -0,0 +1,4 @@ +if Rails.env.development? || Rails.env.test? + require "bundler/audit/task" + Bundler::Audit::Task.new +end diff --git a/test/generators/suspenders/rake_generator_test.rb b/test/generators/suspenders/rake_generator_test.rb new file mode 100644 index 000000000..92180b84c --- /dev/null +++ b/test/generators/suspenders/rake_generator_test.rb @@ -0,0 +1,91 @@ +require "test_helper" +require "generators/suspenders/rake_generator" + +module Suspenders + module Generators + class RakeGeneratorTest < Rails::Generators::TestCase + include Suspenders::TestHelpers + + tests Suspenders::Generators::RakeGenerator + destination Rails.root + setup :prepare_destination + teardown :restore_destination + + test "adds gems to Gemfile" do + expected_output = <<~RUBY + group :development, :test do + gem "bundler-audit", ">= 0.7.0", require: false + gem "standard" + end + RUBY + + run_generator + + assert_file app_root("Gemfile") do |file| + assert_match(expected_output, file) + end + end + + test "installs gems with Bundler" do + Bundler.stubs(:with_unbundled_env).yields + generator.expects(:run).with("bundle install").once + + capture(:stdout) do + generator.add_bundler_audit_and_standard + end + end + + test "creates custom Rake task" do + expected_rake_task = <<~RUBY + if Rails.env.development? || Rails.env.test? + require "bundler/audit/task" + Bundler::Audit::Task.new + end + RUBY + + run_generator + + assert_file app_root("lib/tasks/bundler_audit.rake") do |file| + assert_match expected_rake_task, file + end + end + + test "modifies existing Rakefile" do + rakefile = <<~RUBY + require_relative "config/application" + + Rails.application.load_tasks + RUBY + File.open(app_root("Rakefile"), "w") { _1.write rakefile } + + expected_rakefile = <<~RUBY + require_relative "config/application" + require "standard/rake" + + Rails.application.load_tasks + + task default: %i[bundle:audit standard] + RUBY + + run_generator + + assert_file app_root("Rakefile") do |file| + assert_equal expected_rakefile, file + end + end + + private + + def prepare_destination + touch "Gemfile" + backup_file "Rakefile" + end + + def restore_destination + remove_file_if_exists "Gemfile" + remove_file_if_exists "lib/tasks/bundler_audit.rake" + restore_file "Rakefile" + end + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 060d7dc22..3fb50d589 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -68,8 +68,6 @@ class Application < Rails::Application restore_file "config/application.rb" end - private - def backup_file(file) FileUtils.mv app_root(file), app_root("#{file}.bak") touch file