From d6e5481af49392619cdc66eda1d8500007980bf9 Mon Sep 17 00:00:00 2001 From: Mane Darbinyan <122614161+m-darbinyan@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:01:17 +0400 Subject: [PATCH] Add a rake task that installs the gem (#121) --- README.md | 20 +++++++++--- actual_db_schema.gemspec | 8 ++--- lib/actual_db_schema.rb | 12 +++---- lib/actual_db_schema/configuration.rb | 32 +++++++++++++++++++ .../templates/actual_db_schema.rb | 23 +++++++++++++ lib/tasks/actual_db_schema.rake | 30 ++++++++++++++++- 6 files changed, 109 insertions(+), 16 deletions(-) create mode 100644 lib/actual_db_schema/configuration.rb create mode 100644 lib/generators/actual_db_schema/templates/actual_db_schema.rb diff --git a/README.md b/README.md index 1444741..40332c0 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,16 @@ And then execute: If you cannot commit changes to the repo or Gemfile, consider the local Gemfile installation described in [this post](https://blog.widefix.com/personal-gemfile-for-development/). +Next, generate your ActualDbSchema initializer file by running: + +```sh +rake actual_db_schema:install +``` + +This will create a `config/initializers/actual_db_schema.rb` file with all the available configuration options so you can adjust them as needed. It will also prompt you to install the post-checkout Git hook for automatic phantom migration rollback when switching branches. + +For more details on the available configuration options, see the sections below. + ## Usage Just run `rails db:migrate` inside the current branch. It will roll back all phantom migrations for all configured databases in your `database.yml.` @@ -86,7 +96,7 @@ export ACTUAL_DB_SCHEMA_UI_ENABLED=true Add the following line to your initializer file (`config/initializers/actual_db_schema.rb`): ```ruby -ActualDbSchema.config[:ui_enabled] = true +config.ui_enabled = true ``` > With this option, the UI can be disabled for all environments or be enabled in specific ones. @@ -107,7 +117,7 @@ export ACTUAL_DB_SCHEMA_AUTO_ROLLBACK_DISABLED=true Add the following line to your initializer file (`config/initializers/actual_db_schema.rb`): ```ruby -ActualDbSchema.config[:auto_rollback_disabled] = true +config.auto_rollback_disabled = true ``` ## Automatic Phantom Migration Rollback On Branch Switch @@ -126,7 +136,7 @@ export ACTUAL_DB_SCHEMA_GIT_HOOKS_ENABLED=true Add the following line to your initializer file (`config/initializers/actual_db_schema.rb`): ```ruby -ActualDbSchema.config[:git_hooks_enabled] = true +config.git_hooks_enabled = true ``` ### Installing the Post-Checkout Hook @@ -149,13 +159,13 @@ Based on your selection, a post-checkout hook will be installed or updated in yo If your application leverages multiple schemas for multi-tenancy — such as those implemented by the [apartment](https://github.com/influitive/apartment) gem or similar solutions — you can configure ActualDbSchema to handle migrations across all schemas. To do so, add the following configuration to your initializer file (`config/initializers/actual_db_schema.rb`): ```ruby -ActualDbSchema.config[:multi_tenant_schemas] = -> { # list of all active schemas } +config.multi_tenant_schemas = -> { # list of all active schemas } ``` ### Example: ```ruby -ActualDbSchema.config[:multi_tenant_schemas] = -> { ["public", "tenant1", "tenant2"] } +config.multi_tenant_schemas = -> { ["public", "tenant1", "tenant2"] } ``` ## Development diff --git a/actual_db_schema.gemspec b/actual_db_schema.gemspec index b37a341..bbaf1f9 100644 --- a/actual_db_schema.gemspec +++ b/actual_db_schema.gemspec @@ -47,10 +47,10 @@ Gem::Specification.new do |spec| spec.post_install_message = <<~MSG Thank you for installing ActualDbSchema! - To enable automatic rollback of phantom migrations when switching branches, follow these steps: - 1. Set `export ACTUAL_DB_SCHEMA_GIT_HOOKS_ENABLED=true` in your environment, OR - add `ActualDbSchema.config[:git_hooks_enabled] = true` to your initializer. - 2. Run `rake actual_db_schema:install_git_hooks` to install the post-checkout Git hook. + Next steps: + 1. Run `rake actual_db_schema:install` to generate the initializer file and install + the post-checkout Git hook for automatic phantom migration rollback when switching branches. + 2. Or, if you prefer environment variables, skip this step. For more information, see the README. diff --git a/lib/actual_db_schema.rb b/lib/actual_db_schema.rb index b177ab2..ce281b0 100644 --- a/lib/actual_db_schema.rb +++ b/lib/actual_db_schema.rb @@ -4,6 +4,7 @@ require "active_record/migration" require "csv" require_relative "actual_db_schema/git" +require_relative "actual_db_schema/configuration" require_relative "actual_db_schema/store" require_relative "actual_db_schema/version" require_relative "actual_db_schema/migration" @@ -29,12 +30,11 @@ class << self end self.failed = [] - self.config = { - enabled: Rails.env.development?, - auto_rollback_disabled: ENV["ACTUAL_DB_SCHEMA_AUTO_ROLLBACK_DISABLED"].present?, - ui_enabled: Rails.env.development? || ENV["ACTUAL_DB_SCHEMA_UI_ENABLED"].present?, - git_hooks_enabled: ENV["ACTUAL_DB_SCHEMA_GIT_HOOKS_ENABLED"].present? - } + self.config = Configuration.new + + def self.configure + yield(config) + end def self.migrated_folder migrated_folders.first diff --git a/lib/actual_db_schema/configuration.rb b/lib/actual_db_schema/configuration.rb new file mode 100644 index 0000000..58c307c --- /dev/null +++ b/lib/actual_db_schema/configuration.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module ActualDbSchema + # Manages the configuration settings for the gem. + class Configuration + attr_accessor :enabled, :auto_rollback_disabled, :ui_enabled, :git_hooks_enabled, :multi_tenant_schemas + + def initialize + @enabled = Rails.env.development? + @auto_rollback_disabled = ENV["ACTUAL_DB_SCHEMA_AUTO_ROLLBACK_DISABLED"].present? + @ui_enabled = Rails.env.development? || ENV["ACTUAL_DB_SCHEMA_UI_ENABLED"].present? + @git_hooks_enabled = ENV["ACTUAL_DB_SCHEMA_GIT_HOOKS_ENABLED"].present? + @multi_tenant_schemas = nil + end + + def [](key) + public_send(key) + end + + def []=(key, value) + public_send("#{key}=", value) + end + + def fetch(key, default = nil) + if respond_to?(key) + public_send(key) + else + default + end + end + end +end diff --git a/lib/generators/actual_db_schema/templates/actual_db_schema.rb b/lib/generators/actual_db_schema/templates/actual_db_schema.rb new file mode 100644 index 0000000..dae3b9c --- /dev/null +++ b/lib/generators/actual_db_schema/templates/actual_db_schema.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# ActualDbSchema initializer +# Adjust the configuration as needed. + +ActualDbSchema.configure do |config| + # Enable the gem. + config.enabled = Rails.env.development? + + # Disable automatic rollback of phantom migrations. + # config.auto_rollback_disabled = true + config.auto_rollback_disabled = ENV["ACTUAL_DB_SCHEMA_AUTO_ROLLBACK_DISABLED"].present? + + # Enable the UI for managing migrations. + config.ui_enabled = Rails.env.development? || ENV["ACTUAL_DB_SCHEMA_UI_ENABLED"].present? + + # Enable automatic phantom migration rollback on branch switch, + # config.git_hooks_enabled = true + config.git_hooks_enabled = ENV["ACTUAL_DB_SCHEMA_GIT_HOOKS_ENABLED"].present? + + # If your application leverages multiple schemas for multi-tenancy, define the active schemas. + # config.multi_tenant_schemas = -> { ["public", "tenant1", "tenant2"] } +end diff --git a/lib/tasks/actual_db_schema.rake b/lib/tasks/actual_db_schema.rake index 4823fa4..244385c 100644 --- a/lib/tasks/actual_db_schema.rake +++ b/lib/tasks/actual_db_schema.rake @@ -1,6 +1,34 @@ # frozen_string_literal: true -namespace :actual_db_schema do +namespace :actual_db_schema do # rubocop:disable Metrics/BlockLength + desc "Install ActualDbSchema initializer and post-checkout git hook." + task :install do + extend ActualDbSchema::OutputFormatter + + initializer_path = Rails.root.join("config", "initializers", "actual_db_schema.rb") + initializer_content = File.read( + File.expand_path("../../lib/generators/actual_db_schema/templates/actual_db_schema.rb", __dir__) + ) + + if File.exist?(initializer_path) + puts colorize("[ActualDbSchema] An initializer already exists at #{initializer_path}.", :gray) + puts "Overwrite the existing file at #{initializer_path}? [y,n] " + answer = $stdin.gets.chomp.downcase + + if answer.start_with?("y") + File.write(initializer_path, initializer_content) + puts colorize("[ActualDbSchema] Initializer updated successfully at #{initializer_path}", :green) + else + puts colorize("[ActualDbSchema] Skipped overwriting the initializer.", :yellow) + end + else + File.write(initializer_path, initializer_content) + puts colorize("[ActualDbSchema] Initializer created successfully at #{initializer_path}", :green) + end + + Rake::Task["actual_db_schema:install_git_hooks"].invoke + end + desc "Install ActualDbSchema post-checkout git hook that rolls back phantom migrations when switching branches." task :install_git_hooks do extend ActualDbSchema::OutputFormatter