safe_migrations 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7650ddb667009ee039677b92f7bb557db0f92b9b12441ff96de8bf9c512d6bb3
4
+ data.tar.gz: c3248fee222eb0a13a332aa234719f16947f93e05a5cf4250f4f8a16f066ebb9
5
+ SHA512:
6
+ metadata.gz: 47cdc90dee9cd19aa2ae5968c596cc8a77d0b30b7123693946bed97de9ed3083c8bfd2a66166ba0ac75c0d74a82418adb5788c5d28a20796e8503669da2c9399
7
+ data.tar.gz: 34f0f835de314a7311bebc89a48f413c58020d0f0ff90b4a738a26fe2e4d854816c9bb9af8029499d3f140a3c606a7b422ab0dce4f7763ae49a2101b38c97934
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,2 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.2
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2.9
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.10
7
+ before_install: gem install bundler -v 1.17.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [1.0.0] - 2025-10-24
8
+
9
+ ### Added
10
+ - Initial release of CHANGELOG.md, the all-in-one safe rails migrations.
11
+
12
+
13
+ ### Changed
14
+ - N/A (initial release)
15
+
16
+ [1.0.0]: https://github.com/moskvin/safe_migrations/releases/tag/v1.0.0
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in safe_migrations.gemspec
8
+ gemspec
9
+
10
+ group :test do
11
+ gem 'rspec', '~> 3.12'
12
+ gem 'sqlite3', '~> 2.7'
13
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,124 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ safe_migrations (1.0.0)
5
+ activerecord (>= 7.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (8.1.0)
11
+ activesupport (= 8.1.0)
12
+ activerecord (8.1.0)
13
+ activemodel (= 8.1.0)
14
+ activesupport (= 8.1.0)
15
+ timeout (>= 0.4.0)
16
+ activesupport (8.1.0)
17
+ base64
18
+ bigdecimal
19
+ concurrent-ruby (~> 1.0, >= 1.3.1)
20
+ connection_pool (>= 2.2.5)
21
+ drb
22
+ i18n (>= 1.6, < 2)
23
+ json
24
+ logger (>= 1.4.2)
25
+ minitest (>= 5.1)
26
+ securerandom (>= 0.3)
27
+ tzinfo (~> 2.0, >= 2.0.5)
28
+ uri (>= 0.13.1)
29
+ ast (2.4.3)
30
+ base64 (0.3.0)
31
+ bigdecimal (3.3.1)
32
+ concurrent-ruby (1.3.5)
33
+ connection_pool (2.5.4)
34
+ diff-lcs (1.6.2)
35
+ drb (2.2.3)
36
+ i18n (1.14.7)
37
+ concurrent-ruby (~> 1.0)
38
+ json (2.15.1)
39
+ language_server-protocol (3.17.0.5)
40
+ lint_roller (1.1.0)
41
+ logger (1.7.0)
42
+ mini_portile2 (2.8.9)
43
+ minitest (5.26.0)
44
+ parallel (1.27.0)
45
+ parser (3.3.9.0)
46
+ ast (~> 2.4.1)
47
+ racc
48
+ prism (1.6.0)
49
+ racc (1.8.1)
50
+ rainbow (3.1.1)
51
+ rake (13.3.0)
52
+ regexp_parser (2.11.3)
53
+ rspec (3.13.2)
54
+ rspec-core (~> 3.13.0)
55
+ rspec-expectations (~> 3.13.0)
56
+ rspec-mocks (~> 3.13.0)
57
+ rspec-core (3.13.6)
58
+ rspec-support (~> 3.13.0)
59
+ rspec-expectations (3.13.5)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.13.0)
62
+ rspec-mocks (3.13.6)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.13.0)
65
+ rspec-support (3.13.6)
66
+ rubocop (1.81.6)
67
+ json (~> 2.3)
68
+ language_server-protocol (~> 3.17.0.2)
69
+ lint_roller (~> 1.1.0)
70
+ parallel (~> 1.10)
71
+ parser (>= 3.3.0.2)
72
+ rainbow (>= 2.2.2, < 4.0)
73
+ regexp_parser (>= 2.9.3, < 3.0)
74
+ rubocop-ast (>= 1.47.1, < 2.0)
75
+ ruby-progressbar (~> 1.7)
76
+ unicode-display_width (>= 2.4.0, < 4.0)
77
+ rubocop-ast (1.47.1)
78
+ parser (>= 3.3.7.2)
79
+ prism (~> 1.4)
80
+ ruby-progressbar (1.13.0)
81
+ securerandom (0.4.1)
82
+ sqlite3 (2.7.4)
83
+ mini_portile2 (~> 2.8.0)
84
+ sqlite3 (2.7.4-aarch64-linux-gnu)
85
+ sqlite3 (2.7.4-aarch64-linux-musl)
86
+ sqlite3 (2.7.4-arm-linux-gnu)
87
+ sqlite3 (2.7.4-arm-linux-musl)
88
+ sqlite3 (2.7.4-arm64-darwin)
89
+ sqlite3 (2.7.4-x86-linux-gnu)
90
+ sqlite3 (2.7.4-x86-linux-musl)
91
+ sqlite3 (2.7.4-x86_64-darwin)
92
+ sqlite3 (2.7.4-x86_64-linux-gnu)
93
+ sqlite3 (2.7.4-x86_64-linux-musl)
94
+ timeout (0.4.3)
95
+ tzinfo (2.0.6)
96
+ concurrent-ruby (~> 1.0)
97
+ unicode-display_width (3.2.0)
98
+ unicode-emoji (~> 4.1)
99
+ unicode-emoji (4.1.0)
100
+ uri (1.0.4)
101
+
102
+ PLATFORMS
103
+ aarch64-linux-gnu
104
+ aarch64-linux-musl
105
+ arm-linux-gnu
106
+ arm-linux-musl
107
+ arm64-darwin
108
+ ruby
109
+ x86-linux-gnu
110
+ x86-linux-musl
111
+ x86_64-darwin
112
+ x86_64-linux-gnu
113
+ x86_64-linux-musl
114
+
115
+ DEPENDENCIES
116
+ bundler (~> 2.7)
117
+ rake (~> 13.0)
118
+ rspec (~> 3.12, ~> 3.0)
119
+ rubocop
120
+ safe_migrations!
121
+ sqlite3 (~> 2.7)
122
+
123
+ BUNDLED WITH
124
+ 2.7.2
data/README.md ADDED
@@ -0,0 +1,99 @@
1
+ # SafeMigrations
2
+
3
+ G'day, mate! Welcome to **SafeMigrations**, a ripper of a gem that makes your Rails migrations as safe as a kangaroo in the outback. With `safe_` prefixed methods, this gem ensures your database schema changes are idempotent—no dramas if you run 'em twice. Built to play nice with Rails' `CommandRecorder`, it auto-reverses your migrations in the `change` method, so you can crack on with building your app without worrying about dodgy rollbacks.
4
+
5
+ ## Why SafeMigrations?
6
+
7
+ Tired of migrations chucking a wobbly when tables or columns already exist? SafeMigrations wraps Rails migration methods with `safe_` prefixes (e.g., `safe_create_table`, `safe_add_column`) to check for existing schema elements before making changes. It hooks into Rails' `CommandRecorder` for automatic reversals in `change`-based migrations, keeping your database fair dinkum.
8
+ **Warning**: Since it uses `CommandRecorder`, rollbacks may affect pre-existing schema elements—use with care or chuck in a `reversible` block for complex stuff.
9
+
10
+ ## Features
11
+
12
+ - **Idempotent Migrations**: `safe_create_table`, `safe_add_column`, `safe_add_index`, and more only run if needed.
13
+ - **Auto-Reversal**: Integrates with Rails' `CommandRecorder` to invert `safe_` methods (e.g., `safe_create_table` → `safe_drop_table`) in `change` rollbacks.
14
+ - **Rails 7.2+ Ready**: Built for ActiveRecord 7.2, with support for modern Ruby 3.2.
15
+ - **Aussie Spirit**: Crafted with a bit of outback grit to keep your migrations smooth as a cold one on a summer arvo.
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'safe_migrations'
23
+ ```
24
+
25
+ Then give it a burl:
26
+
27
+ ```bash
28
+ $ bundle install
29
+ ```
30
+
31
+ Or install it yourself faster than a dingo nicks your lunch:
32
+
33
+ ```bash
34
+ $ gem install safe_migrations
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ Use `safe_` methods in your Rails migrations’ `change` block, and let Rails’ `CommandRecorder` handle the rollback. Here’s a cracking example:
40
+
41
+ ```ruby
42
+ class CreateUsers < ActiveRecord::Migration[7.2]
43
+ def change
44
+ safe_create_table(:users) do |t|
45
+ t.string :name
46
+ t.string :email
47
+ t.timestamps
48
+ end
49
+ safe_add_column(:users, :role, :string, default: 'user')
50
+ safe_add_index(:users, :email, unique: true)
51
+ end
52
+ end
53
+ ```
54
+
55
+ - **Running**: `rails db:migrate` creates the table, column, and index only if they don’t exist.
56
+ - **Rolling Back**: `rails db:rollback` inverts to `safe_drop_table`, `safe_remove_column`, `safe_remove_index` (in reverse order).
57
+ - **Heads Up**: If a table exists before the migration, `safe_create_table` skips it, but rollback may still call `safe_drop_table`. For critical cases, use `reversible`:
58
+
59
+ ## Development
60
+
61
+ No worries, mate! To get started:
62
+
63
+ 1. Clone the repo and run `bin/setup` to install dependencies.
64
+ 2. Run `rake spec` to give the tests a fair go.
65
+ 3. Use `bin/console` for an interactive prompt to muck around with the code.
66
+
67
+ To install the gem locally:
68
+
69
+ ```bash
70
+ $ bundle exec rake install
71
+ ```
72
+
73
+ To release a new version:
74
+ 1. Update the version in `lib/safe_migrations/version.rb`.
75
+ 2. Run `bundle exec rake release` to tag the version, push to Git, and ship the gem to [RubyGems.org](https://rubygems.org).
76
+
77
+ ## Testing
78
+
79
+ The gem includes an RSpec suite to ensure your migrations are as solid as Uluru:
80
+
81
+ ```bash
82
+ $ rake spec
83
+ ```
84
+
85
+ Tests check idempotency (re-running migrations) and rollback behavior. Note the `CommandRecorder` limitation: pre-existing tables may get dropped on rollback. See `spec/migration_spec.rb` for details.
86
+
87
+ ## Contributing
88
+
89
+ Got a ripper idea or found a bug? Chuck us a pull request or bug report on GitHub at https://github.com/moskvin/safe_migrations. We’re keen as mustard to make this gem top-notch!
90
+
91
+ ## License
92
+
93
+ This gem is available as open-source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
94
+
95
+ ## Acknowledgements
96
+
97
+ Built with a nod to the Aussie spirit—because who doesn’t love a bit of fair dinkum coding? Cheers to the Rails community for the migration framework that makes this possible.
98
+
99
+ Crack on and make your migrations safe as, mate!
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'safe_migrations'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
data/bin/fix_bundle ADDED
@@ -0,0 +1,9 @@
1
+ #!/bin/sh
2
+
3
+ version=${1:-2.7.2}
4
+ echo "Bundle will be updated to" "$version"
5
+
6
+ # Fix the bundler version in the Gemfile.lock and remove all platforms except the ruby one
7
+ bundle _"${version}"_ update --bundler \
8
+ && bundle lock --add-platform ruby x86_64-linux x86_64-darwin-19 x86_64-darwin-20 x86_64-darwin-22 x86_64-darwin-23 arm64-darwin-22 arm64-darwin-23 arm64-darwin-24 \
9
+ && bundle lock --remove-platform x86_64-linux x86_64-darwin-19 x86_64-darwin-20 x86_64-darwin-22 x86_64-darwin-23 arm64-darwin-22 arm64-darwin-23 arm64-darwin-24
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SafeMigrations
4
+ module CommandRecorderExtension
5
+ SAFE_METHODS = %i[
6
+ safe_create_table
7
+ safe_drop_table
8
+ safe_add_column
9
+ safe_remove_column
10
+ safe_rename_column
11
+ safe_add_index
12
+ safe_remove_index
13
+ safe_add_foreign_key
14
+ safe_remove_foreign_key
15
+ safe_add_column_and_index
16
+ safe_remove_column_and_index
17
+ safe_change_column
18
+ safe_change_column_null
19
+ ].freeze
20
+
21
+ SAFE_REVERSIBLE_MAP = {
22
+ safe_create_table: :safe_drop_table,
23
+ safe_add_column: :safe_remove_column,
24
+ safe_remove_column: :safe_add_column,
25
+ safe_add_index: :safe_remove_index,
26
+ safe_remove_index: :safe_add_index,
27
+ safe_add_foreign_key: :safe_remove_foreign_key,
28
+ safe_remove_foreign_key: :safe_add_foreign_key,
29
+ safe_add_column_and_index: :safe_remove_column_and_index,
30
+ safe_remove_column_and_index: :safe_add_column_and_index,
31
+ safe_change_column_null: :safe_change_column_null
32
+ }.freeze
33
+
34
+ def self.apply
35
+ ActiveRecord::Migration::CommandRecorder.class_eval do
36
+ SAFE_METHODS.each do |method|
37
+ define_method(:"#{method}") do |*args, &block|
38
+ record(:"#{method}", args, &block)
39
+ end
40
+ ruby2_keywords(method)
41
+ end
42
+
43
+ SAFE_REVERSIBLE_MAP.each do |cmd, inv|
44
+ define_method(:"invert_#{cmd}") do |args, &block|
45
+ [inv, args, block]
46
+ end
47
+ end
48
+
49
+ # Special case for safe_rename_column (swap column names)
50
+ def invert_safe_rename_column(args)
51
+ table, old_col, new_col = args
52
+ [:safe_rename_column, [table, new_col, old_col]]
53
+ end
54
+
55
+ # Special case for safe_change_column (needs type tracking)
56
+ def invert_safe_change_column(args)
57
+ table, column, type, options = args
58
+ # If column existed, invert to original type (not tracked, so warn)
59
+ # If column was added, invert to remove
60
+ [:safe_remove_column, [table, column, type, options]]
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,72 @@
1
+ module SafeMigrations
2
+ module MigrationHelper
3
+ def self.included(base)
4
+ base.send(:include, InstanceMethods)
5
+ end
6
+
7
+ module InstanceMethods
8
+ def safe_add_column(table, column, type, **options)
9
+ return unless table_exists?(table)
10
+ return if column_exists?(table, column)
11
+
12
+ add_column(table, column, type, **options)
13
+ end
14
+
15
+ def safe_remove_column(table, column, type = nil, **options)
16
+ table_exists?(table) && column_exists?(table, column) && remove_column(table, column, type, **options)
17
+ end
18
+
19
+ def safe_rename_column(table_name, column_name, new_column_name)
20
+ column_exists?(table_name, column_name) && !column_exists?(table_name, new_column_name) && rename_column(table_name, column_name, new_column_name)
21
+ end
22
+
23
+ def safe_add_index(table, column, **options)
24
+ return unless table_exists?(table)
25
+ return if index_exists?(table, column, **options)
26
+
27
+ add_index(table, column, **options)
28
+ end
29
+
30
+ def safe_remove_index(table, column_name = nil, **options)
31
+ index_exists?(table, column_name, **options) && remove_index(table, column_name, **options)
32
+ end
33
+
34
+ def safe_add_column_and_index(table, column, type, column_options = {}, index_options = {})
35
+ safe_add_column(table, column, type, **column_options)
36
+ safe_add_index(table, column, **index_options)
37
+ end
38
+
39
+ def safe_remove_column_and_index(table, column, column_options = {}, index_options = {})
40
+ safe_remove_index(table, column, **index_options)
41
+ safe_remove_column(table, column, **column_options)
42
+ end
43
+
44
+ def safe_change_column(table, column, type, **options)
45
+ column_exists?(table, column) ? change_column(table, column, type, **options) : add_column(table, column, type, **options)
46
+ end
47
+
48
+ def safe_change_column_null(table, column, null, default = nil)
49
+ column_exists?(table, column) && change_column_null(table, column, null, default)
50
+ end
51
+
52
+ def safe_create_table(table, **options, &block)
53
+ create_table(table, **options, &block) unless table_exists?(table)
54
+ end
55
+
56
+ def safe_drop_table(table)
57
+ drop_table(table, if_exists: true) if table_exists?(table)
58
+ end
59
+
60
+ def safe_add_foreign_key(from_table, to_table, **options)
61
+ return unless table_exists?(from_table) && table_exists?(to_table)
62
+ return if foreign_key_exists?(from_table, to_table, **options)
63
+
64
+ add_foreign_key(from_table, to_table, **options)
65
+ end
66
+
67
+ def safe_remove_foreign_key(from_table, to_table, **options)
68
+ table_exists?(from_table) && table_exists?(to_table) && foreign_key_exists?(from_table, to_table, **options) && remove_foreign_key(from_table, to_table, **options)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ module SafeMigrations
2
+ VERSION = '1.0.0'.freeze
3
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
4
+ require 'safe_migrations/version'
5
+ require 'safe_migrations/migration_helper'
6
+ require 'safe_migrations/command_recorder_extension'
7
+
8
+ module SafeMigrations
9
+ class Error < StandardError; end
10
+ # Your code goes here...
11
+ end
12
+
13
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.include(SafeMigrations::MigrationHelper)
14
+ SafeMigrations::CommandRecorderExtension.apply
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'safe_migrations/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'safe_migrations'
9
+ spec.version = SafeMigrations::VERSION
10
+ spec.authors = ['Nikolay Moskvin']
11
+ spec.email = ['nikolay.moskvin@gmail.com']
12
+
13
+ spec.summary = 'Idempotent migration helpers for Rails with safe, reversible operations.'
14
+ spec.description = "SafeMigrations enhances Rails migrations with safe_ prefixed methods that prevent errors by checking for existing schema elements before execution. It integrates with Rails' CommandRecorder for automatic reversal in change-based migrations, ensuring safe and reliable database schema management."
15
+ spec.homepage = 'https://github.com/moskvin/safe_migrations'
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
21
+
22
+ spec.metadata['homepage_uri'] = spec.homepage
23
+ spec.metadata['source_code_uri'] = 'https://github.com/moskvin/safe_migrations'
24
+ spec.metadata['changelog_uri'] = 'https://github.com/moskvin/safe_migrations/CHANGELOG.md'
25
+ else
26
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
27
+ 'public gem pushes.'
28
+ end
29
+
30
+ # Specify which files should be added to the gem when it is released.
31
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
33
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
+ end
35
+ spec.bindir = 'exe'
36
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
+ spec.require_paths = ['lib']
38
+
39
+ spec.required_ruby_version = '>= 3.2'
40
+
41
+ spec.add_dependency 'activerecord', '>= 7.2'
42
+
43
+ spec.add_development_dependency 'bundler', '~> 2.7'
44
+ spec.add_development_dependency 'rake', '~> 13.0'
45
+ spec.add_development_dependency 'rspec', '~> 3.0'
46
+ spec.add_development_dependency 'rubocop'
47
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safe_migrations
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Nikolay Moskvin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-10-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '7.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.7'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: SafeMigrations enhances Rails migrations with safe_ prefixed methods
84
+ that prevent errors by checking for existing schema elements before execution. It
85
+ integrates with Rails' CommandRecorder for automatic reversal in change-based migrations,
86
+ ensuring safe and reliable database schema management.
87
+ email:
88
+ - nikolay.moskvin@gmail.com
89
+ executables: []
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - ".gitignore"
94
+ - ".rspec"
95
+ - ".rubocop.yml"
96
+ - ".ruby-version"
97
+ - ".travis.yml"
98
+ - CHANGELOG.md
99
+ - Gemfile
100
+ - Gemfile.lock
101
+ - README.md
102
+ - Rakefile
103
+ - bin/console
104
+ - bin/fix_bundle
105
+ - bin/setup
106
+ - lib/safe_migrations.rb
107
+ - lib/safe_migrations/command_recorder_extension.rb
108
+ - lib/safe_migrations/migration_helper.rb
109
+ - lib/safe_migrations/version.rb
110
+ - safe_migrations.gemspec
111
+ homepage: https://github.com/moskvin/safe_migrations
112
+ licenses: []
113
+ metadata:
114
+ allowed_push_host: https://rubygems.org
115
+ homepage_uri: https://github.com/moskvin/safe_migrations
116
+ source_code_uri: https://github.com/moskvin/safe_migrations
117
+ changelog_uri: https://github.com/moskvin/safe_migrations/CHANGELOG.md
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '3.2'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.4.19
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: Idempotent migration helpers for Rails with safe, reversible operations.
137
+ test_files: []