squasher 0.2.2 → 0.3.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
  SHA1:
3
- metadata.gz: 12116f56ac7b71bdd918cd878a4954efa0a9ef46
4
- data.tar.gz: 0cc5ba3d421e63497336b8e71ed79a25fa00d279
3
+ metadata.gz: cc559f05a448e4588dbc9bad9e58d638ae7b00ce
4
+ data.tar.gz: a68a4350108a577fc3e245ce1d6e3b800b4ebef1
5
5
  SHA512:
6
- metadata.gz: 151aa2462ff4415923bcb36cc85d601c48deb7271d44d0702e3095551e75b9e859ccaf62ba2885ae3c3921ad6aab6420f2645125adf2feee5b7767a9bec02647
7
- data.tar.gz: 353e4d710717f72cbd2e7a9ebc0d434d0864ae497d7f49e9a0fd609df3e86949eedc032175fa55a7df56503a5f4b9a81152a11817e073274ffbcec0e215d6fb1
6
+ metadata.gz: 6ac40501ddb62f825bbea4c776218bfacfc50d35dc80bc6181b8ced3324a7b6f1a3952c8dff0a99e165505ab4146e139362f885e48298f935ab334cc50532b64
7
+ data.tar.gz: 9d184455efd6c40609c8cd11374f02ed250a616d7f667761c760dfa6e44fb470461abb5448ff37752f1641d5c684616b5077b5cb93597898117b1e892d59faa7
data/.gitignore CHANGED
@@ -3,6 +3,7 @@
3
3
  /.bundle
4
4
  /.config
5
5
  /.rspec
6
+ /dummy
6
7
  Gemfile.custom
7
8
  Gemfile.lock
8
9
  InstalledFiles
data/README.md CHANGED
@@ -50,12 +50,20 @@ process breaks in a migration from 2014. In this situation you squash till 2014,
50
50
  database at the end, make a patch in the broken migration and run again the suite with `-r` option. As the result
51
51
  squasher will not need to create the db schema and all data from the previous migrations will be there.
52
52
 
53
+ `-e` - tell squasher that you are squashing a Rails engine. To squash migrations you need to configure a dummy app. If your dummy app located outside the engine's folder provide path to it as the next argument `squasher -e ../my-engine-app 2016`
54
+
53
55
  ## Requirements
54
56
 
55
57
  It works and was tested on Ruby 2.0+ and Rails 3.1+. It also requires a valid development configuration in `config/database.yml` and using Ruby format in `db/schema.rb` (default Rails use-case).
56
58
  If an old migration inserted data (created ActiveRecord model records) you will lose this code in the squashed migration, **BUT** `squasher` will ask you to leave a tmp database which will have all data that was inserted while migrating. Using this database you could add that data as another migration, or into `config/seed.rb` (the expected place for this stuff).
57
59
 
58
60
  ## Changelog
61
+ - 0.3.0
62
+ - **rails engines support** ([@JakeTheSnake3p0](https://github.com/JakeTheSnake3p0))
63
+ - move messages from JSON file to YAML
64
+ - allow to use a db config with a "soft" parsing errors
65
+ - 0.2.2
66
+ - strip white spaces in init migrations
59
67
  - 0.2.1
60
68
  - support rails 5
61
69
  - 0.2.0
@@ -6,19 +6,32 @@ module Squasher
6
6
  autoload :Render, 'squasher/render'
7
7
  autoload :Worker, 'squasher/worker'
8
8
 
9
- def squash(raw_date, raw_options)
9
+ attr_reader :config
10
+
11
+ @config = Config.new
12
+
13
+ def squash(raw_date, options)
10
14
  parts = raw_date.to_s.split('/').map(&:to_i)
11
15
  date = Time.new(*parts)
12
16
 
13
- options = raw_options.map do |o|
14
- o = o.gsub('-', '').to_sym
15
- unless Worker::OPTIONS.include?(o)
16
- tell(:wrong_option, o: o)
17
+ options.reduce([]) do |acc, arg|
18
+ if arg.index('-') == 0
19
+ arg = arg.gsub('-', '').to_sym
20
+ unless Config::OPTIONS.include?(arg)
21
+ tell(:wrong_option, arg: arg)
22
+ error(:usage)
23
+ end
24
+ acc.push([arg])
25
+ elsif acc.empty?
26
+ tell(:invalid_param, arg: arg)
17
27
  error(:usage)
28
+ else
29
+ acc.last[1] = arg
18
30
  end
19
- o
20
- end
21
- Worker.process(date, options)
31
+ acc
32
+ end.each { |(k, v)| config.set(k, v) }
33
+
34
+ Worker.process(date)
22
35
  end
23
36
 
24
37
  def clean
@@ -27,7 +40,9 @@ module Squasher
27
40
 
28
41
  def rake(command, description = nil)
29
42
  tell(description) if description
30
- system("RAILS_ENV=development DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake #{ command }")
43
+ config.in_app_root do
44
+ system("RAILS_ENV=development DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake #{ command }")
45
+ end
31
46
  end
32
47
 
33
48
  def ask(*args)
@@ -44,7 +59,7 @@ module Squasher
44
59
 
45
60
  def error(*args)
46
61
  tell(*args)
47
- exit
62
+ abort
48
63
  end
49
64
 
50
65
  private
@@ -52,9 +67,9 @@ module Squasher
52
67
  def messages
53
68
  return @messages if @messages
54
69
 
55
- require 'json'
56
- path = File.join(File.dirname(__FILE__), 'squasher/messages.json')
57
- @messages = JSON.load(File.open(path))
70
+ require 'yaml'
71
+ path = File.join(File.dirname(__FILE__), 'squasher/messages.yml')
72
+ @messages = YAML.load(File.open(path))
58
73
  end
59
74
 
60
75
  COLORS = ['red', 'green', 'yellow', 'blue'].each_with_index.inject({}) { |r, (k, i)| r.merge!(k => "03#{ i + 1 }") }
@@ -25,7 +25,7 @@ module Squasher
25
25
  private
26
26
 
27
27
  def config
28
- @config ||= Squasher::Config.new
28
+ Squasher.config
29
29
  end
30
30
 
31
31
  def prev_migration
@@ -4,14 +4,65 @@ require 'erb'
4
4
 
5
5
  module Squasher
6
6
  class Config
7
+ OPTIONS = [:d, :r, :e].freeze
8
+
9
+ module Render
10
+ extend self
11
+
12
+ def process(path)
13
+ @error = false
14
+
15
+ str = YAML.load(ERB.new(File.read(path)).result(binding))
16
+ [str, @error]
17
+ end
18
+
19
+ def method_missing(*args)
20
+ @error = true
21
+ self
22
+ end
23
+
24
+ def const_missing(*args)
25
+ @error = true
26
+ self
27
+ end
28
+
29
+ def to_s
30
+ ''
31
+ end
32
+
33
+ def inspect
34
+ ''
35
+ end
36
+ end
37
+
7
38
  attr_reader :schema_file
8
39
 
9
40
  def initialize
10
- root_path = Dir.pwd
41
+ @root_path = Dir.pwd.freeze
42
+ @migrations_folder = File.join(@root_path, 'db', 'migrate')
43
+ @flags = []
44
+ set_app_path(@root_path)
45
+ end
46
+
47
+ def set(key, value)
48
+ if key == :e
49
+ base = value.nil? ? @root_path : File.expand_path(value, @root_path)
50
+ list = Dir.glob(File.join(base, '**', '*', 'config', 'application.rb'))
51
+ case list.size
52
+ when 1
53
+ set_app_path(File.expand_path('../..', list.first))
54
+ when 0
55
+ Squasher.error(:cannot_find_dummy, base: base)
56
+ else
57
+ Squasher.error(:multi_dummy_case, base: base)
58
+ end
59
+ else
60
+ @flags << key
61
+ end
62
+ end
11
63
 
12
- @schema_file = File.join(root_path, 'db', 'schema.rb')
13
- @migrations_folder = File.join(root_path, 'db', 'migrate')
14
- @dbconfig_file = File.join(root_path, 'config', 'database.yml')
64
+ def with?(k)
65
+ @flags.include?(k)
15
66
  end
16
67
 
17
68
  def migration_files
@@ -50,6 +101,10 @@ module Squasher
50
101
  end
51
102
  end
52
103
 
104
+ def in_app_root(&block)
105
+ Dir.chdir(@app_path, &block)
106
+ end
107
+
53
108
  private
54
109
 
55
110
  attr_reader :migrations_folder, :dbconfig_file
@@ -61,13 +116,23 @@ module Squasher
61
116
  @dbconfig = nil
62
117
 
63
118
  begin
64
- content = YAML.load(ERB.new(File.read(dbconfig_file)).result(binding))
119
+ content, soft_error = Render.process(dbconfig_file)
65
120
  if content.has_key?('development')
66
121
  @dbconfig = { 'development' => content['development'].merge('database' => 'squasher') }
67
122
  end
68
123
  rescue
69
124
  end
125
+
126
+ if soft_error && @dbconfig
127
+ exit unless Squasher.ask(:use_dbconfig, config: @dbconfig.fetch('development'))
128
+ end
70
129
  @dbconfig
71
130
  end
131
+
132
+ def set_app_path(path)
133
+ @app_path = path
134
+ @schema_file = File.join(path, 'db', 'schema.rb')
135
+ @dbconfig_file = File.join(path, 'config', 'database.yml')
136
+ end
72
137
  end
73
138
  end
@@ -0,0 +1,30 @@
1
+ keep_database:
2
+ - "Squasher's created the `:green<squasher>` database for its needs."
3
+ - It might be useful to keep it if any of your deleted migrations inserts data or
4
+ - you squash migrations in a few steps (look at -r option).
5
+ - "Keep it (:green<yes> / :red<no>)?"
6
+ apply_clean: "Do you want to clean your database from the old schema migration records(:red<yes>/:green<no>)?"
7
+ migration_folder_missing:
8
+ - The folder with migrations is missing.
9
+ - "Are you sure that you're in the :red<root of a rails> application?"
10
+ no_migrations: "There are no migrations in the folder prior to :red<%{date}>"
11
+ use_dbconfig: "There were problems in parsing `:green<database.yml>`. Do you want to use the config below (:green<yes>/:red<no>)?\n\n%{config}\n"
12
+ dbconfig_invalid: "Squasher couldn't load `:green<database.yml>`. Please, make sure that it's present and doesn't include any ruby code."
13
+ db_create: Squasher is creating a tmp database
14
+ db_migrate: Squasher is applying migrations on a tmp database
15
+ db_cleaning: Squasher is applying the clean migration
16
+ db_reuse: Squasher is reusing the database from the previous squashing
17
+ usage:
18
+ - "Example usage:"
19
+ - " :green<squasher> [options] :yellow<year[/month][/day]> => squash migrations prior to a specified date"
20
+ - " :green<squasher> :yellow<clean> => generate or update a cleaning migration and apply it"
21
+ - " :green<squasher> :yellow<info> => show the message\n"
22
+ - "Options:"
23
+ - " :yellow<-d> => execute in :blue<`dry`> mode - test a squashing process without removing old migrations"
24
+ - " :yellow<-r> => reuse a database from the previous squashing"
25
+ - " :yellow<-e> [dummy-root] => execute in :blue<`engine`> mode - requires a dummy app"
26
+ wrong_option: "You provided a wrong option :red<%{arg}>\n\n"
27
+ invalid_param: "You provided a wrong param :red<%{arg}>\n\n"
28
+ dry_mode_finished: "The `dry` mode is finished. Below the init schema's content:"
29
+ cannot_find_dummy: "Squasher can't find a dummy app inside :yellow<%{base}>"
30
+ multi_dummy_case: "Squasher found a few config/application.rb inside :yellow<%{base}>. Please specify the path more precisely"
@@ -2,24 +2,21 @@ require 'fileutils'
2
2
 
3
3
  module Squasher
4
4
  class Worker
5
- OPTIONS = [:d, :r]
6
-
7
- attr_reader :date, :options
5
+ attr_reader :date
8
6
 
9
7
  def self.process(*args)
10
8
  new(*args).process
11
9
  end
12
10
 
13
- def initialize(date, options = [])
11
+ def initialize(date)
14
12
  @date = date
15
- @options = options
16
13
  end
17
14
 
18
15
  def process
19
16
  check!
20
17
 
21
18
  result = under_squash_env do
22
- if options.include?(:d)
19
+ if Squasher.config.with?(:d)
23
20
  Squasher.tell(:dry_mode_finished)
24
21
  puts Render.render(:init_schema, config)
25
22
  else
@@ -37,7 +34,7 @@ module Squasher
37
34
  private
38
35
 
39
36
  def config
40
- @config ||= ::Squasher::Config.new
37
+ Squasher.config
41
38
  end
42
39
 
43
40
  def check!
@@ -50,9 +47,7 @@ module Squasher
50
47
  end
51
48
 
52
49
  def migrations
53
- return @migrations if @migrations
54
-
55
- @migrations = config.migration_files.select { |file| before_date?(get_timestamp(file)) }.sort
50
+ @migrations ||= config.migration_files.select { |file| before_date?(get_timestamp(file)) }.sort
56
51
  end
57
52
 
58
53
  def get_timestamp(file)
@@ -71,7 +66,7 @@ module Squasher
71
66
 
72
67
  def under_squash_env
73
68
  config.stub_dbconfig do
74
- if options.include?(:r)
69
+ if Squasher.config.with?(:r)
75
70
  Squasher.tell(:db_reuse)
76
71
  else
77
72
  return unless Squasher.rake("db:drop db:create", :db_create)
@@ -6,7 +6,7 @@ describe Squasher do
6
6
  specify { expected_covert("2013", Time.new(2013, 1, 1)) }
7
7
 
8
8
  def expected_covert(input, expected)
9
- expect(Squasher::Worker).to receive(:process).with(expected, [])
9
+ expect(Squasher::Worker).to receive(:process).with(expected)
10
10
  Squasher.squash(input, [])
11
11
  end
12
12
  end
@@ -50,21 +50,29 @@ describe Squasher::Worker do
50
50
  end
51
51
  end
52
52
 
53
- specify 'the dry mode' do
54
- worker = described_class.new(Time.new(2014), [:d])
55
- allow(worker).to receive(:under_squash_env).and_yield.and_return(true)
56
- expect(Squasher).to receive(:tell).with(:dry_mode_finished).and_call_original
57
- expect(Squasher).to receive(:ask).with(:keep_database).and_return(false)
58
- expect(Squasher).to receive(:rake).with("db:drop")
59
- expect(Squasher).to receive(:ask).with(:apply_clean).and_return(false)
60
- worker.process
61
- end
53
+ context 'with flags' do
54
+ before do
55
+ Squasher.instance_variable_set(:@config, Squasher::Config.new)
56
+ end
62
57
 
63
- specify 'reuse of an existing database' do
64
- worker = described_class.new(Time.new(2014), [:r])
65
- expect(Squasher).to receive(:tell).with(:db_reuse).and_call_original
66
- expect(Squasher).not_to receive(:rake).with("db:drop db:create", :db_create)
67
- allow(Squasher).to receive(:rake).with("db:migrate VERSION=20131213090719", :db_migrate).and_return(false)
68
- worker.process
58
+ specify 'the dry mode' do
59
+ Squasher.config.set(:d, nil)
60
+ worker = described_class.new(Time.new(2014))
61
+ allow(worker).to receive(:under_squash_env).and_yield.and_return(true)
62
+ expect(Squasher).to receive(:tell).with(:dry_mode_finished).and_call_original
63
+ expect(Squasher).to receive(:ask).with(:keep_database).and_return(false)
64
+ expect(Squasher).to receive(:rake).with("db:drop")
65
+ expect(Squasher).to receive(:ask).with(:apply_clean).and_return(false)
66
+ worker.process
67
+ end
68
+
69
+ specify 'reuse of an existing database' do
70
+ Squasher.config.set(:r, nil)
71
+ worker = described_class.new(Time.new(2014))
72
+ expect(Squasher).to receive(:tell).with(:db_reuse).and_call_original
73
+ expect(Squasher).not_to receive(:rake).with("db:drop db:create", :db_create)
74
+ allow(Squasher).to receive(:rake).with("db:migrate VERSION=20131213090719", :db_migrate).and_return(false)
75
+ worker.process
76
+ end
69
77
  end
70
78
  end
@@ -1,6 +1,3 @@
1
- require 'bundler/setup'
2
- Bundler.require
3
-
4
1
  module SpecHelpers
5
2
  def fake_root
6
3
  File.join(File.dirname(__FILE__), 'fake_app')
@@ -15,6 +12,9 @@ module Squasher
15
12
  end
16
13
  end
17
14
 
15
+ require 'bundler/setup'
16
+ Bundler.require
17
+
18
18
  RSpec.configure do |config|
19
19
  config.order = 'random'
20
20
  config.include SpecHelpers
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "squasher"
8
- spec.version = "0.2.2"
8
+ spec.version = "0.3.0"
9
9
  spec.authors = ["Sergey Pchelintsev"]
10
10
  spec.email = ["mail@sergeyp.me"]
11
11
  spec.description = %q{Squash your old migrations}
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.2.2
4
+ version: 0.3.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: 2017-03-09 00:00:00.000000000 Z
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,7 +70,7 @@ files:
70
70
  - lib/squasher.rb
71
71
  - lib/squasher/cleaner.rb
72
72
  - lib/squasher/config.rb
73
- - lib/squasher/messages.json
73
+ - lib/squasher/messages.yml
74
74
  - lib/squasher/render.rb
75
75
  - lib/squasher/templates/init_schema.rb.erb
76
76
  - lib/squasher/templates/squasher_clean.rb.erb
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
108
  version: '0'
109
109
  requirements: []
110
110
  rubyforge_project:
111
- rubygems_version: 2.4.5
111
+ rubygems_version: 2.6.11
112
112
  signing_key:
113
113
  specification_version: 4
114
114
  summary: Squash your old migrations
@@ -125,4 +125,3 @@ test_files:
125
125
  - spec/lib/squasher_spec.rb
126
126
  - spec/lib/worker_spec.rb
127
127
  - spec/spec_helper.rb
128
- has_rdoc:
@@ -1,42 +0,0 @@
1
- {
2
- "keep_database" : [
3
- "Squasher's created the `:green<squasher>` database for its needs.",
4
- "It might be useful to keep it if any of your deleted migrations inserts data or",
5
- "you squash migrations in few steps (look at -r option).",
6
- "Keep it (:green<yes> / :red<no>)?"
7
- ],
8
-
9
- "apply_clean": "Do you want to clean your database from the old schema migration records(:red<yes>/:green<no>)?",
10
-
11
- "migration_folder_missing" : [
12
- "The folder with migrations is missing.",
13
- "Are you sure that you're in the :red<root of a rails> application?"
14
- ],
15
-
16
- "no_migrations" : "There are no migrations in the folder prior to :red<%{date}>",
17
-
18
- "dbconfig_invalid" : "Squasher couldn't load `:green<database.yml>`. Please, make sure that it's present and doesn't include any ruby code.",
19
-
20
- "db_create": "Squasher is creating a tmp database",
21
-
22
- "db_migrate": "Squasher is applying migrations on a tmp database",
23
-
24
- "db_cleaning": "Squasher is applying the clean migration",
25
-
26
- "db_reuse": "Squasher is reusing the database from the previous squashing",
27
-
28
- "usage": [
29
- "Example usage:",
30
- " :green<squasher> [options] :yellow<year[/month][/day]> => squash migrations prior to a specified date",
31
- " :green<squasher> :yellow<clean> => generate or update a cleaning migration and apply it",
32
- " :green<squasher> :yellow<info> => show the message",
33
- "",
34
- "Options:",
35
- " :yellow<-d> => execute in :blue<`dry`> mode - test a squashing process without removing old migrations",
36
- " :yellow<-r> => reuse a database from the previous squashing"
37
- ],
38
-
39
- "wrong_option": "You provided a wrong option :red<%{o}>",
40
-
41
- "dry_mode_finished": "The `dry` mode is finished. Below the init schema's content:"
42
- }