ardb 0.27.3 → 0.29.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.
Files changed (54) hide show
  1. checksums.yaml +7 -7
  2. data/Gemfile +4 -5
  3. data/README.md +252 -3
  4. data/ardb.gemspec +8 -8
  5. data/bin/ardb +1 -1
  6. data/lib/ardb.rb +155 -72
  7. data/lib/ardb/adapter/base.rb +67 -47
  8. data/lib/ardb/adapter/mysql.rb +3 -19
  9. data/lib/ardb/adapter/postgresql.rb +33 -37
  10. data/lib/ardb/adapter/sqlite.rb +7 -16
  11. data/lib/ardb/adapter_spy.rb +58 -92
  12. data/lib/ardb/cli.rb +18 -226
  13. data/lib/ardb/{clirb.rb → cli/clirb.rb} +16 -18
  14. data/lib/ardb/cli/commands.rb +365 -0
  15. data/lib/ardb/db_tests.rb +2 -4
  16. data/lib/ardb/default_order_by.rb +3 -13
  17. data/lib/ardb/migration.rb +18 -20
  18. data/lib/ardb/record_spy.rb +7 -26
  19. data/lib/ardb/relation_spy.rb +0 -6
  20. data/lib/ardb/require_autoloaded_active_record_files.rb +103 -58
  21. data/lib/ardb/test_helpers.rb +2 -5
  22. data/lib/ardb/use_db_default.rb +4 -15
  23. data/lib/ardb/version.rb +1 -1
  24. data/script/determine_autoloaded_active_record_files.rb +11 -8
  25. data/test/helper.rb +9 -6
  26. data/test/support/factory.rb +17 -2
  27. data/test/support/fake_schema.rb +5 -0
  28. data/test/support/postgresql/migrations/.keep +0 -0
  29. data/test/support/postgresql/schema.rb +2 -0
  30. data/test/support/postgresql/setup_test_db.rb +51 -0
  31. data/test/support/relative_require_test_db_file.rb +2 -0
  32. data/test/support/require_test_db_file.rb +1 -0
  33. data/test/system/.keep +0 -0
  34. data/test/unit/adapter/base_tests.rb +163 -75
  35. data/test/unit/adapter/mysql_tests.rb +4 -20
  36. data/test/unit/adapter/postgresql_tests.rb +20 -28
  37. data/test/unit/adapter/sqlite_tests.rb +9 -12
  38. data/test/unit/adapter_spy_tests.rb +48 -71
  39. data/test/unit/ardb_tests.rb +338 -38
  40. data/test/unit/cli_tests.rb +334 -225
  41. data/test/unit/db_tests_tests.rb +3 -6
  42. data/test/unit/default_order_by_tests.rb +4 -8
  43. data/test/unit/migration_tests.rb +20 -17
  44. data/test/unit/record_spy_tests.rb +18 -23
  45. data/test/unit/relation_spy_tests.rb +17 -46
  46. data/test/unit/test_helpers_tests.rb +5 -20
  47. data/test/unit/use_db_default_tests.rb +9 -13
  48. metadata +111 -100
  49. data/lib/ardb/has_slug.rb +0 -107
  50. data/lib/ardb/migration_helpers.rb +0 -77
  51. data/lib/ardb/root_path.rb +0 -15
  52. data/test/unit/config_tests.rb +0 -58
  53. data/test/unit/has_slug_tests.rb +0 -341
  54. data/test/unit/migration_helpers_tests.rb +0 -59
@@ -1,22 +1,19 @@
1
- require 'ardb'
2
- require 'ardb/clirb'
1
+ require "ardb/cli/clirb"
2
+ require "ardb/cli/commands"
3
+ require "ardb/version"
3
4
 
4
5
  module Ardb
5
-
6
6
  class CLI
7
-
8
- class InvalidCommand; end
9
- class ConnectCommand; end
10
- class CreateCommand; end
11
- class DropCommand; end
12
- class MigrateCommand; end
13
- class GenerateMigrationCommand; end
14
- COMMANDS = Hash.new{ |h, k| InvalidCommand.new(k) }.tap do |h|
15
- h['connect'] = ConnectCommand
16
- h['create'] = CreateCommand
17
- h['drop'] = DropCommand
18
- h['migrate'] = MigrateCommand
19
- h['generate-migration'] = GenerateMigrationCommand
7
+ COMMANDS = CommandSet.new{ |unknown| InvalidCommand.new(unknown) }.tap do |c|
8
+ c.add(ConnectCommand)
9
+ c.add(CreateCommand)
10
+ c.add(DropCommand)
11
+ c.add(GenerateMigrationCommand)
12
+ c.add(MigrateCommand)
13
+ c.add(MigrateUpCommand)
14
+ c.add(MigrateDownCommand)
15
+ c.add(MigrateForwardCommand)
16
+ c.add(MigrateBackwardCommand)
20
17
  end
21
18
 
22
19
  def self.run(args)
@@ -32,19 +29,18 @@ module Ardb
32
29
  def run(args)
33
30
  begin
34
31
  $LOAD_PATH.push(Dir.pwd) unless $LOAD_PATH.include?(Dir.pwd)
35
- Ardb.init(false) # don't establish a connection
36
32
 
37
33
  cmd_name = args.shift
38
- cmd = COMMANDS[cmd_name].new(args)
39
- cmd.run
34
+ cmd = COMMANDS[cmd_name]
35
+ cmd.run(args)
40
36
  rescue CLIRB::HelpExit
41
- @stdout.puts cmd.help
37
+ @stdout.puts cmd.command_help
42
38
  rescue CLIRB::VersionExit
43
39
  @stdout.puts Ardb::VERSION
44
40
  rescue CLIRB::Error, ArgumentError, InvalidCommandError => exception
45
41
  display_debug(exception)
46
42
  @stderr.puts "#{exception.message}\n\n"
47
- @stdout.puts cmd.help
43
+ @stdout.puts cmd.command_help
48
44
  @kernel.exit 1
49
45
  rescue CommandExitError
50
46
  @kernel.exit 1
@@ -59,214 +55,10 @@ module Ardb
59
55
  private
60
56
 
61
57
  def display_debug(exception)
62
- if ENV['DEBUG']
58
+ if ENV["DEBUG"]
63
59
  @stderr.puts "#{exception.class}: #{exception.message}"
64
60
  @stderr.puts exception.backtrace.join("\n")
65
61
  end
66
62
  end
67
-
68
- InvalidCommandError = Class.new(ArgumentError)
69
- CommandExitError = Class.new(RuntimeError)
70
-
71
- class InvalidCommand
72
-
73
- attr_reader :name, :argv, :clirb
74
-
75
- def initialize(name)
76
- @name = name
77
- @argv = []
78
- @clirb = Ardb::CLIRB.new
79
- end
80
-
81
- def new(args)
82
- @argv = [@name, args].flatten.compact
83
- self
84
- end
85
-
86
- def run
87
- @clirb.parse!(@argv)
88
- raise CLIRB::HelpExit if @clirb.args.empty? || @name.to_s.empty?
89
- raise InvalidCommandError, "'#{self.name}' is not a command."
90
- end
91
-
92
- def help
93
- "Usage: ardb [COMMAND] [options]\n\n" \
94
- "Commands: #{COMMANDS.keys.sort.join(', ')}\n" \
95
- "Options: #{@clirb}"
96
- end
97
-
98
- end
99
-
100
- class ConnectCommand
101
-
102
- attr_reader :clirb
103
-
104
- def initialize(argv, stdout = nil, stderr = nil)
105
- @argv = argv
106
- @stdout = stdout || $stdout
107
- @stderr = stderr || $stderr
108
-
109
- @clirb = Ardb::CLIRB.new
110
- @adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
111
- end
112
-
113
- def run
114
- @clirb.parse!(@argv)
115
- begin
116
- Ardb.init
117
- @adapter.connect_db
118
- @stdout.puts "connected to #{Ardb.config.db.adapter} db `#{Ardb.config.db.database}`"
119
- rescue StandardError => e
120
- @stderr.puts e
121
- @stderr.puts e.backtrace.join("\n")
122
- @stderr.puts "error connecting to #{Ardb.config.db.database.inspect} database " \
123
- "with #{Ardb.config.db_settings.inspect}"
124
- raise CommandExitError
125
- end
126
- end
127
-
128
- def help
129
- "Usage: ardb connect [options]\n\n" \
130
- "Options: #{@clirb}"
131
- end
132
-
133
- end
134
-
135
- class CreateCommand
136
-
137
- attr_reader :clirb
138
-
139
- def initialize(argv, stdout = nil, stderr = nil)
140
- @argv = argv
141
- @stdout = stdout || $stdout
142
- @stderr = stderr || $stderr
143
-
144
- @clirb = Ardb::CLIRB.new
145
- @adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
146
- end
147
-
148
- def run
149
- @clirb.parse!(@argv)
150
- begin
151
- @adapter.create_db
152
- @stdout.puts "created #{Ardb.config.db.adapter} db `#{Ardb.config.db.database}`"
153
- rescue StandardError => e
154
- @stderr.puts e
155
- @stderr.puts "error creating #{Ardb.config.db.database.inspect} database"
156
- raise CommandExitError
157
- end
158
- end
159
-
160
- def help
161
- "Usage: ardb create [options]\n\n" \
162
- "Options: #{@clirb}"
163
- end
164
-
165
- end
166
-
167
- class DropCommand
168
-
169
- attr_reader :clirb
170
-
171
- def initialize(argv, stdout = nil, stderr = nil)
172
- @argv = argv
173
- @stdout = stdout || $stdout
174
- @stderr = stderr || $stderr
175
-
176
- @clirb = Ardb::CLIRB.new
177
- @adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
178
- end
179
-
180
- def run
181
- @clirb.parse!(@argv)
182
- begin
183
- @adapter.drop_db
184
- @stdout.puts "dropped #{Ardb.config.db.adapter} db `#{Ardb.config.db.database}`"
185
- rescue StandardError => e
186
- @stderr.puts e
187
- @stderr.puts "error dropping #{Ardb.config.db.database.inspect} database"
188
- raise CommandExitError
189
- end
190
- end
191
-
192
- def help
193
- "Usage: ardb drop [options]\n\n" \
194
- "Options: #{@clirb}"
195
- end
196
-
197
- end
198
-
199
- class MigrateCommand
200
-
201
- attr_reader :clirb
202
-
203
- def initialize(argv, stdout = nil, stderr = nil)
204
- @argv = argv
205
- @stdout = stdout || $stdout
206
- @stderr = stderr || $stderr
207
-
208
- @clirb = Ardb::CLIRB.new
209
- @adapter = Ardb::Adapter.send(Ardb.config.db.adapter)
210
- end
211
-
212
- def run
213
- @clirb.parse!(@argv)
214
- begin
215
- Ardb.init
216
- @adapter.migrate_db
217
- @adapter.dump_schema unless ENV['ARDB_MIGRATE_NO_SCHEMA']
218
- rescue StandardError => e
219
- @stderr.puts e
220
- @stderr.puts e.backtrace.join("\n")
221
- @stderr.puts "error migrating #{Ardb.config.db.database.inspect} database"
222
- raise CommandExitError
223
- end
224
- end
225
-
226
- def help
227
- "Usage: ardb migrate [options]\n\n" \
228
- "Options: #{@clirb}"
229
- end
230
-
231
- end
232
-
233
- class GenerateMigrationCommand
234
-
235
- attr_reader :clirb
236
-
237
- def initialize(argv, stdout = nil, stderr = nil)
238
- @argv = argv
239
- @stdout = stdout || $stdout
240
- @stderr = stderr || $stderr
241
-
242
- @clirb = Ardb::CLIRB.new
243
- end
244
-
245
- def run
246
- @clirb.parse!(@argv)
247
- begin
248
- require "ardb/migration"
249
- path = Ardb::Migration.new(@clirb.args.first).save!.file_path
250
- @stdout.puts "generated #{path}"
251
- rescue Ardb::Migration::NoIdentifierError => exception
252
- error = ArgumentError.new("MIGRATION-NAME must be provided")
253
- error.set_backtrace(exception.backtrace)
254
- raise error
255
- rescue StandardError => e
256
- @stderr.puts e
257
- @stderr.puts e.backtrace.join("\n")
258
- @stderr.puts "error generating migration"
259
- raise CommandExitError
260
- end
261
- end
262
-
263
- def help
264
- "Usage: ardb generate-migration [options] MIGRATION-NAME\n\n" \
265
- "Options: #{@clirb}"
266
- end
267
-
268
- end
269
-
270
63
  end
271
-
272
64
  end
@@ -1,19 +1,19 @@
1
- module Ardb
2
-
3
- class CLIRB # Version 1.0.0, https://github.com/redding/cli.rb
1
+ module Ardb; end
2
+ class Ardb::CLI
3
+ class CLIRB # Version 1.1.0, https://github.com/redding/cli.rb
4
4
  Error = Class.new(RuntimeError);
5
5
  HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
6
6
  attr_reader :argv, :args, :opts, :data
7
7
 
8
8
  def initialize(&block)
9
9
  @options = []; instance_eval(&block) if block
10
- require 'optparse'
10
+ require "optparse"
11
11
  @data, @args, @opts = [], [], {}; @parser = OptionParser.new do |p|
12
- p.banner = ''; @options.each do |o|
12
+ p.banner = ""; @options.each do |o|
13
13
  @opts[o.name] = o.value; p.on(*o.parser_args){ |v| @opts[o.name] = v }
14
14
  end
15
- p.on_tail('--version', ''){ |v| raise VersionExit, v.to_s }
16
- p.on_tail('--help', ''){ |v| raise HelpExit, v.to_s }
15
+ p.on_tail("--version", ""){ |v| raise VersionExit, v.to_s }
16
+ p.on_tail("--help", ""){ |v| raise HelpExit, v.to_s }
17
17
  end
18
18
  end
19
19
 
@@ -26,33 +26,31 @@ module Ardb
26
26
  end
27
27
  def to_s; @parser.to_s; end
28
28
  def inspect
29
- "#<#{self.class}:#{'0x0%x' % (object_id << 1)} @data=#{@data.inspect}>"
29
+ "#<#{self.class}:#{"0x0%x" % (object_id << 1)} @data=#{@data.inspect}>"
30
30
  end
31
31
 
32
32
  class Option
33
33
  attr_reader :name, :opt_name, :desc, :abbrev, :value, :klass, :parser_args
34
34
 
35
- def initialize(name, *args)
36
- settings, @desc = args.last.kind_of?(::Hash) ? args.pop : {}, args.pop || ''
37
- @name, @opt_name, @abbrev = parse_name_values(name, settings[:abbrev])
38
- @value, @klass = gvalinfo(settings[:value])
35
+ def initialize(name, desc = nil, abbrev: nil, value: nil)
36
+ @name, @desc = name, desc || ""
37
+ @opt_name, @abbrev = parse_name_values(name, abbrev)
38
+ @value, @klass = gvalinfo(value)
39
39
  @parser_args = if [TrueClass, FalseClass, NilClass].include?(@klass)
40
40
  ["-#{@abbrev}", "--[no-]#{@opt_name}", @desc]
41
41
  else
42
- ["-#{@abbrev}", "--#{@opt_name} #{@opt_name.upcase}", @klass, @desc]
42
+ ["-#{@abbrev}", "--#{@opt_name} VALUE", @klass, @desc]
43
43
  end
44
44
  end
45
45
 
46
46
  private
47
47
 
48
48
  def parse_name_values(name, custom_abbrev)
49
- [ (processed_name = name.to_s.strip.downcase), processed_name.gsub('_', '-'),
50
- custom_abbrev || processed_name.gsub(/[^a-z]/, '').chars.first || 'a'
49
+ [ (processed_name = name.to_s.strip.downcase).gsub("_", "-"),
50
+ custom_abbrev || processed_name.gsub(/[^a-z]/, "").chars.first || "a"
51
51
  ]
52
52
  end
53
- def gvalinfo(v); v.kind_of?(Class) ? [nil,gklass(v)] : [v,gklass(v.class)]; end
54
- def gklass(k); k == Fixnum ? Integer : k; end
53
+ def gvalinfo(v); v.kind_of?(Class) ? [nil,v] : [v,v.class]; end
55
54
  end
56
55
  end
57
-
58
56
  end
@@ -0,0 +1,365 @@
1
+ require "ardb"
2
+ require "ardb/cli/clirb"
3
+ require "much-plugin"
4
+
5
+ module Ardb; end
6
+ class Ardb::CLI
7
+ InvalidCommandError = Class.new(ArgumentError)
8
+ CommandExitError = Class.new(RuntimeError)
9
+
10
+ class InvalidCommand
11
+ attr_reader :name, :clirb
12
+
13
+ def initialize(name)
14
+ @name = name
15
+ @clirb = CLIRB.new
16
+ end
17
+
18
+ def new; self; end
19
+
20
+ def run(argv)
21
+ @clirb.parse!([@name, argv].flatten.compact)
22
+ raise CLIRB::HelpExit if @name.to_s.empty?
23
+ raise InvalidCommandError, "\"#{self.name}\" is not a command."
24
+ end
25
+
26
+ def command_help
27
+ "Usage: ardb [COMMAND] [options]\n\n" \
28
+ "Options: #{@clirb}\n" \
29
+ "Commands:\n" \
30
+ "#{COMMANDS.to_s.split("\n").map{ |l| " #{l}" }.join("\n")}\n"
31
+ end
32
+ end
33
+
34
+ module ValidCommand
35
+ include MuchPlugin
36
+
37
+ plugin_class_methods do
38
+ def command_name; raise NotImplementedError; end
39
+ def command_summary; ""; end
40
+ end
41
+
42
+ plugin_instance_methods do
43
+ def initialize(&clirb_build)
44
+ @clirb = CLIRB.new(&clirb_build)
45
+ end
46
+
47
+ def clirb; @clirb; end
48
+
49
+ def run(argv, stdout = nil, stderr = nil)
50
+ @clirb.parse!(argv)
51
+ @stdout = stdout || $stdout
52
+ @stderr = stderr || $stderr
53
+ end
54
+
55
+ def command_name; self.class.command_name; end
56
+ def command_summary; self.class.command_summary; end
57
+
58
+ def command_help
59
+ "Usage: ardb #{self.command_name} [options]\n\n" \
60
+ "Options: #{self.clirb}\n" \
61
+ "Description:\n" \
62
+ " #{self.command_summary}"
63
+ end
64
+ end
65
+ end
66
+
67
+ class ConnectCommand
68
+ include ValidCommand
69
+
70
+ def self.command_name; "connect"; end
71
+ def self.command_summary; "Connect to the configured DB"; end
72
+
73
+ def run(argv, *args)
74
+ super
75
+
76
+ begin
77
+ Ardb.init(false)
78
+ Ardb.adapter.connect_db
79
+ @stdout.puts "connected to #{Ardb.config.adapter} db #{Ardb.config.database.inspect}"
80
+ rescue ActiveRecord::NoDatabaseError => e
81
+ @stderr.puts "error: database #{Ardb.config.database.inspect} "\
82
+ "does not exist"
83
+ rescue StandardError => e
84
+ @stderr.puts e
85
+ @stderr.puts e.backtrace.join("\n")
86
+ @stderr.puts "error connecting to #{Ardb.config.database.inspect} database " \
87
+ "with #{Ardb.config.activerecord_connect_hash.inspect}"
88
+ raise CommandExitError
89
+ end
90
+ end
91
+ end
92
+
93
+ class CreateCommand
94
+ include ValidCommand
95
+
96
+ def self.command_name; "create"; end
97
+ def self.command_summary; "Create the configured DB"; end
98
+
99
+ def run(argv, *args)
100
+ super
101
+
102
+ begin
103
+ Ardb.init(false)
104
+ Ardb.adapter.create_db
105
+ @stdout.puts "created #{Ardb.config.adapter} db #{Ardb.config.database.inspect}"
106
+ rescue ActiveRecord::StatementInvalid => e
107
+ @stderr.puts "error: database #{Ardb.config.database.inspect} "\
108
+ "already exists"
109
+ rescue StandardError => e
110
+ @stderr.puts e
111
+ @stderr.puts "error creating #{Ardb.config.database.inspect} database"
112
+ raise CommandExitError
113
+ end
114
+ end
115
+ end
116
+
117
+ class DropCommand
118
+ include ValidCommand
119
+
120
+ def self.command_name; "drop"; end
121
+ def self.command_summary; "Drop the configured DB"; end
122
+
123
+ def run(argv, *args)
124
+ super
125
+
126
+ begin
127
+ Ardb.init(true)
128
+ Ardb.adapter.drop_db
129
+ @stdout.puts "dropped #{Ardb.config.adapter} db #{Ardb.config.database.inspect}"
130
+ rescue ActiveRecord::NoDatabaseError => e
131
+ @stderr.puts "error: database #{Ardb.config.database.inspect} "\
132
+ "does not exist"
133
+ rescue StandardError => e
134
+ @stderr.puts e
135
+ @stderr.puts "error dropping #{Ardb.config.database.inspect} database"
136
+ raise CommandExitError
137
+ end
138
+ end
139
+ end
140
+
141
+ class GenerateMigrationCommand
142
+ include ValidCommand
143
+
144
+ def self.command_name; "generate-migration"; end
145
+ def self.command_summary; "Generate a MIGRATION-NAME migration file"; end
146
+
147
+ def run(argv, *args)
148
+ super
149
+
150
+ begin
151
+ Ardb.init(false)
152
+
153
+ require "ardb/migration"
154
+ migration = Ardb::Migration.new(Ardb.config, @clirb.args.first)
155
+ migration.save!
156
+ @stdout.puts "generated #{migration.file_path}"
157
+ rescue Ardb::Migration::NoIdentifierError => exception
158
+ error = ArgumentError.new("MIGRATION-NAME must be provided")
159
+ error.set_backtrace(exception.backtrace)
160
+ raise error
161
+ rescue StandardError => e
162
+ @stderr.puts e
163
+ @stderr.puts e.backtrace.join("\n")
164
+ @stderr.puts "error generating migration"
165
+ raise CommandExitError
166
+ end
167
+ end
168
+
169
+ def command_help
170
+ "Usage: ardb #{self.command_name} MIGRATION-NAME [options]\n\n" \
171
+ "Options: #{self.clirb}\n" \
172
+ "Description:\n" \
173
+ " #{self.command_summary}"
174
+ end
175
+ end
176
+
177
+ module MigrateCommandBehaviors
178
+ include MuchPlugin
179
+
180
+ plugin_included do
181
+ include ValidCommand
182
+ end
183
+
184
+ plugin_instance_methods do
185
+ def migrate; raise NotImplementedError; end
186
+
187
+ def run(argv, *args)
188
+ super
189
+
190
+ begin
191
+ Ardb.init(true)
192
+ self.migrate
193
+ Ardb.adapter.dump_schema unless ENV["ARDB_MIGRATE_NO_SCHEMA"]
194
+ rescue ActiveRecord::NoDatabaseError => e
195
+ @stderr.puts "error: database #{Ardb.config.database.inspect} "\
196
+ "does not exist"
197
+ rescue StandardError => e
198
+ @stderr.puts e
199
+ @stderr.puts e.backtrace.join("\n")
200
+ @stderr.puts "error migrating #{Ardb.config.database.inspect} database"
201
+ raise CommandExitError
202
+ end
203
+ end
204
+ end
205
+ end
206
+
207
+ class MigrateCommand
208
+ include MigrateCommandBehaviors
209
+
210
+ def self.command_name; "migrate"; end
211
+ def self.command_summary; "Migrate the configured DB"; end
212
+
213
+ def migrate
214
+ Ardb.adapter.migrate_db
215
+ end
216
+ end
217
+
218
+ module MigrateStyleBehaviors
219
+ include MuchPlugin
220
+
221
+ plugin_included do
222
+ include MigrateCommandBehaviors
223
+ end
224
+
225
+ plugin_class_methods do
226
+ def command_style; raise NotImplementedError; end
227
+
228
+ def command_name; "migrate-#{self.command_style}"; end
229
+ def command_summary; "Migrate the configured DB #{self.command_style}"; end
230
+ end
231
+
232
+ plugin_instance_methods do
233
+ def migrate
234
+ Ardb.adapter.send("migrate_db_#{self.class.command_style}", *migrate_args)
235
+ end
236
+
237
+ private
238
+
239
+ def migrate_args; raise NotImplementedError; end
240
+ end
241
+ end
242
+
243
+ module MigrateDirectionBehaviors
244
+ include MuchPlugin
245
+
246
+ plugin_included do
247
+ include MigrateStyleBehaviors
248
+ end
249
+
250
+ plugin_class_methods do
251
+ def command_style; self.command_direction; end
252
+ def command_direction; raise NotImplementedError; end
253
+ end
254
+
255
+ plugin_instance_methods do
256
+ def initialize
257
+ super do
258
+ option(:target_version, "version to migrate to", value: String)
259
+ end
260
+ end
261
+
262
+ private
263
+
264
+ def migrate_args
265
+ [@clirb.opts[:target_version]]
266
+ end
267
+ end
268
+ end
269
+
270
+ module MigrateStepDirectionBehaviors
271
+ include MuchPlugin
272
+
273
+ plugin_included do
274
+ include MigrateStyleBehaviors
275
+ end
276
+
277
+ plugin_class_methods do
278
+ def command_style; self.command_direction; end
279
+ def command_direction; raise NotImplementedError; end
280
+ end
281
+
282
+ plugin_instance_methods do
283
+ def initialize
284
+ super do
285
+ option(:steps, "number of migrations to migrate", value: 1)
286
+ end
287
+ end
288
+
289
+ private
290
+
291
+ def migrate_args
292
+ [@clirb.opts[:steps]]
293
+ end
294
+ end
295
+ end
296
+
297
+ class MigrateUpCommand
298
+ include MigrateDirectionBehaviors
299
+
300
+ def self.command_direction; "up"; end
301
+ end
302
+
303
+ class MigrateDownCommand
304
+ include MigrateDirectionBehaviors
305
+
306
+ def self.command_direction; "down"; end
307
+ end
308
+
309
+ class MigrateForwardCommand
310
+ include MigrateStepDirectionBehaviors
311
+
312
+ def self.command_direction; "forward"; end
313
+ end
314
+
315
+ class MigrateBackwardCommand
316
+ include MigrateStepDirectionBehaviors
317
+
318
+ def self.command_direction; "backward"; end
319
+ end
320
+
321
+ class CommandSet
322
+ def initialize(&unknown_cmd_block)
323
+ @lookup = Hash.new{ |h,k| unknown_cmd_block.call(k) }
324
+ @names = []
325
+ @aliases = {}
326
+ @summaries = {}
327
+ end
328
+
329
+ def add(klass)
330
+ begin
331
+ cmd = klass.new
332
+ rescue StandardError
333
+ # don"t add any commands you can"t initialize
334
+ else
335
+ @lookup[cmd.command_name] = cmd
336
+ @to_s = nil
337
+ @names << cmd.command_name
338
+ @summaries[cmd.command_name] = cmd.command_summary.to_s
339
+ end
340
+ end
341
+
342
+ def remove(klass)
343
+ @lookup.delete(klass.command_name)
344
+ @names.delete(klass.command_name)
345
+ @summaries.delete(klass.command_name)
346
+ @to_s = nil
347
+ end
348
+
349
+ def [](cmd_name)
350
+ @lookup[cmd_name]
351
+ end
352
+
353
+ def size
354
+ @names.size
355
+ end
356
+
357
+ def to_s
358
+ max_name_size = @names.map{ |n| n.size }.max || 0
359
+
360
+ @to_s ||= @names.map do |n|
361
+ "#{n.ljust(max_name_size)} #{@summaries[n]}"
362
+ end.join("\n")
363
+ end
364
+ end
365
+ end