engineyard 2.0.0.pre1 → 2.0.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. data/README.rdoc +39 -136
  2. data/bin/ey_perftools +12 -0
  3. data/lib/engineyard.rb +0 -2
  4. data/lib/engineyard/cli.rb +3 -4
  5. data/lib/engineyard/cli/api.rb +3 -2
  6. data/lib/engineyard/commands/deploy.rb +0 -0
  7. data/lib/engineyard/thor.rb +7 -3
  8. data/lib/engineyard/version.rb +1 -1
  9. data/spec/engineyard/cli/api_spec.rb +6 -0
  10. data/spec/ey/deploy_spec.rb +6 -0
  11. data/spec/ey/ssh_spec.rb +6 -6
  12. metadata +24 -37
  13. data/lib/vendor/thor/LICENSE.md +0 -20
  14. data/lib/vendor/thor/README.md +0 -26
  15. data/lib/vendor/thor/lib/thor.rb +0 -379
  16. data/lib/vendor/thor/lib/thor/actions.rb +0 -318
  17. data/lib/vendor/thor/lib/thor/actions/create_file.rb +0 -105
  18. data/lib/vendor/thor/lib/thor/actions/create_link.rb +0 -57
  19. data/lib/vendor/thor/lib/thor/actions/directory.rb +0 -97
  20. data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +0 -153
  21. data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +0 -308
  22. data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +0 -109
  23. data/lib/vendor/thor/lib/thor/base.rb +0 -611
  24. data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +0 -9
  25. data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +0 -75
  26. data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +0 -100
  27. data/lib/vendor/thor/lib/thor/error.rb +0 -35
  28. data/lib/vendor/thor/lib/thor/group.rb +0 -285
  29. data/lib/vendor/thor/lib/thor/invocation.rb +0 -170
  30. data/lib/vendor/thor/lib/thor/parser.rb +0 -4
  31. data/lib/vendor/thor/lib/thor/parser/argument.rb +0 -67
  32. data/lib/vendor/thor/lib/thor/parser/arguments.rb +0 -165
  33. data/lib/vendor/thor/lib/thor/parser/option.rb +0 -121
  34. data/lib/vendor/thor/lib/thor/parser/options.rb +0 -181
  35. data/lib/vendor/thor/lib/thor/rake_compat.rb +0 -71
  36. data/lib/vendor/thor/lib/thor/runner.rb +0 -321
  37. data/lib/vendor/thor/lib/thor/shell.rb +0 -88
  38. data/lib/vendor/thor/lib/thor/shell/basic.rb +0 -331
  39. data/lib/vendor/thor/lib/thor/shell/color.rb +0 -108
  40. data/lib/vendor/thor/lib/thor/shell/html.rb +0 -121
  41. data/lib/vendor/thor/lib/thor/task.rb +0 -132
  42. data/lib/vendor/thor/lib/thor/util.rb +0 -248
  43. data/lib/vendor/thor/lib/thor/version.rb +0 -3
@@ -1,109 +0,0 @@
1
- require 'thor/actions/empty_directory'
2
-
3
- class Thor
4
- module Actions
5
-
6
- # Injects the given content into a file. Different from gsub_file, this
7
- # method is reversible.
8
- #
9
- # ==== Parameters
10
- # destination<String>:: Relative path to the destination root
11
- # data<String>:: Data to add to the file. Can be given as a block.
12
- # config<Hash>:: give :verbose => false to not log the status and the flag
13
- # for injection (:after or :before) or :force => true for
14
- # insert two or more times the same content.
15
- #
16
- # ==== Examples
17
- #
18
- # insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
19
- #
20
- # insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
21
- # gems = ask "Which gems would you like to add?"
22
- # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
23
- # end
24
- #
25
- def insert_into_file(destination, *args, &block)
26
- if block_given?
27
- data, config = block, args.shift
28
- else
29
- data, config = args.shift, args.shift
30
- end
31
- action InjectIntoFile.new(self, destination, data, config)
32
- end
33
- alias_method :inject_into_file, :insert_into_file
34
-
35
- class InjectIntoFile < EmptyDirectory #:nodoc:
36
- attr_reader :replacement, :flag, :behavior
37
-
38
- def initialize(base, destination, data, config)
39
- super(base, destination, { :verbose => true }.merge(config))
40
-
41
- @behavior, @flag = if @config.key?(:after)
42
- [:after, @config.delete(:after)]
43
- else
44
- [:before, @config.delete(:before)]
45
- end
46
-
47
- @replacement = data.is_a?(Proc) ? data.call : data
48
- @flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
49
- end
50
-
51
- def invoke!
52
- say_status :invoke
53
-
54
- content = if @behavior == :after
55
- '\0' + replacement
56
- else
57
- replacement + '\0'
58
- end
59
-
60
- replace!(/#{flag}/, content, config[:force])
61
- end
62
-
63
- def revoke!
64
- say_status :revoke
65
-
66
- regexp = if @behavior == :after
67
- content = '\1\2'
68
- /(#{flag})(.*)(#{Regexp.escape(replacement)})/m
69
- else
70
- content = '\2\3'
71
- /(#{Regexp.escape(replacement)})(.*)(#{flag})/m
72
- end
73
-
74
- replace!(regexp, content, true)
75
- end
76
-
77
- protected
78
-
79
- def say_status(behavior)
80
- status = if behavior == :invoke
81
- if flag == /\A/
82
- :prepend
83
- elsif flag == /\z/
84
- :append
85
- else
86
- :insert
87
- end
88
- else
89
- :subtract
90
- end
91
-
92
- super(status, config[:verbose])
93
- end
94
-
95
- # Adds the content to the file.
96
- #
97
- def replace!(regexp, string, force)
98
- unless base.options[:pretend]
99
- content = File.binread(destination)
100
- if force || !content.include?(replacement)
101
- content.gsub!(regexp, string)
102
- File.open(destination, 'wb') { |file| file.write(content) }
103
- end
104
- end
105
- end
106
-
107
- end
108
- end
109
- end
@@ -1,611 +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, :parent_options, :args
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
- parse_options = self.class.class_options
42
-
43
- # The start method splits inbound arguments at the first argument
44
- # that looks like an option (starts with - or --). It then calls
45
- # new, passing in the two halves of the arguments Array as the
46
- # first two parameters.
47
-
48
- if options.is_a?(Array)
49
- task_options = config.delete(:task_options) # hook for start
50
- parse_options = parse_options.merge(task_options) if task_options
51
- array_options, hash_options = options, {}
52
- else
53
- # Handle the case where the class was explicitly instantiated
54
- # with pre-parsed options.
55
- array_options, hash_options = [], options
56
- end
57
-
58
- # Let Thor::Options parse the options first, so it can remove
59
- # declared options from the array. This will leave us with
60
- # a list of arguments that weren't declared.
61
- opts = Thor::Options.new(parse_options, hash_options)
62
- self.options = opts.parse(array_options)
63
-
64
- # If unknown options are disallowed, make sure that none of the
65
- # remaining arguments looks like an option.
66
- opts.check_unknown! if self.class.check_unknown_options?(config)
67
-
68
- # Add the remaining arguments from the options parser to the
69
- # arguments passed in to initialize. Then remove any positional
70
- # arguments declared using #argument (this is primarily used
71
- # by Thor::Group). Tis will leave us with the remaining
72
- # positional arguments.
73
- thor_args = Thor::Arguments.new(self.class.arguments)
74
- thor_args.parse(args + opts.remaining).each { |k,v| send("#{k}=", v) }
75
- args = thor_args.remaining
76
-
77
- @args = args
78
- end
79
-
80
- class << self
81
- def included(base) #:nodoc:
82
- base.send :extend, ClassMethods
83
- base.send :include, Invocation
84
- base.send :include, Shell
85
- end
86
-
87
- # Returns the classes that inherits from Thor or Thor::Group.
88
- #
89
- # ==== Returns
90
- # Array[Class]
91
- #
92
- def subclasses
93
- @subclasses ||= []
94
- end
95
-
96
- # Returns the files where the subclasses are kept.
97
- #
98
- # ==== Returns
99
- # Hash[path<String> => Class]
100
- #
101
- def subclass_files
102
- @subclass_files ||= Hash.new{ |h,k| h[k] = [] }
103
- end
104
-
105
- # Whenever a class inherits from Thor or Thor::Group, we should track the
106
- # class and the file on Thor::Base. This is the method responsable for it.
107
- #
108
- def register_klass_file(klass) #:nodoc:
109
- file = caller[1].match(/(.*):\d+/)[1]
110
- Thor::Base.subclasses << klass unless Thor::Base.subclasses.include?(klass)
111
-
112
- file_subclasses = Thor::Base.subclass_files[File.expand_path(file)]
113
- file_subclasses << klass unless file_subclasses.include?(klass)
114
- end
115
- end
116
-
117
- module ClassMethods
118
- def attr_reader(*) #:nodoc:
119
- no_tasks { super }
120
- end
121
-
122
- def attr_writer(*) #:nodoc:
123
- no_tasks { super }
124
- end
125
-
126
- def attr_accessor(*) #:nodoc:
127
- no_tasks { super }
128
- end
129
-
130
- # If you want to raise an error for unknown options, call check_unknown_options!
131
- # This is disabled by default to allow dynamic invocations.
132
- def check_unknown_options!
133
- @check_unknown_options = true
134
- end
135
-
136
- def check_unknown_options #:nodoc:
137
- @check_unknown_options ||= from_superclass(:check_unknown_options, false)
138
- end
139
-
140
- def check_unknown_options?(config) #:nodoc:
141
- !!check_unknown_options
142
- end
143
-
144
- # Adds an argument to the class and creates an attr_accessor for it.
145
- #
146
- # Arguments are different from options in several aspects. The first one
147
- # is how they are parsed from the command line, arguments are retrieved
148
- # from position:
149
- #
150
- # thor task NAME
151
- #
152
- # Instead of:
153
- #
154
- # thor task --name=NAME
155
- #
156
- # Besides, arguments are used inside your code as an accessor (self.argument),
157
- # while options are all kept in a hash (self.options).
158
- #
159
- # Finally, arguments cannot have type :default or :boolean but can be
160
- # optional (supplying :optional => :true or :required => false), although
161
- # you cannot have a required argument after a non-required argument. If you
162
- # try it, an error is raised.
163
- #
164
- # ==== Parameters
165
- # name<Symbol>:: The name of the argument.
166
- # options<Hash>:: Described below.
167
- #
168
- # ==== Options
169
- # :desc - Description for the argument.
170
- # :required - If the argument is required or not.
171
- # :optional - If the argument is optional or not.
172
- # :type - The type of the argument, can be :string, :hash, :array, :numeric.
173
- # :default - Default value for this argument. It cannot be required and have default values.
174
- # :banner - String to show on usage notes.
175
- #
176
- # ==== Errors
177
- # ArgumentError:: Raised if you supply a required argument after a non required one.
178
- #
179
- def argument(name, options={})
180
- is_thor_reserved_word?(name, :argument)
181
- no_tasks { attr_accessor name }
182
-
183
- required = if options.key?(:optional)
184
- !options[:optional]
185
- elsif options.key?(:required)
186
- options[:required]
187
- else
188
- options[:default].nil?
189
- end
190
-
191
- remove_argument name
192
-
193
- arguments.each do |argument|
194
- next if argument.required?
195
- raise ArgumentError, "You cannot have #{name.to_s.inspect} as required argument after " <<
196
- "the non-required argument #{argument.human_name.inspect}."
197
- end if required
198
-
199
- arguments << Thor::Argument.new(name, options[:desc], required, options[:type],
200
- options[:default], options[:banner])
201
- end
202
-
203
- # Returns this class arguments, looking up in the ancestors chain.
204
- #
205
- # ==== Returns
206
- # Array[Thor::Argument]
207
- #
208
- def arguments
209
- @arguments ||= from_superclass(:arguments, [])
210
- end
211
-
212
- # Adds a bunch of options to the set of class options.
213
- #
214
- # class_options :foo => false, :bar => :required, :baz => :string
215
- #
216
- # If you prefer more detailed declaration, check class_option.
217
- #
218
- # ==== Parameters
219
- # Hash[Symbol => Object]
220
- #
221
- def class_options(options=nil)
222
- @class_options ||= from_superclass(:class_options, {})
223
- build_options(options, @class_options) if options
224
- @class_options
225
- end
226
-
227
- # Adds an option to the set of class options
228
- #
229
- # ==== Parameters
230
- # name<Symbol>:: The name of the argument.
231
- # options<Hash>:: Described below.
232
- #
233
- # ==== Options
234
- # :desc:: -- Description for the argument.
235
- # :required:: -- If the argument is required or not.
236
- # :default:: -- Default value for this argument.
237
- # :group:: -- The group for this options. Use by class options to output options in different levels.
238
- # :aliases:: -- Aliases for this option. <b>Note:</b> Thor follows a convention of one-dash-one-letter options. Thus aliases like "-something" wouldn't be parsed; use either "\--something" or "-s" instead.
239
- # :type:: -- The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
240
- # :banner:: -- String to show on usage notes.
241
- # :hide:: -- If you want to hide this option from the help.
242
- #
243
- def class_option(name, options={})
244
- build_option(name, options, class_options)
245
- end
246
-
247
- # Removes a previous defined argument. If :undefine is given, undefine
248
- # accessors as well.
249
- #
250
- # ==== Parameters
251
- # names<Array>:: Arguments to be removed
252
- #
253
- # ==== Examples
254
- #
255
- # remove_argument :foo
256
- # remove_argument :foo, :bar, :baz, :undefine => true
257
- #
258
- def remove_argument(*names)
259
- options = names.last.is_a?(Hash) ? names.pop : {}
260
-
261
- names.each do |name|
262
- arguments.delete_if { |a| a.name == name.to_s }
263
- undef_method name, "#{name}=" if options[:undefine]
264
- end
265
- end
266
-
267
- # Removes a previous defined class option.
268
- #
269
- # ==== Parameters
270
- # names<Array>:: Class options to be removed
271
- #
272
- # ==== Examples
273
- #
274
- # remove_class_option :foo
275
- # remove_class_option :foo, :bar, :baz
276
- #
277
- def remove_class_option(*names)
278
- names.each do |name|
279
- class_options.delete(name)
280
- end
281
- end
282
-
283
- # Defines the group. This is used when thor list is invoked so you can specify
284
- # that only tasks from a pre-defined group will be shown. Defaults to standard.
285
- #
286
- # ==== Parameters
287
- # name<String|Symbol>
288
- #
289
- def group(name=nil)
290
- case name
291
- when nil
292
- @group ||= from_superclass(:group, 'standard')
293
- else
294
- @group = name.to_s
295
- end
296
- end
297
-
298
- # Returns the tasks for this Thor class.
299
- #
300
- # ==== Returns
301
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
302
- # objects as values.
303
- #
304
- def tasks
305
- @tasks ||= Thor::CoreExt::OrderedHash.new
306
- end
307
-
308
- # Returns the tasks for this Thor class and all subclasses.
309
- #
310
- # ==== Returns
311
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
312
- # objects as values.
313
- #
314
- def all_tasks
315
- @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new)
316
- @all_tasks.merge(tasks)
317
- end
318
-
319
- # Removes a given task from this Thor class. This is usually done if you
320
- # are inheriting from another class and don't want it to be available
321
- # anymore.
322
- #
323
- # By default it only remove the mapping to the task. But you can supply
324
- # :undefine => true to undefine the method from the class as well.
325
- #
326
- # ==== Parameters
327
- # name<Symbol|String>:: The name of the task to be removed
328
- # options<Hash>:: You can give :undefine => true if you want tasks the method
329
- # to be undefined from the class as well.
330
- #
331
- def remove_task(*names)
332
- options = names.last.is_a?(Hash) ? names.pop : {}
333
-
334
- names.each do |name|
335
- tasks.delete(name.to_s)
336
- all_tasks.delete(name.to_s)
337
- undef_method name if options[:undefine]
338
- end
339
- end
340
-
341
- # All methods defined inside the given block are not added as tasks.
342
- #
343
- # So you can do:
344
- #
345
- # class MyScript < Thor
346
- # no_tasks do
347
- # def this_is_not_a_task
348
- # end
349
- # end
350
- # end
351
- #
352
- # You can also add the method and remove it from the task list:
353
- #
354
- # class MyScript < Thor
355
- # def this_is_not_a_task
356
- # end
357
- # remove_task :this_is_not_a_task
358
- # end
359
- #
360
- def no_tasks
361
- @no_tasks = true
362
- yield
363
- ensure
364
- @no_tasks = false
365
- end
366
-
367
- # Sets the namespace for the Thor or Thor::Group class. By default the
368
- # namespace is retrieved from the class name. If your Thor class is named
369
- # Scripts::MyScript, the help method, for example, will be called as:
370
- #
371
- # thor scripts:my_script -h
372
- #
373
- # If you change the namespace:
374
- #
375
- # namespace :my_scripts
376
- #
377
- # You change how your tasks are invoked:
378
- #
379
- # thor my_scripts -h
380
- #
381
- # Finally, if you change your namespace to default:
382
- #
383
- # namespace :default
384
- #
385
- # Your tasks can be invoked with a shortcut. Instead of:
386
- #
387
- # thor :my_task
388
- #
389
- def namespace(name=nil)
390
- case name
391
- when nil
392
- @namespace ||= Thor::Util.namespace_from_thor_class(self)
393
- else
394
- @namespace = name.to_s
395
- end
396
- end
397
-
398
- # Parses the task and options from the given args, instantiate the class
399
- # and invoke the task. This method is used when the arguments must be parsed
400
- # from an array. If you are inside Ruby and want to use a Thor class, you
401
- # can simply initialize it:
402
- #
403
- # script = MyScript.new(args, options, config)
404
- # script.invoke(:task, first_arg, second_arg, third_arg)
405
- #
406
- def start(given_args=ARGV, config={})
407
- config[:shell] ||= Thor::Base.shell.new
408
- dispatch(nil, given_args.dup, nil, config)
409
- rescue Thor::Error => e
410
- ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
411
- exit(1) if exit_on_failure?
412
- end
413
-
414
- # Allows to use private methods from parent in child classes as tasks.
415
- #
416
- # ==== Parameters
417
- # names<Array>:: Method names to be used as tasks
418
- #
419
- # ==== Examples
420
- #
421
- # public_task :foo
422
- # public_task :foo, :bar, :baz
423
- #
424
- def public_task(*names)
425
- names.each do |name|
426
- class_eval "def #{name}(*); super end"
427
- end
428
- end
429
-
430
- def handle_no_task_error(task, has_namespace = $thor_runner) #:nodoc:
431
- if has_namespace
432
- raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace."
433
- else
434
- raise UndefinedTaskError, "Could not find task #{task.inspect}."
435
- end
436
- end
437
-
438
- def handle_argument_error(task, error, arity=nil) #:nodoc:
439
- msg = "#{basename} #{task.name}"
440
- if arity
441
- required = arity < 0 ? (-1 - arity) : arity
442
- msg << " requires at least #{required} argument"
443
- msg << "s" if required > 1
444
- else
445
- msg = "call #{msg} as"
446
- end
447
-
448
- msg << ": #{self.banner(task).inspect}."
449
- raise InvocationError, msg
450
- end
451
-
452
- protected
453
-
454
- # Prints the class options per group. If an option does not belong to
455
- # any group, it's printed as Class option.
456
- #
457
- def class_options_help(shell, groups={}) #:nodoc:
458
- # Group options by group
459
- class_options.each do |_, value|
460
- groups[value.group] ||= []
461
- groups[value.group] << value
462
- end
463
-
464
- # Deal with default group
465
- global_options = groups.delete(nil) || []
466
- print_options(shell, global_options)
467
-
468
- # Print all others
469
- groups.each do |group_name, options|
470
- print_options(shell, options, group_name)
471
- end
472
- end
473
-
474
- # Receives a set of options and print them.
475
- def print_options(shell, options, group_name=nil)
476
- return if options.empty?
477
-
478
- list = []
479
- padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
480
-
481
- options.each do |option|
482
- unless option.hide
483
- item = [ option.usage(padding) ]
484
- item.push(option.description ? "# #{option.description}" : "")
485
-
486
- list << item
487
- list << [ "", "# Default: #{option.default}" ] if option.show_default?
488
- end
489
- end
490
-
491
- shell.say(group_name ? "#{group_name} options:" : "Options:")
492
- shell.print_table(list, :indent => 2)
493
- shell.say ""
494
- end
495
-
496
- # Raises an error if the word given is a Thor reserved word.
497
- def is_thor_reserved_word?(word, type) #:nodoc:
498
- return false unless THOR_RESERVED_WORDS.include?(word.to_s)
499
- raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
500
- end
501
-
502
- # Build an option and adds it to the given scope.
503
- #
504
- # ==== Parameters
505
- # name<Symbol>:: The name of the argument.
506
- # options<Hash>:: Described in both class_option and method_option.
507
- def build_option(name, options, scope) #:nodoc:
508
- scope[name] = Thor::Option.new(name, options[:desc], options[:required],
509
- options[:type], options[:default], options[:banner],
510
- options[:lazy_default], options[:group], options[:aliases], options[:hide])
511
- end
512
-
513
- # Receives a hash of options, parse them and add to the scope. This is a
514
- # fast way to set a bunch of options:
515
- #
516
- # build_options :foo => true, :bar => :required, :baz => :string
517
- #
518
- # ==== Parameters
519
- # Hash[Symbol => Object]
520
- def build_options(options, scope) #:nodoc:
521
- options.each do |key, value|
522
- scope[key] = Thor::Option.parse(key, value)
523
- end
524
- end
525
-
526
- # Finds a task with the given name. If the task belongs to the current
527
- # class, just return it, otherwise dup it and add the fresh copy to the
528
- # current task hash.
529
- def find_and_refresh_task(name) #:nodoc:
530
- task = if task = tasks[name.to_s]
531
- task
532
- elsif task = all_tasks[name.to_s]
533
- tasks[name.to_s] = task.clone
534
- else
535
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found."
536
- end
537
- end
538
-
539
- # Everytime someone inherits from a Thor class, register the klass
540
- # and file into baseclass.
541
- def inherited(klass)
542
- Thor::Base.register_klass_file(klass)
543
- klass.instance_variable_set(:@no_tasks, false)
544
- end
545
-
546
- # Fire this callback whenever a method is added. Added methods are
547
- # tracked as tasks by invoking the create_task method.
548
- def method_added(meth)
549
- meth = meth.to_s
550
-
551
- if meth == "initialize"
552
- initialize_added
553
- return
554
- end
555
-
556
- # Return if it's not a public instance method
557
- return unless public_instance_methods.include?(meth) ||
558
- public_instance_methods.include?(meth.to_sym)
559
-
560
- return if @no_tasks || !create_task(meth)
561
-
562
- is_thor_reserved_word?(meth, :task)
563
- Thor::Base.register_klass_file(self)
564
- end
565
-
566
- # Retrieves a value from superclass. If it reaches the baseclass,
567
- # returns default.
568
- def from_superclass(method, default=nil)
569
- if self == baseclass || !superclass.respond_to?(method, true)
570
- default
571
- else
572
- value = superclass.send(method)
573
- value.dup if value
574
- end
575
- end
576
-
577
- # A flag that makes the process exit with status 1 if any error happens.
578
- def exit_on_failure?
579
- false
580
- end
581
-
582
- #
583
- # The basename of the program invoking the thor class.
584
- #
585
- def basename
586
- File.basename($0).split(' ').first
587
- end
588
-
589
- # SIGNATURE: Sets the baseclass. This is where the superclass lookup
590
- # finishes.
591
- def baseclass #:nodoc:
592
- end
593
-
594
- # SIGNATURE: Creates a new task if valid_task? is true. This method is
595
- # called when a new method is added to the class.
596
- def create_task(meth) #:nodoc:
597
- end
598
-
599
- # SIGNATURE: Defines behavior when the initialize method is added to the
600
- # class.
601
- def initialize_added #:nodoc:
602
- end
603
-
604
- # SIGNATURE: The hook invoked by start.
605
- def dispatch(task, given_args, given_opts, config) #:nodoc:
606
- raise NotImplementedError
607
- end
608
-
609
- end
610
- end
611
- end