engineyard 1.0.0 → 1.0.1

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