engineyard 1.0.0 → 1.0.1

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 (34) hide show
  1. data/lib/engineyard/cli.rb +11 -2
  2. data/lib/engineyard/model/environment.rb +36 -3
  3. data/lib/engineyard/model/instance.rb +1 -1
  4. data/lib/engineyard/thor.rb +50 -68
  5. data/lib/engineyard/version.rb +1 -1
  6. data/spec/ey/deploy_spec.rb +66 -0
  7. metadata +23 -36
  8. data/lib/engineyard/vendor/thor.rb +0 -270
  9. data/lib/engineyard/vendor/thor/actions.rb +0 -297
  10. data/lib/engineyard/vendor/thor/actions/create_file.rb +0 -105
  11. data/lib/engineyard/vendor/thor/actions/directory.rb +0 -93
  12. data/lib/engineyard/vendor/thor/actions/empty_directory.rb +0 -134
  13. data/lib/engineyard/vendor/thor/actions/file_manipulation.rb +0 -229
  14. data/lib/engineyard/vendor/thor/actions/inject_into_file.rb +0 -104
  15. data/lib/engineyard/vendor/thor/base.rb +0 -540
  16. data/lib/engineyard/vendor/thor/core_ext/file_binary_read.rb +0 -9
  17. data/lib/engineyard/vendor/thor/core_ext/hash_with_indifferent_access.rb +0 -75
  18. data/lib/engineyard/vendor/thor/core_ext/ordered_hash.rb +0 -100
  19. data/lib/engineyard/vendor/thor/error.rb +0 -30
  20. data/lib/engineyard/vendor/thor/group.rb +0 -271
  21. data/lib/engineyard/vendor/thor/invocation.rb +0 -180
  22. data/lib/engineyard/vendor/thor/parser.rb +0 -4
  23. data/lib/engineyard/vendor/thor/parser/argument.rb +0 -67
  24. data/lib/engineyard/vendor/thor/parser/arguments.rb +0 -161
  25. data/lib/engineyard/vendor/thor/parser/option.rb +0 -128
  26. data/lib/engineyard/vendor/thor/parser/options.rb +0 -164
  27. data/lib/engineyard/vendor/thor/rake_compat.rb +0 -66
  28. data/lib/engineyard/vendor/thor/runner.rb +0 -314
  29. data/lib/engineyard/vendor/thor/shell.rb +0 -83
  30. data/lib/engineyard/vendor/thor/shell/basic.rb +0 -268
  31. data/lib/engineyard/vendor/thor/shell/color.rb +0 -108
  32. data/lib/engineyard/vendor/thor/task.rb +0 -102
  33. data/lib/engineyard/vendor/thor/util.rb +0 -229
  34. data/lib/engineyard/vendor/thor/version.rb +0 -3
@@ -1,540 +0,0 @@
1
- require 'thor/core_ext/hash_with_indifferent_access'
2
- require 'thor/core_ext/ordered_hash'
3
- require 'thor/error'
4
- require 'thor/shell'
5
- require 'thor/invocation'
6
- require 'thor/parser'
7
- require 'thor/task'
8
- require 'thor/util'
9
-
10
- class Thor
11
- autoload :Actions, 'thor/actions'
12
- autoload :RakeCompat, 'thor/rake_compat'
13
-
14
- # Shortcuts for help.
15
- HELP_MAPPINGS = %w(-h -? --help -D)
16
-
17
- # Thor methods that should not be overwritten by the user.
18
- THOR_RESERVED_WORDS = %w(invoke shell options behavior root destination_root relative_root
19
- action add_file create_file in_root inside run run_ruby_script)
20
-
21
- module Base
22
- attr_accessor :options
23
-
24
- # It receives arguments in an Array and two hashes, one for options and
25
- # other for configuration.
26
- #
27
- # Notice that it does not check if all required arguments were supplied.
28
- # It should be done by the parser.
29
- #
30
- # ==== Parameters
31
- # args<Array[Object]>:: An array of objects. The objects are applied to their
32
- # respective accessors declared with <tt>argument</tt>.
33
- #
34
- # options<Hash>:: An options hash that will be available as self.options.
35
- # The hash given is converted to a hash with indifferent
36
- # access, magic predicates (options.skip?) and then frozen.
37
- #
38
- # config<Hash>:: Configuration for this Thor class.
39
- #
40
- def initialize(args=[], options={}, config={})
41
- args = Thor::Arguments.parse(self.class.arguments, args)
42
- args.each { |key, value| send("#{key}=", value) }
43
-
44
- parse_options = self.class.class_options
45
-
46
- if options.is_a?(Array)
47
- task_options = config.delete(:task_options) # hook for start
48
- parse_options = parse_options.merge(task_options) if task_options
49
- array_options, hash_options = options, {}
50
- else
51
- array_options, hash_options = [], options
52
- end
53
-
54
- opts = Thor::Options.new(parse_options, hash_options)
55
- self.options = opts.parse(array_options)
56
- opts.check_unknown! if self.class.check_unknown_options?
57
- end
58
-
59
- class << self
60
- def included(base) #:nodoc:
61
- base.send :extend, ClassMethods
62
- base.send :include, Invocation
63
- base.send :include, Shell
64
- end
65
-
66
- # Returns the classes that inherits from Thor or Thor::Group.
67
- #
68
- # ==== Returns
69
- # Array[Class]
70
- #
71
- def subclasses
72
- @subclasses ||= []
73
- end
74
-
75
- # Returns the files where the subclasses are kept.
76
- #
77
- # ==== Returns
78
- # Hash[path<String> => Class]
79
- #
80
- def subclass_files
81
- @subclass_files ||= Hash.new{ |h,k| h[k] = [] }
82
- end
83
-
84
- # Whenever a class inherits from Thor or Thor::Group, we should track the
85
- # class and the file on Thor::Base. This is the method responsable for it.
86
- #
87
- def register_klass_file(klass) #:nodoc:
88
- file = caller[1].match(/(.*):\d+/)[1]
89
- Thor::Base.subclasses << klass unless Thor::Base.subclasses.include?(klass)
90
-
91
- file_subclasses = Thor::Base.subclass_files[File.expand_path(file)]
92
- file_subclasses << klass unless file_subclasses.include?(klass)
93
- end
94
- end
95
-
96
- module ClassMethods
97
- attr_accessor :debugging
98
-
99
- def attr_reader(*) #:nodoc:
100
- no_tasks { super }
101
- end
102
-
103
- def attr_writer(*) #:nodoc:
104
- no_tasks { super }
105
- end
106
-
107
- def attr_accessor(*) #:nodoc:
108
- no_tasks { super }
109
- end
110
-
111
- # If you want to raise an error for unknown options, call check_unknown_options!
112
- # This is disabled by default to allow dynamic invocations.
113
- def check_unknown_options!
114
- @check_unknown_options = true
115
- end
116
-
117
- def check_unknown_options? #:nodoc:
118
- @check_unknown_options || false
119
- end
120
-
121
- # Adds an argument to the class and creates an attr_accessor for it.
122
- #
123
- # Arguments are different from options in several aspects. The first one
124
- # is how they are parsed from the command line, arguments are retrieved
125
- # from position:
126
- #
127
- # thor task NAME
128
- #
129
- # Instead of:
130
- #
131
- # thor task --name=NAME
132
- #
133
- # Besides, arguments are used inside your code as an accessor (self.argument),
134
- # while options are all kept in a hash (self.options).
135
- #
136
- # Finally, arguments cannot have type :default or :boolean but can be
137
- # optional (supplying :optional => :true or :required => false), although
138
- # you cannot have a required argument after a non-required argument. If you
139
- # try it, an error is raised.
140
- #
141
- # ==== Parameters
142
- # name<Symbol>:: The name of the argument.
143
- # options<Hash>:: Described below.
144
- #
145
- # ==== Options
146
- # :desc - Description for the argument.
147
- # :required - If the argument is required or not.
148
- # :optional - If the argument is optional or not.
149
- # :type - The type of the argument, can be :string, :hash, :array, :numeric.
150
- # :default - Default value for this argument. It cannot be required and have default values.
151
- # :banner - String to show on usage notes.
152
- #
153
- # ==== Errors
154
- # ArgumentError:: Raised if you supply a required argument after a non required one.
155
- #
156
- def argument(name, options={})
157
- is_thor_reserved_word?(name, :argument)
158
- no_tasks { attr_accessor name }
159
-
160
- required = if options.key?(:optional)
161
- !options[:optional]
162
- elsif options.key?(:required)
163
- options[:required]
164
- else
165
- options[:default].nil?
166
- end
167
-
168
- remove_argument name
169
-
170
- arguments.each do |argument|
171
- next if argument.required?
172
- raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
173
- "the non-required argument #{argument.human_name.inspect}."
174
- end if required
175
-
176
- arguments << Thor::Argument.new(name, options[:desc], required, options[:type],
177
- options[:default], options[:banner])
178
- end
179
-
180
- # Returns this class arguments, looking up in the ancestors chain.
181
- #
182
- # ==== Returns
183
- # Array[Thor::Argument]
184
- #
185
- def arguments
186
- @arguments ||= from_superclass(:arguments, [])
187
- end
188
-
189
- # Adds a bunch of options to the set of class options.
190
- #
191
- # class_options :foo => false, :bar => :required, :baz => :string
192
- #
193
- # If you prefer more detailed declaration, check class_option.
194
- #
195
- # ==== Parameters
196
- # Hash[Symbol => Object]
197
- #
198
- def class_options(options=nil)
199
- @class_options ||= from_superclass(:class_options, {})
200
- build_options(options, @class_options) if options
201
- @class_options
202
- end
203
-
204
- # Adds an option to the set of class options
205
- #
206
- # ==== Parameters
207
- # name<Symbol>:: The name of the argument.
208
- # options<Hash>:: Described below.
209
- #
210
- # ==== Options
211
- # :desc - Description for the argument.
212
- # :required - If the argument is required or not.
213
- # :default - Default value for this argument.
214
- # :group - The group for this options. Use by class options to output options in different levels.
215
- # :aliases - Aliases for this option.
216
- # :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
217
- # :banner - String to show on usage notes.
218
- #
219
- def class_option(name, options={})
220
- build_option(name, options, class_options)
221
- end
222
-
223
- # Removes a previous defined argument. If :undefine is given, undefine
224
- # accessors as well.
225
- #
226
- # ==== Paremeters
227
- # names<Array>:: Arguments to be removed
228
- #
229
- # ==== Examples
230
- #
231
- # remove_argument :foo
232
- # remove_argument :foo, :bar, :baz, :undefine => true
233
- #
234
- def remove_argument(*names)
235
- options = names.last.is_a?(Hash) ? names.pop : {}
236
-
237
- names.each do |name|
238
- arguments.delete_if { |a| a.name == name.to_s }
239
- undef_method name, "#{name}=" if options[:undefine]
240
- end
241
- end
242
-
243
- # Removes a previous defined class option.
244
- #
245
- # ==== Paremeters
246
- # names<Array>:: Class options to be removed
247
- #
248
- # ==== Examples
249
- #
250
- # remove_class_option :foo
251
- # remove_class_option :foo, :bar, :baz
252
- #
253
- def remove_class_option(*names)
254
- names.each do |name|
255
- class_options.delete(name)
256
- end
257
- end
258
-
259
- # Defines the group. This is used when thor list is invoked so you can specify
260
- # that only tasks from a pre-defined group will be shown. Defaults to standard.
261
- #
262
- # ==== Parameters
263
- # name<String|Symbol>
264
- #
265
- def group(name=nil)
266
- case name
267
- when nil
268
- @group ||= from_superclass(:group, 'standard')
269
- else
270
- @group = name.to_s
271
- end
272
- end
273
-
274
- # Returns the tasks for this Thor class.
275
- #
276
- # ==== Returns
277
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
278
- # objects as values.
279
- #
280
- def tasks
281
- @tasks ||= Thor::CoreExt::OrderedHash.new
282
- end
283
-
284
- # Returns the tasks for this Thor class and all subclasses.
285
- #
286
- # ==== Returns
287
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
288
- # objects as values.
289
- #
290
- def all_tasks
291
- @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new)
292
- @all_tasks.merge(tasks)
293
- end
294
-
295
- # Removes a given task from this Thor class. This is usually done if you
296
- # are inheriting from another class and don't want it to be available
297
- # anymore.
298
- #
299
- # By default it only remove the mapping to the task. But you can supply
300
- # :undefine => true to undefine the method from the class as well.
301
- #
302
- # ==== Parameters
303
- # name<Symbol|String>:: The name of the task to be removed
304
- # options<Hash>:: You can give :undefine => true if you want tasks the method
305
- # to be undefined from the class as well.
306
- #
307
- def remove_task(*names)
308
- options = names.last.is_a?(Hash) ? names.pop : {}
309
-
310
- names.each do |name|
311
- tasks.delete(name.to_s)
312
- all_tasks.delete(name.to_s)
313
- undef_method name if options[:undefine]
314
- end
315
- end
316
-
317
- # All methods defined inside the given block are not added as tasks.
318
- #
319
- # So you can do:
320
- #
321
- # class MyScript < Thor
322
- # no_tasks do
323
- # def this_is_not_a_task
324
- # end
325
- # end
326
- # end
327
- #
328
- # You can also add the method and remove it from the task list:
329
- #
330
- # class MyScript < Thor
331
- # def this_is_not_a_task
332
- # end
333
- # remove_task :this_is_not_a_task
334
- # end
335
- #
336
- def no_tasks
337
- @no_tasks = true
338
- yield
339
- @no_tasks = false
340
- end
341
-
342
- # Sets the namespace for the Thor or Thor::Group class. By default the
343
- # namespace is retrieved from the class name. If your Thor class is named
344
- # Scripts::MyScript, the help method, for example, will be called as:
345
- #
346
- # thor scripts:my_script -h
347
- #
348
- # If you change the namespace:
349
- #
350
- # namespace :my_scripts
351
- #
352
- # You change how your tasks are invoked:
353
- #
354
- # thor my_scripts -h
355
- #
356
- # Finally, if you change your namespace to default:
357
- #
358
- # namespace :default
359
- #
360
- # Your tasks can be invoked with a shortcut. Instead of:
361
- #
362
- # thor :my_task
363
- #
364
- def namespace(name=nil)
365
- case name
366
- when nil
367
- @namespace ||= Thor::Util.namespace_from_thor_class(self)
368
- else
369
- @namespace = name.to_s
370
- end
371
- end
372
-
373
- # Default way to start generators from the command line.
374
- #
375
- def start(given_args=ARGV, config={})
376
- self.debugging = given_args.include?("--debug")
377
- config[:shell] ||= Thor::Base.shell.new
378
- yield(given_args.dup)
379
- rescue Thor::Error => e
380
- debugging ? (raise e) : config[:shell].error(e.message)
381
- exit(1) if exit_on_failure?
382
- end
383
-
384
- def handle_no_task_error(task) #:nodoc:
385
- if self.banner_base == "thor"
386
- raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace."
387
- else
388
- raise UndefinedTaskError, "Could not find task #{task.inspect}."
389
- end
390
- end
391
-
392
- protected
393
-
394
- # Prints the class options per group. If an option does not belong to
395
- # any group, it's printed as Class option.
396
- #
397
- def class_options_help(shell, groups={}) #:nodoc:
398
- # Group options by group
399
- class_options.each do |_, value|
400
- groups[value.group] ||= []
401
- groups[value.group] << value
402
- end
403
-
404
- # Deal with default group
405
- global_options = groups.delete(nil) || []
406
- print_options(shell, global_options)
407
-
408
- # Print all others
409
- groups.each do |group_name, options|
410
- print_options(shell, options, group_name)
411
- end
412
- end
413
-
414
- # Receives a set of options and print them.
415
- def print_options(shell, options, group_name=nil)
416
- return if options.empty?
417
-
418
- list = []
419
- padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
420
-
421
- options.each do |option|
422
- item = [ option.usage(padding) ]
423
- item.push(option.description ? "# #{option.description}" : "")
424
-
425
- list << item
426
- list << [ "", "# Default: #{option.default}" ] if option.show_default?
427
- end
428
-
429
- shell.say(group_name ? "#{group_name} options:" : "Options:")
430
- shell.print_table(list, :ident => 2)
431
- shell.say ""
432
- end
433
-
434
- # Raises an error if the word given is a Thor reserved word.
435
- def is_thor_reserved_word?(word, type) #:nodoc:
436
- return false unless THOR_RESERVED_WORDS.include?(word.to_s)
437
- raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
438
- end
439
-
440
- # Build an option and adds it to the given scope.
441
- #
442
- # ==== Parameters
443
- # name<Symbol>:: The name of the argument.
444
- # options<Hash>:: Described in both class_option and method_option.
445
- def build_option(name, options, scope) #:nodoc:
446
- scope[name] = Thor::Option.new(name, options[:desc], options[:required],
447
- options[:type], options[:default], options[:banner],
448
- options[:group], options[:aliases])
449
- end
450
-
451
- # Receives a hash of options, parse them and add to the scope. This is a
452
- # fast way to set a bunch of options:
453
- #
454
- # build_options :foo => true, :bar => :required, :baz => :string
455
- #
456
- # ==== Parameters
457
- # Hash[Symbol => Object]
458
- def build_options(options, scope) #:nodoc:
459
- options.each do |key, value|
460
- scope[key] = Thor::Option.parse(key, value)
461
- end
462
- end
463
-
464
- # Finds a task with the given name. If the task belongs to the current
465
- # class, just return it, otherwise dup it and add the fresh copy to the
466
- # current task hash.
467
- def find_and_refresh_task(name) #:nodoc:
468
- task = if task = tasks[name.to_s]
469
- task
470
- elsif task = all_tasks[name.to_s]
471
- tasks[name.to_s] = task.clone
472
- else
473
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found."
474
- end
475
- end
476
-
477
- # Everytime someone inherits from a Thor class, register the klass
478
- # and file into baseclass.
479
- def inherited(klass)
480
- Thor::Base.register_klass_file(klass)
481
- end
482
-
483
- # Fire this callback whenever a method is added. Added methods are
484
- # tracked as tasks by invoking the create_task method.
485
- def method_added(meth)
486
- meth = meth.to_s
487
-
488
- if meth == "initialize"
489
- initialize_added
490
- return
491
- end
492
-
493
- # Return if it's not a public instance method
494
- return unless public_instance_methods.include?(meth) ||
495
- public_instance_methods.include?(meth.to_sym)
496
-
497
- return if @no_tasks || !create_task(meth)
498
-
499
- is_thor_reserved_word?(meth, :task)
500
- Thor::Base.register_klass_file(self)
501
- end
502
-
503
- # Retrieves a value from superclass. If it reaches the baseclass,
504
- # returns default.
505
- def from_superclass(method, default=nil)
506
- if self == baseclass || !superclass.respond_to?(method, true)
507
- default
508
- else
509
- value = superclass.send(method)
510
- value.dup if value
511
- end
512
- end
513
-
514
- # A flag that makes the process exit with status 1 if any error happens.
515
- def exit_on_failure?
516
- false
517
- end
518
-
519
- # Returns the base for banner.
520
- def banner_base
521
- @banner_base ||= $thor_runner ? "thor" : File.basename($0.split(" ").first)
522
- end
523
-
524
- # SIGNATURE: Sets the baseclass. This is where the superclass lookup
525
- # finishes.
526
- def baseclass #:nodoc:
527
- end
528
-
529
- # SIGNATURE: Creates a new task if valid_task? is true. This method is
530
- # called when a new method is added to the class.
531
- def create_task(meth) #:nodoc:
532
- end
533
-
534
- # SIGNATURE: Defines behavior when the initialize method is added to the
535
- # class.
536
- def initialize_added #:nodoc:
537
- end
538
- end
539
- end
540
- end