squasher 0.7.3 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c119d1c7581f2a095e9417f79ad66ffa78bfd0c60c90b7c60ee0ac5b9907258
4
- data.tar.gz: bcce5a1fd4281e75a83a784e27282c0e3419469be567a5ee768037940a2eec4e
3
+ metadata.gz: f24c854e23e0551b83dae9c84535512267c5e289b97e6e80bd6f2aa5ef8e114b
4
+ data.tar.gz: 71907e46c851eb643fcea44e358905ca32118dd927395bd9368180e077bdd88a
5
5
  SHA512:
6
- metadata.gz: 724ccdd003b9ae060e79cd081de7b75b4cd3195181946bc3f26056c0f5a0e6225d3630a5e8053f128b5781f5d1f1ebff16f79d380b3964fa2c006ea9736ee545
7
- data.tar.gz: e0d2fadd2d22296ae6107bbb9057a6a1dc8b30092f4a0d9b1cec3a2112dcf1531d60eaafbe8c8d9e3fa74d8729a482af397b564a39c95e2e8039f3db4adeaa10
6
+ metadata.gz: 8e2a01c40884087c7f931c0d35535100b128c8acd8bb9f90d2f52d935bed3cc32be6317283ad4aced836f68fe6664f325558cf4e9d644a909b9cac718bb424f7
7
+ data.tar.gz: 6c87b45b989701ce8731b71141f647905e67089f6a3aca42ef1dbc962f78d059adcc654b81ffdcdb0703dd9029f0670d3669fbb14daa12bf585c7ffed843340e
data/CHANGELOG.md CHANGED
@@ -1,3 +1,5 @@
1
+ - 0.8.0
2
+ - Support multiple databases in Rails-style ([@fynsta](https://github.com/fynsta))
1
3
  - 0.7.0
2
4
  - Support the presence of multiverse ([@mlohbihler](https://github.com/mlohbihler))
3
5
  - 0.6.1
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Squasher
2
2
 
3
- [![Build Status](https://travis-ci.org/jalkoby/squasher.svg?branch=master)](https://travis-ci.org/jalkoby/squasher)
3
+ [![CI](https://github.com/jalkoby/squasher/actions/workflows/ci.yml/badge.svg)](https://github.com/jalkoby/squasher/actions/workflows/ci.yml)
4
4
  [![Code Climate](https://codeclimate.com/github/jalkoby/squasher.svg)](https://codeclimate.com/github/jalkoby/squasher)
5
5
  [![Gem Version](https://badge.fury.io/rb/squasher.svg)](http://badge.fury.io/rb/squasher)
6
6
 
data/bin/squasher CHANGED
@@ -32,7 +32,11 @@ parser = OptionParser.new do |config|
32
32
  options[:engine] = value
33
33
  end
34
34
 
35
- config.on('--databases=DB_KEY,...', 'alternate database configuration keys to be included dbconfig (for multiverse)') do |value|
35
+ config.on('--multi-db_format=FORMAT', 'format of the multi-db configuration (rails, multiverse)') do |value|
36
+ options[:multi_db_format] = value
37
+ end
38
+
39
+ config.on('--databases=DB_KEY,...', 'alternate database configuration keys to be included') do |value|
36
40
  options[:databases] = value&.split(",")
37
41
  end
38
42
 
@@ -9,16 +9,31 @@ module Squasher
9
9
  end
10
10
 
11
11
  def process
12
- Squasher.error(:migration_folder_missing) unless config.migrations_folder?
12
+ Squasher.error(:migration_folder_missing) unless config.migrations_folders?
13
+
14
+ if config.multi_db_format == 'rails'
15
+ config.databases.each do |database|
16
+ process_database(database)
17
+ end
18
+ else
19
+ process_database
20
+ end
21
+ end
13
22
 
14
- migration_file = config.migration_file(now_timestamp, MIGRATION_NAME)
15
- if prev_migration
23
+ def process_database(database = nil)
24
+ migration_file = config.migration_file(now_timestamp, MIGRATION_NAME, database)
25
+ if (prev_migration = prev_migration(database))
16
26
  FileUtils.rm(prev_migration)
17
27
  end
18
28
  File.open(migration_file, 'wb') do |stream|
19
- stream << ::Squasher::Render.render(MIGRATION_NAME, config)
29
+ stream << ::Squasher::Render.render(MIGRATION_NAME, config, database)
30
+ end
31
+
32
+ if database.nil?
33
+ Squasher.rake("db:migrate", :db_cleaning)
34
+ else
35
+ Squasher.rake("db:migrate:#{database}", :db_cleaning)
20
36
  end
21
- Squasher.rake("db:migrate", :db_cleaning)
22
37
  end
23
38
 
24
39
  private
@@ -27,10 +42,10 @@ module Squasher
27
42
  Squasher.config
28
43
  end
29
44
 
30
- def prev_migration
45
+ def prev_migration(database = nil)
31
46
  return @prev_migration if defined?(@prev_migration)
32
47
 
33
- @prev_migration = config.migration_files.detect do |file|
48
+ @prev_migration = config.migration_files(database).detect do |file|
34
49
  File.basename(file).include?(MIGRATION_NAME)
35
50
  end
36
51
  end
@@ -34,12 +34,12 @@ module Squasher
34
34
  end
35
35
  end
36
36
 
37
- attr_reader :schema_file, :migration_version
37
+ attr_reader :migration_version, :multi_db_format, :databases
38
38
 
39
39
  def initialize
40
40
  @root_path = Dir.pwd.freeze
41
- @migrations_folder = File.join(@root_path, 'db', 'migrate')
42
41
  @flags = []
42
+ @multi_db_format = nil
43
43
  @databases = []
44
44
  set_app_path(@root_path)
45
45
  end
@@ -59,9 +59,9 @@ module Squasher
59
59
  elsif key == :migration
60
60
  Squasher.error(:invalid_migration_version, value: value) unless value.to_s =~ /\A\d.\d\z/
61
61
  @migration_version = "[#{value}]"
62
- elsif key == :sql
63
- @schema_file = File.join(@app_path, 'db', 'structure.sql')
64
- @flags << key
62
+ elsif key == :multi_db_format
63
+ Squasher.error(:invalid_multi_db_format, value: value) unless %w[rails multiverse].include?(value)
64
+ @multi_db_format = value
65
65
  elsif key == :databases
66
66
  @databases = value
67
67
  else
@@ -73,16 +73,46 @@ module Squasher
73
73
  @flags.include?(k)
74
74
  end
75
75
 
76
- def migration_files
77
- Dir.glob(File.join(migrations_folder, '**.rb'))
76
+ def schema_files
77
+ return [schema_file] unless @multi_db_format == 'rails'
78
+
79
+ @databases.map { |db| schema_file(db) }
80
+ end
81
+
82
+ def schema_file(database = nil)
83
+ prefix = database.nil? || database == 'primary' ? '' : "#{ database }_"
84
+ file = set?(:sql) ? 'structure.sql' : 'schema.rb'
85
+
86
+ File.join(@app_path, 'db', "#{ prefix }#{ file }")
87
+ end
88
+
89
+ def migration_files(database = nil)
90
+ Dir.glob(File.join(migrations_folder(database), '**.rb'))
78
91
  end
79
92
 
80
- def migration_file(timestamp, migration_name)
81
- File.join(migrations_folder, "#{ timestamp }_#{ migration_name }.rb")
93
+ def migration_file(timestamp, migration_name, database = nil)
94
+ File.join(migrations_folder(database), "#{ timestamp }_#{ migration_name }.rb")
95
+ end
96
+
97
+ def migrations_folder(database = nil)
98
+ return default_migration_folder if database.nil?
99
+
100
+ migrations_paths = dbconfig['development'][database]['migrations_paths']
101
+ return default_migration_folder unless migrations_paths
102
+
103
+ File.join(@app_path, migrations_paths)
104
+ end
105
+
106
+ def migrations_folders?
107
+ if @multi_db_format != 'rails'
108
+ Dir.exist?(migrations_folder)
109
+ else
110
+ @databases.all? { |db| Dir.exist?(migrations_folder(db)) }
111
+ end
82
112
  end
83
113
 
84
- def migrations_folder?
85
- Dir.exist?(migrations_folder)
114
+ def default_migration_folder
115
+ File.join(@root_path, 'db', 'migrate')
86
116
  end
87
117
 
88
118
  def dbconfig?
@@ -92,7 +122,7 @@ module Squasher
92
122
  def stub_dbconfig
93
123
  return unless dbconfig?
94
124
 
95
- list = [dbconfig_file, schema_file]
125
+ list = [dbconfig_file, *schema_files]
96
126
  list.each do |file|
97
127
  next unless File.exist?(file)
98
128
  FileUtils.mv file, "#{ file }.sq"
@@ -115,7 +145,7 @@ module Squasher
115
145
 
116
146
  private
117
147
 
118
- attr_reader :migrations_folder, :dbconfig_file
148
+ attr_reader :dbconfig_file
119
149
 
120
150
  def dbconfig
121
151
  return @dbconfig if defined?(@dbconfig)
@@ -126,8 +156,27 @@ module Squasher
126
156
  begin
127
157
  content, soft_error = Render.process(dbconfig_file)
128
158
  if content.has_key?('development')
129
- @dbconfig = { 'development' => content['development'].merge('database' => 'squasher') }
130
- @databases&.each { |database| @dbconfig[database] = content[database] }
159
+ if @multi_db_format == 'rails'
160
+ @dbconfig = { 'development' => {} }
161
+ @databases.each do |database|
162
+ @dbconfig['development'][database] = content['development'][database].merge('database' => "#{database}_squasher")
163
+
164
+ database_name = content['development'][database]['database']
165
+ content['development'].select { |_, v| v['database'] == database_name && v['replica'] }.each do |k, v|
166
+ @dbconfig['development'][k] = v.merge('database' => "#{database}_squasher")
167
+ end
168
+ end
169
+ else
170
+ @dbconfig = { 'development' => content['development'].merge('database' => 'squasher') }
171
+
172
+ multiverse_by_default = @multi_db_format.nil? && @databases.any?
173
+ if multiverse_by_default
174
+ puts "Using multiverse format by default is deprecated and will be removed in the next major release. Please specify --multi-db_format=rails or --multi-db_format=multiverse explicitly."
175
+ end
176
+ if multiverse_by_default || @multi_db_format == 'multiverse'
177
+ @databases&.each { |database| @dbconfig[database] = content[database] }
178
+ end
179
+ end
131
180
  end
132
181
  rescue
133
182
  end
@@ -140,7 +189,6 @@ module Squasher
140
189
 
141
190
  def set_app_path(path)
142
191
  @app_path = path
143
- @schema_file = File.join(path, 'db', 'schema.rb')
144
192
  @dbconfig_file = File.join(path, 'config', 'database.yml')
145
193
  end
146
194
  end
@@ -8,9 +8,10 @@ module Squasher
8
8
 
9
9
  attr_reader :name, :config
10
10
 
11
- def initialize(name, config)
11
+ def initialize(name, config, database = nil)
12
12
  @name = name
13
13
  @config = config
14
+ @database = database
14
15
  end
15
16
 
16
17
  def render
@@ -22,7 +23,7 @@ module Squasher
22
23
  end
23
24
 
24
25
  def each_schema_line(&block)
25
- File.open(config.schema_file, 'r') do |stream|
26
+ File.open(config.schema_file(@database), 'r') do |stream|
26
27
  if @config.set?(:sql)
27
28
  stream_structure(stream, &block)
28
29
  else
@@ -1,3 +1,3 @@
1
1
  module Squasher
2
- VERSION = "0.7.3"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -20,9 +20,13 @@ module Squasher
20
20
  Squasher.tell(:dry_mode_finished)
21
21
  Squasher.print(Render.render(:init_schema, config))
22
22
  else
23
- path = config.migration_file(finish_timestamp, :init_schema)
24
- File.open(path, 'wb') { |io| io << Render.render(:init_schema, config) }
25
- migrations.each { |file| FileUtils.rm(file) }
23
+ if config.multi_db_format == 'rails'
24
+ config.databases.each do |database|
25
+ clean_migrations(database)
26
+ end
27
+ else
28
+ clean_migrations
29
+ end
26
30
  end
27
31
 
28
32
  Squasher.rake("db:drop") unless Squasher.ask(:keep_database)
@@ -38,30 +42,48 @@ module Squasher
38
42
  end
39
43
 
40
44
  def check!
41
- Squasher.error(:migration_folder_missing) unless config.migrations_folder?
45
+ Squasher.error(:migration_folder_missing) unless config.migrations_folders?
42
46
  Squasher.error(:dbconfig_invalid) unless config.dbconfig?
43
- if migrations.empty?
47
+
48
+ if config.multi_db_format == 'rails'
49
+ config.databases.each do |database|
50
+ check_migrations_exist(database)
51
+ end
52
+ else
53
+ check_migrations_exist
54
+ end
55
+ end
56
+
57
+ def check_migrations_exist(database = nil)
58
+ if migrations(database).empty?
44
59
  print_date = date.strftime("%Y/%m/%d")
45
- Squasher.error(:no_migrations, :date => print_date)
60
+
61
+ Squasher.error(:no_migrations, :date => date.strftime("%Y/%m/%d"))
46
62
  end
47
63
  end
48
64
 
49
- def migrations
50
- @migrations ||= config.migration_files.select { |file| before_date?(get_timestamp(file)) }.sort
65
+ def migrations(database = nil)
66
+ config.migration_files(database).select { |file| before_date?(get_timestamp(file)) }.sort
51
67
  end
52
68
 
53
69
  def get_timestamp(file)
54
70
  File.basename(file)[/\A\d+/]
55
71
  end
56
72
 
73
+ def clean_migrations(database = nil)
74
+ path = config.migration_file(finish_timestamp(database), :init_schema, database)
75
+ migrations(database).each { |file| FileUtils.rm(file) } # Remove all migrations before creating the new one
76
+ File.open(path, 'wb') { |io| io << Render.render(:init_schema, config, database) }
77
+ end
78
+
57
79
  def before_date?(timestamp)
58
80
  @point ||= date.strftime("%Y%m%d").to_i
59
81
  return unless timestamp
60
82
  timestamp[0...8].to_i < @point
61
83
  end
62
84
 
63
- def finish_timestamp
64
- @finish_timestamp ||= get_timestamp(migrations.last)
85
+ def finish_timestamp(database = nil)
86
+ get_timestamp(migrations(database).last)
65
87
  end
66
88
 
67
89
  def under_squash_env
@@ -72,7 +94,13 @@ module Squasher
72
94
  return unless Squasher.rake("db:drop db:create", :db_create)
73
95
  end
74
96
 
75
- return unless Squasher.rake("db:migrate VERSION=#{ finish_timestamp }", :db_migrate)
97
+ if config.multi_db_format == 'rails'
98
+ config.databases.each do |database|
99
+ return unless Squasher.rake("db:migrate:#{ database } VERSION=#{ finish_timestamp(database) }", :db_migrate)
100
+ end
101
+ else
102
+ return unless Squasher.rake("db:migrate VERSION=#{ finish_timestamp }", :db_migrate)
103
+ end
76
104
 
77
105
  yield
78
106
 
@@ -6,7 +6,7 @@ describe Squasher::Worker do
6
6
  let(:worker) { described_class.new(Time.new(2012, 6, 20)) }
7
7
 
8
8
  specify 'command was run not in application root' do
9
- allow_any_instance_of(Squasher::Config).to receive(:migrations_folder?).and_return(false)
9
+ allow_any_instance_of(Squasher::Config).to receive(:migrations_folders?).and_return(false)
10
10
 
11
11
  expect_exit_with(:migration_folder_missing)
12
12
  end
@@ -31,7 +31,7 @@ describe Squasher::Worker do
31
31
  worker = described_class.new(Time.new(2014))
32
32
  allow(worker).to receive(:under_squash_env).and_yield.and_return(true)
33
33
  new_migration_path = File.join(Dir.tmpdir, 'init_schema.rb')
34
- allow_any_instance_of(Squasher::Config).to receive(:migration_file).with('20131213090719', :init_schema).and_return(new_migration_path)
34
+ allow_any_instance_of(Squasher::Config).to receive(:migration_file).with('20131213090719', :init_schema, nil).and_return(new_migration_path)
35
35
 
36
36
  expect(FileUtils).to receive(:rm).with(File.join(fake_root, 'db', 'migrate', '20131205160936_first_migration.rb'))
37
37
  expect(FileUtils).to receive(:rm).with(File.join(fake_root, 'db', 'migrate', '20131213090719_second_migration.rb'))
@@ -60,7 +60,7 @@ describe Squasher::Worker do
60
60
  worker = described_class.new(Time.new(2014))
61
61
  allow(worker).to receive(:under_squash_env).and_yield.and_return(true)
62
62
  new_migration_path = File.join(Dir.tmpdir, 'init_schema.rb')
63
- allow_any_instance_of(Squasher::Config).to receive(:migration_file).with('20131213090719', :init_schema).and_return(new_migration_path)
63
+ allow_any_instance_of(Squasher::Config).to receive(:migration_file).with('20131213090719', :init_schema, nil).and_return(new_migration_path)
64
64
  expect(FileUtils).to receive(:rm).with(File.join(fake_root, 'db', 'migrate', '20131205160936_first_migration.rb'))
65
65
  expect(FileUtils).to receive(:rm).with(File.join(fake_root, 'db', 'migrate', '20131213090719_second_migration.rb'))
66
66
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: squasher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.3
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Pchelintsev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-24 00:00:00.000000000 Z
11
+ date: 2024-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
113
  requirements: []
114
- rubygems_version: 3.2.32
114
+ rubygems_version: 3.4.10
115
115
  signing_key:
116
116
  specification_version: 4
117
117
  summary: Squash your old migrations