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 +4 -4
- data/CHANGELOG.md +10 -1
- data/Gemfile.lock +1 -1
- data/README.md +17 -7
- data/actual_db_schema.gemspec +1 -1
- data/lib/actual_db_schema/version.rb +1 -1
- data/lib/tasks/db.rake +54 -27
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b63fb97832086a404eb2ff18cda0efa99659c8b4b836128130f15e72f20a77b2
|
4
|
+
data.tar.gz: 7d5e45d844564dc33377837ebc926137a6ef1e72765ac2dd91dbded0c45c2a38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f5372a2858523be0bdfdf3487c83dab1ebea97be8c5f8875d6cec3094f017a802d9b141870de3c2877423fc071ac2f55ceccaa5136cd81eda77d94c3757fcdd
|
7
|
+
data.tar.gz: 7e71a858de75c5fb314da5d55d06a07cdbfde7919cbe016cdd7c3ab657b72ae892557ef8552f2e248a70ffe5e6484b750073b5d9a7ad1a66e7925220326fd5d8
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,13 @@
|
|
1
|
-
## [
|
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
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
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
34
|
-
|
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
|
|
data/actual_db_schema.gemspec
CHANGED
@@ -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"
|
data/lib/tasks/db.rake
CHANGED
@@ -1,32 +1,35 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "active_record/migration"
|
3
|
+
return unless Rails.env.development?
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
11
|
-
|
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
|
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 =
|
41
|
-
migrator.extend(
|
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(
|
54
|
-
other_branches_files.reject { migration_filename(
|
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
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
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.
|
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:
|
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: []
|