ardb 0.27.3 → 0.29.0

Sign up to get free protection for your applications and to get access to all the features.
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