Squasher

repository·master·Indexed 23 days ago

https://github.com/jalkoby/squasher

A utility for compressing large histories of ActiveRecord migrations into a single migration representing the database state at a specific point in time. It reduces overhead for running migrations and creating new databases in long-lived projects. Supports Rails 3, 4, and 5+, as well as SQL schemas and Rails engines. Requires Ruby 2.0+ and ActiveRecord 3.1+.

Tokens
2.7K
Snippets
1
Records
20
Agent score
78%

What's inside squasher

  1. Squasher requirements and data considerations

    master

    Requirements

    • Ruby: 2.0+
    • ActiveRecord: 3.1+
    • Configuration: A valid development configuration in config/database.yml.

    Data Handling

    If your old migrations contained code that inserted data (e.g., creating ActiveRecord model records), that code will be lost in the squashed migration.

    However, squasher will prompt you to leave a temporary database containing all data inserted during the migration process. You can use this temporary database to:

    1. Add the data as a new migration.
    2. Add the data to config/seed.rb (the recommended location for such data).
  2. Compress ActiveRecord migrations with Squasher

    master

    Squasher compresses old ActiveRecord migrations by removing individual migration files and replacing them with a single migration that represents the final database state as of a specific date. This speeds up rake db:migrate and database creation in large projects.

    Important: Stop all preloading systems (like spring or zeus) before running Squasher.

    Usage by Rails version:

    • Rails 3 & 4: Pass the year as an argument.
    • Rails 5+: Pass the year and use the -m flag followed by the Rails version.

    Date Formats:

    • Year only: 2017
    • Year and Month: 2016/12 (prior to December 2016)
    • Full Date: 2016/12/19 (prior to 19 December 2016)

    Warning for older versions: If you are using a version prior to 0.6.2, upgrade immediately. Versions before 0.6.2 could damage real data by generating "force" tables. If you have already used an older version, manually clean the force tag from the initial migration.

  3. Install Squasher

    master

    You can install Squasher as a standalone tool or include it in your application's Gemfile.

    Standalone installation:

    $ gem install squasher

    Note: If using Rbenv, run rbenv rehash after installation.

    Gemfile integration: Add it to a utility group (e.g., :tools) to share it with your application environment:

    group :tools do
      gem 'squasher', '>= 0.6.0'
      gem 'capistrano'
      gem 'rubocop'
    end

    After adding to the Gemfile, run bundle.

    To create a runner inside your application's bin folder, run:

    $ bundle binstub squasher
    $ bin/squasher
  4. How Squasher handles database configuration (database.yml)

    master

    Squasher automatically locates and processes your config/database.yml file.

    Multi-DB Formats

    • 'rails' format: Squasher expects a development key in database.yml. It will attempt to merge your configured :databases into the development section, redirecting them to use a [database_name]_squasher database name to avoid conflicts.
    • 'multiverse' format: Squasher looks for top-level keys in database.yml corresponding to your configured :databases list.

    Stubbing database.yml

    To prevent Squasher from accidentally modifying your real database configuration during operations, you can use stub_dbconfig. This method temporarily renames your existing database.yml and schema files (adding a .sq extension), writes a temporary Squasher-specific database.yml, executes the provided block, and then restores the original files.

  5. Squasher command options

    master

    The squasher command supports several modes of operation. Run squasher -h or simply squasher to view the full help menu. Supported modes include:

    • SQL schema rails app: For apps using SQL schema.
    • Rails 5+ app: Specific handling for Rails 5+ migrations.
    • Inside an engine: For use within Rails engines.
    • Dry mode: To preview changes without applying them.
    • Reuse mode: To reuse existing structures.
  6. Run the Squasher process programmatically with Squasher::Worker.process

    master

    You can trigger the squashing orchestration manually in Ruby by calling Squasher::Worker.process. This method handles the entire lifecycle: checking for migrations, stubbing the database configuration, dropping/recreating the database, migrating to the latest squashed state, and cleaning up old migration files.

    Note that process requires a date argument to determine which migrations are considered 'old' and eligible for squashing. The date is used to calculate a timestamp threshold.

  7. Configure Squasher settings

    master

    Use the Squasher::Config#set(key, value) method to configure the Squasher environment. The configuration supports several specific keys that control how Squasher interacts with your Rails application and database structure:

    • :engine: Sets the application root path. If provided, Squasher searches for config/application.rb within that path to determine the app root. If nil, it defaults to the current working directory.
    • :migration: Sets the migration version format. The value must match the pattern X.Y (e.g., 0.8). This is stored internally as [X.Y].
    • :multi_db_format: Defines how multiple databases are handled. Valid values are 'rails' or 'multiverse'.
    • :databases: An array of database names to be used when working with multiple databases.

    Any other keys passed to set are treated as internal flags.

  8. Configure Squasher with setup()

    master
    Use Squasher.setup(options) to initialize the library's configuration. The options argument should be an enumerable of key-value pairs (e.g., a Hash) where each key is a configuration setting and each value is its corresponding value. These settings are applied to the internal Squasher.config object.
  9. Run Rake tasks via rake()

    master

    The Squasher.rake(command, description = nil) method allows you to execute Rake commands within the application's root directory. It automatically sets the following environment variables:

    • RAILS_ENV: development
    • DISABLE_DATABASE_ENVIRONMENT_CHECK: 1

    If a description is provided, it will be printed to the console before the command is executed. The command is run using bundle exec rake.

  10. Display messages and errors

    master

    Squasher provides several methods for console output:

    • Squasher.tell(key, options = {}): Fetches a predefined message from messages.yml using the provided key and prints it. Supports colorization using a custom syntax.
    • Squasher.print(message, options = {}): Prints a message, optionally using string formatting if options are provided.
    • Squasher.error(*args): Prints a message using tell and then immediately calls abort to terminate the process.