actual_db_schema 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e85ea0679fbf525eeab14a9b9db7d3bfb49cf514b554427db12d1e784e8c55d9
4
- data.tar.gz: 87e02334c37e8d10cae7c05f2aa5df474157100074458d0b41d90b6583ac839c
3
+ metadata.gz: b63fb97832086a404eb2ff18cda0efa99659c8b4b836128130f15e72f20a77b2
4
+ data.tar.gz: 7d5e45d844564dc33377837ebc926137a6ef1e72765ac2dd91dbded0c45c2a38
5
5
  SHA512:
6
- metadata.gz: '083c8a127fc6350f67904dbc7e4295dacd7e924620e2aa9ce7e515fa4b5a300454c9fa8e4f50905f6f626a66b83f24dc10fb10753ff94d048ec986bbea8f73a4'
7
- data.tar.gz: b125355516facc2111e9b48effc33d9eb2946e57c2e75ab2966477357769bf199ff3dd20c3fc1c6765d5a25bccba02aa7b27d3d57688a3781a326368f7b80dce
6
+ metadata.gz: 7f5372a2858523be0bdfdf3487c83dab1ebea97be8c5f8875d6cec3094f017a802d9b141870de3c2877423fc071ac2f55ceccaa5136cd81eda77d94c3757fcdd
7
+ data.tar.gz: 7e71a858de75c5fb314da5d55d06a07cdbfde7919cbe016cdd7c3ab657b72ae892557ef8552f2e248a70ffe5e6484b750073b5d9a7ad1a66e7925220326fd5d8
data/CHANGELOG.md CHANGED
@@ -1,4 +1,13 @@
1
- ## [Unreleased]
1
+ ## [0.2.0] - 2023-01-23
2
+
3
+ - add Rails 6 and older support
4
+
5
+ ## [0.2.0] - 2022-10-19
6
+
7
+ - Catch exceptions about irreversible migrations and show a warning
8
+ - Namespace all patches into gem module
9
+ - Fix typo in a module name with a patch
10
+ - Use guard clause
2
11
 
3
12
  ## [0.1.0] - 2022-10-16
4
13
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- actual_db_schema (0.1.0)
4
+ actual_db_schema (0.3.0)
5
5
  activerecord
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
+ [![Gem Version](https://badge.fury.io/rb/actual_db_schema.svg)](https://badge.fury.io/rb/actual_db_schema)
2
+
1
3
  # ActualDbSchema
2
4
 
3
- Keep DB schema consistent while switching between branches with no additional actions.
5
+ Keep Rails DB schema consistent while switching between branches with no additional actions.
4
6
 
5
7
  ## Installation
6
8
 
@@ -18,7 +20,7 @@ And then execute:
18
20
 
19
21
  ## Usage
20
22
 
21
- TL;TR: Just run `rails db:migrate` inside the current branch.
23
+ TLTR; Just run `rails db:migrate` inside the current branch.
22
24
 
23
25
  In **branch A** I add a mandatory (not null) field into DB via migration and run it.
24
26
  Then I switch to another **branch B**. This branch's code is not aware of that field.
@@ -26,12 +28,20 @@ As the result, the code is failing with an error "null value provided for non-nu
26
28
  Moreover, a DB rake task generates a diff on `schema.rb` that's not relevant to this branch.
27
29
  I can switch to **branch A** and roll back the migration, but I need to remember that branch or waste time on it.
28
30
 
29
- This code changes the standard migration behavior to save all run migrations inside `tmp/migrations` folder.
30
- Every run of schema dump (that's a dependency of `db:migrate` task as well) rolls back the "unknown" migrations
31
- for the current branch looking into the `tmp/migrations` folder.
31
+ Some example of this error:
32
+
33
+ ActiveRecord::NotNullViolation:
34
+ PG::NotNullViolation: ERROR: null value in column "log" of relation "check_results" violates not-null constraint
35
+ DETAIL: Failing row contains (8, 46, success, 2022-10-16 21:47:21.07212, 2022-10-16 21:47:21.07212, null).
36
+
37
+ This gem saves all run migrations inside `tmp/migrations` folder.
38
+ Every run of schema dump (that's a dependency of `db:migrate` task as well) rolls back the "unknown" for the current branch migrations
39
+ looking into the `tmp/migrations` folder.
40
+
41
+ You just need to run `rails db:migrate` in the current branch to actualize the DB schema. With its hand, you will never have wrongly generated `schema.rb`.
32
42
 
33
- Using this gem you need to run `rails db:migrate` in the current branch and it will actualize the DB schema.
34
- You will never have wrongly generated `schema.rb`.
43
+ > **Warning**
44
+ > This solution implies that all migrations are reversible. The cases with irreversible migrations should be solved manually. At the moment, these migrations are ignored by the gem and you will see a warning if some migrations can't roll back automatically.
35
45
 
36
46
  ## Development
37
47
 
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
12
12
  spec.description = <<~DESC
13
13
  Switching between branches with migrations and running them can make your DB inconsistent
14
14
  and not working in another branch if not roll the migration back.
15
- Install this gem and forget about that issue by running the standard rake db:migrate."
15
+ Install this gem and forget about that issue by running the standard rake db:migrate.
16
16
  DESC
17
17
  spec.homepage = "https://github.com/widefix/actual_db_schema"
18
18
  spec.license = "MIT"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActualDbSchema
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/tasks/db.rake CHANGED
@@ -1,32 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if Rails.env.development?
4
- require "active_record/migration"
3
+ return unless Rails.env.development?
5
4
 
6
- def migrated_folder
7
- Rails.root.join("tmp", "migrated").tap { |folder| FileUtils.mkdir_p(folder) }
8
- end
5
+ require "active_record/migration"
6
+
7
+ def migrated_folder
8
+ Rails.root.join("tmp", "migrated").tap { |folder| FileUtils.mkdir_p(folder) }
9
+ end
10
+
11
+ def migration_filename(fullpath)
12
+ fullpath.split("/").last
13
+ end
9
14
 
10
- def migration_filename(fullpath)
11
- fullpath.split("/").last
15
+ # All patches are namespaced into this module
16
+ module ActualDbSchema
17
+ class << self
18
+ attr_accessor :failed
12
19
  end
13
20
 
21
+ self.failed = []
22
+
14
23
  # Track migrated migrations inside the tmp folder
15
24
  module MigrationProxyPatch
16
25
  def migrate(direction)
17
- if direction == :up
18
- FileUtils.copy(filename, migrated_folder.join(basename))
19
- else
20
- FileUtils.rm(migrated_folder.join(basename))
21
- end
22
26
  super(direction)
27
+ FileUtils.copy(filename, migrated_folder.join(basename)) if direction == :up
23
28
  end
24
29
  end
25
30
 
26
- ActiveRecord::MigrationProxy.prepend(MigrationProxyPatch)
27
-
28
31
  # Run only one migration that's being rolled back
29
- module MigratorPath
32
+ module MigratorPatch
30
33
  def runnable
31
34
  migration = migrations.first # there is only one migration, because we pass only one here
32
35
  ran?(migration) ? [migration] : []
@@ -37,34 +40,58 @@ if Rails.env.development?
37
40
  module MigrationContextPatch
38
41
  def rollback_branches
39
42
  migrations.each do |migration|
40
- migrator = ActiveRecord::Migrator.new(:down, [migration], schema_migration, migration.version)
41
- migrator.extend(MigratorPath)
43
+ migrator = down_migrator_for(migration)
44
+ migrator.extend(ActualDbSchema::MigratorPatch)
42
45
  migrator.migrate
46
+ rescue StandardError => e
47
+ raise unless e.message.include?("ActiveRecord::IrreversibleMigration")
48
+
49
+ ActualDbSchema.failed << migration
43
50
  end
44
51
  end
45
52
 
46
53
  private
47
54
 
55
+ def down_migrator_for(migration)
56
+ if ActiveRecord::Migration.current_version < 6
57
+ ActiveRecord::Migrator.new(:down, [migration], migration.version)
58
+ else
59
+ ActiveRecord::Migrator.new(:down, [migration], schema_migration, migration.version)
60
+ end
61
+ end
62
+
48
63
  def migration_files
49
64
  paths = Array(migrations_paths)
50
65
  current_branch_files = Dir[*paths.flat_map { |path| "#{path}/**/[0-9]*_*.rb" }]
51
66
  other_branches_files = Dir["#{migrated_folder}/**/[0-9]*_*.rb"]
52
67
 
53
- current_branch_file_names = current_branch_files.map { migration_filename(_1) }
54
- other_branches_files.reject { migration_filename(_1).in?(current_branch_file_names) }
68
+ current_branch_file_names = current_branch_files.map { |f| migration_filename(f) }
69
+ other_branches_files.reject { |f| migration_filename(f).in?(current_branch_file_names) }
55
70
  end
56
71
  end
72
+ end
57
73
 
58
- namespace :db do
59
- desc "Rollback migrations that were run inside not a merged branch."
60
- task rollback_branches: :load_config do
61
- ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback_branches")
74
+ ActiveRecord::MigrationProxy.prepend(ActualDbSchema::MigrationProxyPatch)
62
75
 
63
- context = ActiveRecord::Base.connection.migration_context
64
- context.extend(MigrationContextPatch)
65
- context.rollback_branches
76
+ namespace :db do
77
+ desc "Rollback migrations that were run inside not a merged branch."
78
+ task rollback_branches: :load_config do
79
+ if ActiveRecord::Migration.current_version >= 6
80
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback_branches")
66
81
  end
67
82
 
68
- task _dump: :rollback_branches
83
+ context = ActiveRecord::Base.connection.migration_context
84
+ context.extend(ActualDbSchema::MigrationContextPatch)
85
+ context.rollback_branches
86
+ if ActualDbSchema.failed.any?
87
+ puts ""
88
+ puts "[ActualDbSchema] Irreversible migrations were found from other branches. Roll them back or fix manually:"
89
+ puts ""
90
+ puts ActualDbSchema.failed.map { |migration| "- #{migration.filename}" }.join("\n")
91
+ puts ""
92
+ end
93
+ # raise ActualDbSchema.failed.inspect
69
94
  end
95
+
96
+ task _dump: :rollback_branches
70
97
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actual_db_schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Kaleshka
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-10-16 00:00:00.000000000 Z
11
+ date: 2023-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -27,7 +27,7 @@ dependencies:
27
27
  description: |
28
28
  Switching between branches with migrations and running them can make your DB inconsistent
29
29
  and not working in another branch if not roll the migration back.
30
- Install this gem and forget about that issue by running the standard rake db:migrate."
30
+ Install this gem and forget about that issue by running the standard rake db:migrate.
31
31
  email:
32
32
  - ka8725@gmail.com
33
33
  executables: []