github_cli 0.5.0 → 0.5.1

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