diff --git a/.rubocop.yml b/.rubocop.yml index 75df1173..7299253b 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,3 +7,4 @@ AllCops: TargetRubyVersion: 3.3 Exclude: - "**/*_schema.rb" + - "lib/generators/solid_queue/update/templates/db/*" diff --git a/app/models/solid_queue/record.rb b/app/models/solid_queue/record.rb index 8617dc85..72da869d 100644 --- a/app/models/solid_queue/record.rb +++ b/app/models/solid_queue/record.rb @@ -24,6 +24,16 @@ def supports_insert_conflict_target? end end + def warn_about_pending_migrations + SolidQueue.deprecator.warn(<<~DEPRECATION) + Solid Queue has pending database migrations. To get the new migration files, run: + rails solid_queue:update + And then: + rails db:migrate + These migrations will be required after version #{SolidQueue.next_major_version}.0 + DEPRECATION + end + # Pass index hints to the query optimizer using SQL comment hints. # Uses MySQL 8 optimizer hint query comments, which SQLite and # PostgreSQL ignore. diff --git a/lib/generators/solid_queue/update/update_generator.rb b/lib/generators/solid_queue/update/update_generator.rb new file mode 100644 index 00000000..393991df --- /dev/null +++ b/lib/generators/solid_queue/update/update_generator.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require "rails/generators/active_record" + +class SolidQueue::UpdateGenerator < Rails::Generators::Base + include ActiveRecord::Generators::Migration + + source_root File.expand_path("templates", __dir__) + + class_option :database, type: :string, aliases: %i[ --db ], default: "queue", + desc: "The database that Solid Queue uses. Defaults to `queue`" + + def copy_new_migrations + Dir.glob(File.join(self.class.source_root, "db", "*.rb")).each do |migration_file| + name = File.basename(migration_file) + migration_template File.join("db", name), File.join(db_migrate_path, name), skip: true + end + end +end diff --git a/lib/solid_queue.rb b/lib/solid_queue.rb index edc90de9..eb77df68 100644 --- a/lib/solid_queue.rb +++ b/lib/solid_queue.rb @@ -86,6 +86,10 @@ def preserve_finished_jobs? preserve_finished_jobs end + def deprecator + @deprecator ||= ActiveSupport::Deprecation.new(next_major_version, "SolidQueue") + end + def instrument(channel, **options, &block) ActiveSupport::Notifications.instrument("#{channel}.solid_queue", **options, &block) end diff --git a/lib/solid_queue/engine.rb b/lib/solid_queue/engine.rb index 71a9cc1a..312107a4 100644 --- a/lib/solid_queue/engine.rb +++ b/lib/solid_queue/engine.rb @@ -43,5 +43,9 @@ class Engine < ::Rails::Engine include ActiveJob::ConcurrencyControls end end + + initializer "solid_queue.deprecator" do |app| + app.deprecators[:solid_queue] = SolidQueue.deprecator + end end end diff --git a/lib/solid_queue/tasks.rb b/lib/solid_queue/tasks.rb index 70422562..c3989a3b 100644 --- a/lib/solid_queue/tasks.rb +++ b/lib/solid_queue/tasks.rb @@ -4,6 +4,11 @@ Rails::Command.invoke :generate, [ "solid_queue:install" ] end + desc "Copy any new Solid Queue migrations to the application" + task :update do + Rails::Command.invoke :generate, [ "solid_queue:update" ] + end + desc "start solid_queue supervisor to dispatch and process jobs" task start: :environment do SolidQueue::Supervisor.start diff --git a/lib/solid_queue/version.rb b/lib/solid_queue/version.rb index da6b7c90..967d4cc4 100644 --- a/lib/solid_queue/version.rb +++ b/lib/solid_queue/version.rb @@ -1,3 +1,7 @@ module SolidQueue VERSION = "1.5.0" + + def self.next_major_version + Gem::Version.new(VERSION).segments.first + 1 + end end diff --git a/test/unit/update_generator_test.rb b/test/unit/update_generator_test.rb new file mode 100644 index 00000000..6a59ff5a --- /dev/null +++ b/test/unit/update_generator_test.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "test_helper" +require "rails/generators/test_case" +require "generators/solid_queue/update/update_generator" + +class UpdateGeneratorTest < Rails::Generators::TestCase + tests SolidQueue::UpdateGenerator + destination Rails.root.join("tmp/update_generator_test") + setup :prepare_destination + + test "copies new migrations to the queue database migrations path" do + with_migration_template("add_batches_to_solid_queue") do + run_generator + + assert_migration "db/queue_migrate/add_batches_to_solid_queue.rb" do |migration| + assert_match(/class AddBatchesToSolidQueue/, migration) + end + end + end + + test "copies new migrations to another database's migrations path" do + with_migration_template("add_batches_to_solid_queue") do + run_generator %w[ --database primary ] + + assert_migration "db/migrate/add_batches_to_solid_queue.rb" + end + end + + test "skips migrations that have already been copied" do + with_migration_template("add_batches_to_solid_queue") do + run_generator + run_generator + + assert_equal 1, Dir.glob(File.join(destination_root, "db/queue_migrate/*_add_batches_to_solid_queue.rb")).count + end + end + + test "does nothing when there are no new migrations" do + run_generator + + assert_empty Dir.glob(File.join(destination_root, "db/**/*.rb")) + end + + private + def with_migration_template(name) + Dir.mktmpdir do |source_root| + FileUtils.mkdir_p File.join(source_root, "db") + File.write File.join(source_root, "db", "#{name}.rb"), <<~MIGRATION + class #{name.camelize} < ActiveRecord::Migration[7.1] + def change + end + end + MIGRATION + + SolidQueue::UpdateGenerator.stubs(:source_root).returns(source_root) + yield + end + end +end