github_cli 0.5.3 → 0.5.4

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 (94) hide show
  1. data/.travis.yml +14 -3
  2. data/CHANGELOG.md +15 -0
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +41 -44
  5. data/README.md +77 -14
  6. data/Rakefile +4 -2
  7. data/features/assignee.feature +1 -0
  8. data/features/blob.feature +1 -0
  9. data/features/collaborator.feature +1 -0
  10. data/features/commit.feature +2 -1
  11. data/features/config.feature +27 -28
  12. data/features/event.feature +1 -0
  13. data/features/init.feature +20 -23
  14. data/features/key.feature +5 -5
  15. data/features/milestone.feature +3 -2
  16. data/features/reference.feature +3 -2
  17. data/features/starring.feature +1 -0
  18. data/features/support/hooks.rb +1 -1
  19. data/features/tag.feature +2 -1
  20. data/features/tree.feature +17 -0
  21. data/features/watching.feature +1 -0
  22. data/fixtures/simple_config +3 -5
  23. data/github_cli.gemspec +1 -1
  24. data/lib/github_cli/api.rb +11 -6
  25. data/lib/github_cli/apis/event.rb +8 -8
  26. data/lib/github_cli/apis/label.rb +0 -12
  27. data/lib/github_cli/apis/starring.rb +5 -5
  28. data/lib/github_cli/apis/watching.rb +5 -5
  29. data/lib/github_cli/cli.rb +21 -30
  30. data/lib/github_cli/command.rb +1 -1
  31. data/lib/github_cli/commands/authorizations.rb +28 -2
  32. data/lib/github_cli/commands/collaborators.rb +12 -12
  33. data/lib/github_cli/commands/commits.rb +18 -2
  34. data/lib/github_cli/commands/events.rb +6 -8
  35. data/lib/github_cli/commands/followers.rb +1 -1
  36. data/lib/github_cli/commands/labels.rb +22 -20
  37. data/lib/github_cli/commands/milestones.rb +43 -13
  38. data/lib/github_cli/commands/references.rb +21 -6
  39. data/lib/github_cli/commands/starring.rb +3 -2
  40. data/lib/github_cli/commands/tags.rb +16 -1
  41. data/lib/github_cli/commands/trees.rb +11 -5
  42. data/lib/github_cli/commands/watching.rb +3 -2
  43. data/lib/github_cli/config.rb +15 -6
  44. data/lib/github_cli/dsl.rb +2 -2
  45. data/lib/github_cli/formatter.rb +2 -3
  46. data/lib/github_cli/formatters/csv.rb +29 -14
  47. data/lib/github_cli/formatters/table.rb +2 -3
  48. data/lib/github_cli/man/gcli-config.1 +17 -13
  49. data/lib/github_cli/man/gcli-config.1.txt +23 -21
  50. data/lib/github_cli/vendor/thor/actions/create_link.rb +3 -0
  51. data/lib/github_cli/vendor/thor/actions/directory.rb +29 -10
  52. data/lib/github_cli/vendor/thor/actions/file_manipulation.rb +9 -3
  53. data/lib/github_cli/vendor/thor/actions.rb +18 -18
  54. data/lib/github_cli/vendor/thor/base.rb +97 -89
  55. data/lib/github_cli/vendor/thor/{task.rb → command.rb} +16 -12
  56. data/lib/github_cli/vendor/thor/core_ext/hash_with_indifferent_access.rb +5 -0
  57. data/lib/github_cli/vendor/thor/core_ext/io_binary_read.rb +12 -0
  58. data/lib/github_cli/vendor/thor/error.rb +4 -7
  59. data/lib/github_cli/vendor/thor/group.rb +34 -32
  60. data/lib/github_cli/vendor/thor/invocation.rb +28 -26
  61. data/lib/github_cli/vendor/thor/parser/options.rb +66 -26
  62. data/lib/github_cli/vendor/thor/rake_compat.rb +3 -2
  63. data/lib/github_cli/vendor/thor/runner.rb +21 -20
  64. data/lib/github_cli/vendor/thor/shell/basic.rb +20 -16
  65. data/lib/github_cli/vendor/thor/shell/color.rb +13 -9
  66. data/lib/github_cli/vendor/thor/shell/html.rb +13 -9
  67. data/lib/github_cli/vendor/thor/util.rb +214 -210
  68. data/lib/github_cli/vendor/thor/version.rb +1 -1
  69. data/lib/github_cli/vendor/thor.rb +232 -153
  70. data/lib/github_cli/version.rb +1 -1
  71. data/man/gcli-config.1.ronn +14 -11
  72. data/spec/github_cli/commands/assignees_spec.rb +20 -0
  73. data/spec/github_cli/commands/blobs_spec.rb +21 -0
  74. data/spec/github_cli/commands/collaborators_spec.rb +31 -0
  75. data/spec/github_cli/commands/commits_spec.rb +26 -0
  76. data/spec/github_cli/commands/emails_spec.rb +24 -0
  77. data/spec/github_cli/commands/events_spec.rb +56 -0
  78. data/spec/github_cli/commands/followers_spec.rb +44 -0
  79. data/spec/github_cli/commands/keys_spec.rb +36 -0
  80. data/spec/github_cli/commands/labels_spec.rb +61 -0
  81. data/spec/github_cli/commands/milestones_spec.rb +47 -0
  82. data/spec/github_cli/commands/references_spec.rb +42 -0
  83. data/spec/github_cli/commands/starring_spec.rb +40 -0
  84. data/spec/github_cli/commands/tags_spec.rb +26 -0
  85. data/spec/github_cli/commands/trees_spec.rb +32 -0
  86. data/spec/github_cli/commands/watching_spec.rb +40 -0
  87. data/spec/github_cli/config_spec.rb +109 -116
  88. data/spec/github_cli/util/convert_value_spec.rb +19 -0
  89. data/spec/github_cli/util/convert_values_spec.rb +14 -0
  90. data/spec/github_cli/util_spec.rb +0 -29
  91. metadata +51 -19
  92. data/lib/github_cli/vendor/thor/core_ext/dir_escape.rb +0 -0
  93. data/lib/github_cli/vendor/thor/core_ext/file_binary_read.rb +0 -9
  94. data/lib/github_cli/vendor/thor/empty.txt +0 -0
@@ -10,7 +10,9 @@ class Thor
10
10
  # ==== Parameters
11
11
  # source<String>:: the relative path to the source root.
12
12
  # destination<String>:: the relative path to the destination root.
13
- # config<Hash>:: give :verbose => false to not log the status.
13
+ # config<Hash>:: give :verbose => false to not log the status, and
14
+ # :mode => :preserve, to preserve the file mode from the source.
15
+
14
16
  #
15
17
  # ==== Examples
16
18
  #
@@ -28,6 +30,10 @@ class Thor
28
30
  content = block.call(content) if block
29
31
  content
30
32
  end
33
+ if config[:mode] == :preserve
34
+ mode = File.stat(source).mode
35
+ chmod(destination, mode, config)
36
+ end
31
37
  end
32
38
 
33
39
  # Links the file from the relative source to the relative destination. If
@@ -123,7 +129,7 @@ class Thor
123
129
  #
124
130
  # ==== Example
125
131
  #
126
- # chmod "script/*", 0755
132
+ # chmod "script/server", 0755
127
133
  #
128
134
  def chmod(path, mode, config={})
129
135
  return unless behavior == :invoke
@@ -245,7 +251,7 @@ class Thor
245
251
  def uncomment_lines(path, flag, *args)
246
252
  flag = flag.respond_to?(:source) ? flag.source : flag
247
253
 
248
- gsub_file(path, /^(\s*)#\s*(.*#{flag})/, '\1\2', *args)
254
+ gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
249
255
  end
250
256
 
251
257
  # Comment all lines matching a given regex. It will leave the space
@@ -1,6 +1,6 @@
1
1
  require 'fileutils'
2
2
  require 'uri'
3
- require 'thor/core_ext/file_binary_read'
3
+ require 'thor/core_ext/io_binary_read'
4
4
  require 'thor/actions/create_file'
5
5
  require 'thor/actions/create_link'
6
6
  require 'thor/actions/directory'
@@ -73,13 +73,13 @@ class Thor
73
73
  #
74
74
  def initialize(args=[], options={}, config={})
75
75
  self.behavior = case config[:behavior].to_s
76
- when "force", "skip"
77
- _cleanup_options_and_set(options, config[:behavior])
78
- :invoke
79
- when "revoke"
80
- :revoke
81
- else
82
- :invoke
76
+ when "force", "skip"
77
+ _cleanup_options_and_set(options, config[:behavior])
78
+ :invoke
79
+ when "revoke"
80
+ :revoke
81
+ else
82
+ :invoke
83
83
  end
84
84
 
85
85
  super
@@ -268,8 +268,8 @@ class Thor
268
268
  # switches.
269
269
  #
270
270
  # ==== Parameters
271
- # task<String>:: the task to be invoked
272
- # args<Array>:: arguments to the task
271
+ # command<String>:: the command to be invoked
272
+ # args<Array>:: arguments to the command
273
273
  # config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output.
274
274
  # Other options are given as parameter to Thor.
275
275
  #
@@ -282,13 +282,13 @@ class Thor
282
282
  # thor :list, :all => true, :substring => 'rails'
283
283
  # #=> thor list --all --substring=rails
284
284
  #
285
- def thor(task, *args)
285
+ def thor(command, *args)
286
286
  config = args.last.is_a?(Hash) ? args.pop : {}
287
287
  verbose = config.key?(:verbose) ? config.delete(:verbose) : true
288
288
  pretend = config.key?(:pretend) ? config.delete(:pretend) : false
289
289
  capture = config.key?(:capture) ? config.delete(:capture) : false
290
290
 
291
- args.unshift task
291
+ args.unshift(command)
292
292
  args.push Thor::Options.to_switches(config)
293
293
  command = args.join(' ').strip
294
294
 
@@ -305,12 +305,12 @@ class Thor
305
305
 
306
306
  def _cleanup_options_and_set(options, key) #:nodoc:
307
307
  case options
308
- when Array
309
- %w(--force -f --skip -s).each { |i| options.delete(i) }
310
- options << "--#{key}"
311
- when Hash
312
- [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
313
- options.merge!(key => true)
308
+ when Array
309
+ %w(--force -f --skip -s).each { |i| options.delete(i) }
310
+ options << "--#{key}"
311
+ when Hash
312
+ [:force, :skip, "force", "skip"].each { |i| options.delete(i) }
313
+ options.merge!(key => true)
314
314
  end
315
315
  end
316
316
 
@@ -1,15 +1,16 @@
1
+ require 'thor/command'
1
2
  require 'thor/core_ext/hash_with_indifferent_access'
2
3
  require 'thor/core_ext/ordered_hash'
3
4
  require 'thor/error'
4
- require 'thor/shell'
5
5
  require 'thor/invocation'
6
6
  require 'thor/parser'
7
- require 'thor/task'
7
+ require 'thor/shell'
8
8
  require 'thor/util'
9
9
 
10
10
  class Thor
11
11
  autoload :Actions, 'thor/actions'
12
12
  autoload :RakeCompat, 'thor/rake_compat'
13
+ autoload :Group, 'thor/group'
13
14
 
14
15
  # Shortcuts for help.
15
16
  HELP_MAPPINGS = %w(-h -? --help -D)
@@ -46,8 +47,8 @@ class Thor
46
47
  # first two parameters.
47
48
 
48
49
  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
50
+ command_options = config.delete(:command_options) # hook for start
51
+ parse_options = parse_options.merge(command_options) if command_options
51
52
  array_options, hash_options = options, {}
52
53
  else
53
54
  # Handle the case where the class was explicitly instantiated
@@ -58,8 +59,10 @@ class Thor
58
59
  # Let Thor::Options parse the options first, so it can remove
59
60
  # declared options from the array. This will leave us with
60
61
  # a list of arguments that weren't declared.
61
- opts = Thor::Options.new(parse_options, hash_options)
62
+ stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
63
+ opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
62
64
  self.options = opts.parse(array_options)
65
+ self.options = config[:class_options].merge(self.options) if config[:class_options]
63
66
 
64
67
  # If unknown options are disallowed, make sure that none of the
65
68
  # remaining arguments looks like an option.
@@ -116,18 +119,6 @@ class Thor
116
119
  end
117
120
 
118
121
  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
122
  # If you want to raise an error for unknown options, call check_unknown_options!
132
123
  # This is disabled by default to allow dynamic invocations.
133
124
  def check_unknown_options!
@@ -142,6 +133,13 @@ class Thor
142
133
  !!check_unknown_options
143
134
  end
144
135
 
136
+ # If true, option parsing is suspended as soon as an unknown option or a
137
+ # regular argument is encountered. All remaining arguments are passed to
138
+ # the command as regular arguments.
139
+ def stop_on_unknown_option?(command_name) #:nodoc:
140
+ false
141
+ end
142
+
145
143
  # If you want only strict string args (useful when cascading thor classes),
146
144
  # call strict_args_position! This is disabled by default to allow dynamic
147
145
  # invocations.
@@ -163,11 +161,11 @@ class Thor
163
161
  # is how they are parsed from the command line, arguments are retrieved
164
162
  # from position:
165
163
  #
166
- # thor task NAME
164
+ # thor command NAME
167
165
  #
168
166
  # Instead of:
169
167
  #
170
- # thor task --name=NAME
168
+ # thor command --name=NAME
171
169
  #
172
170
  # Besides, arguments are used inside your code as an accessor (self.argument),
173
171
  # while options are all kept in a hash (self.options).
@@ -194,7 +192,7 @@ class Thor
194
192
  #
195
193
  def argument(name, options={})
196
194
  is_thor_reserved_word?(name, :argument)
197
- no_tasks { attr_accessor name }
195
+ no_commands { attr_accessor name }
198
196
 
199
197
  required = if options.key?(:optional)
200
198
  !options[:optional]
@@ -298,88 +296,92 @@ class Thor
298
296
  end
299
297
 
300
298
  # 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.
299
+ # that only commands from a pre-defined group will be shown. Defaults to standard.
302
300
  #
303
301
  # ==== Parameters
304
302
  # name<String|Symbol>
305
303
  #
306
304
  def group(name=nil)
307
- case name
308
- when nil
309
- @group ||= from_superclass(:group, 'standard')
310
- else
311
- @group = name.to_s
305
+ @group = case name
306
+ when nil
307
+ @group || from_superclass(:group, 'standard')
308
+ else
309
+ name.to_s
312
310
  end
313
311
  end
314
312
 
315
- # Returns the tasks for this Thor class.
313
+ # Returns the commands for this Thor class.
316
314
  #
317
315
  # ==== Returns
318
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
316
+ # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
319
317
  # objects as values.
320
318
  #
321
- def tasks
322
- @tasks ||= Thor::CoreExt::OrderedHash.new
319
+ def commands
320
+ @commands ||= Thor::CoreExt::OrderedHash.new
323
321
  end
322
+ alias tasks commands
324
323
 
325
- # Returns the tasks for this Thor class and all subclasses.
324
+ # Returns the commands for this Thor class and all subclasses.
326
325
  #
327
326
  # ==== Returns
328
- # OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
327
+ # OrderedHash:: An ordered hash with commands names as keys and Thor::Command
329
328
  # objects as values.
330
329
  #
331
- def all_tasks
332
- @all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new)
333
- @all_tasks.merge(tasks)
330
+ def all_commands
331
+ @all_commands ||= from_superclass(:all_commands, Thor::CoreExt::OrderedHash.new)
332
+ @all_commands.merge(commands)
334
333
  end
334
+ alias all_tasks all_commands
335
335
 
336
- # Removes a given task from this Thor class. This is usually done if you
336
+ # Removes a given command from this Thor class. This is usually done if you
337
337
  # are inheriting from another class and don't want it to be available
338
338
  # anymore.
339
339
  #
340
- # By default it only remove the mapping to the task. But you can supply
340
+ # By default it only remove the mapping to the command. But you can supply
341
341
  # :undefine => true to undefine the method from the class as well.
342
342
  #
343
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
344
+ # name<Symbol|String>:: The name of the command to be removed
345
+ # options<Hash>:: You can give :undefine => true if you want commands the method
346
346
  # to be undefined from the class as well.
347
347
  #
348
- def remove_task(*names)
348
+ def remove_command(*names)
349
349
  options = names.last.is_a?(Hash) ? names.pop : {}
350
350
 
351
351
  names.each do |name|
352
- tasks.delete(name.to_s)
353
- all_tasks.delete(name.to_s)
352
+ commands.delete(name.to_s)
353
+ all_commands.delete(name.to_s)
354
354
  undef_method name if options[:undefine]
355
355
  end
356
356
  end
357
+ alias remove_task remove_command
357
358
 
358
- # All methods defined inside the given block are not added as tasks.
359
+ # All methods defined inside the given block are not added as commands.
359
360
  #
360
361
  # So you can do:
361
362
  #
362
363
  # class MyScript < Thor
363
- # no_tasks do
364
- # def this_is_not_a_task
364
+ # no_commands do
365
+ # def this_is_not_a_command
365
366
  # end
366
367
  # end
367
368
  # end
368
369
  #
369
- # You can also add the method and remove it from the task list:
370
+ # You can also add the method and remove it from the command list:
370
371
  #
371
372
  # class MyScript < Thor
372
- # def this_is_not_a_task
373
+ # def this_is_not_a_command
373
374
  # end
374
- # remove_task :this_is_not_a_task
375
+ # remove_command :this_is_not_a_command
375
376
  # end
376
377
  #
377
- def no_tasks
378
- @no_tasks = true
378
+ def no_commands
379
+ @no_commands = true
379
380
  yield
380
381
  ensure
381
- @no_tasks = false
382
+ @no_commands = false
382
383
  end
384
+ alias no_tasks no_commands
383
385
 
384
386
  # Sets the namespace for the Thor or Thor::Group class. By default the
385
387
  # namespace is retrieved from the class name. If your Thor class is named
@@ -391,7 +393,7 @@ class Thor
391
393
  #
392
394
  # namespace :my_scripts
393
395
  #
394
- # You change how your tasks are invoked:
396
+ # You change how your commands are invoked:
395
397
  #
396
398
  # thor my_scripts -h
397
399
  #
@@ -399,26 +401,26 @@ class Thor
399
401
  #
400
402
  # namespace :default
401
403
  #
402
- # Your tasks can be invoked with a shortcut. Instead of:
404
+ # Your commands can be invoked with a shortcut. Instead of:
403
405
  #
404
- # thor :my_task
406
+ # thor :my_command
405
407
  #
406
408
  def namespace(name=nil)
407
- case name
409
+ @namespace = case name
408
410
  when nil
409
- @namespace ||= Thor::Util.namespace_from_thor_class(self)
411
+ @namespace || Thor::Util.namespace_from_thor_class(self)
410
412
  else
411
413
  @namespace = name.to_s
412
414
  end
413
415
  end
414
416
 
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
+ # Parses the command and options from the given args, instantiate the class
418
+ # and invoke the command. This method is used when the arguments must be parsed
417
419
  # from an array. If you are inside Ruby and want to use a Thor class, you
418
420
  # can simply initialize it:
419
421
  #
420
422
  # script = MyScript.new(args, options, config)
421
- # script.invoke(:task, first_arg, second_arg, third_arg)
423
+ # script.invoke(:command, first_arg, second_arg, third_arg)
422
424
  #
423
425
  def start(given_args=ARGV, config={})
424
426
  config[:shell] ||= Thor::Base.shell.new
@@ -427,40 +429,42 @@ class Thor
427
429
  ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
428
430
  exit(1) if exit_on_failure?
429
431
  rescue Errno::EPIPE
430
- # This happens if a thor task is piped to something like `head`,
432
+ # This happens if a thor command is piped to something like `head`,
431
433
  # which closes the pipe when it's done reading. This will also
432
434
  # mean that if the pipe is closed, further unnecessary
433
435
  # computation will not occur.
434
436
  exit(0)
435
437
  end
436
438
 
437
- # Allows to use private methods from parent in child classes as tasks.
439
+ # Allows to use private methods from parent in child classes as commands.
438
440
  #
439
441
  # ==== Parameters
440
- # names<Array>:: Method names to be used as tasks
442
+ # names<Array>:: Method names to be used as commands
441
443
  #
442
444
  # ==== Examples
443
445
  #
444
- # public_task :foo
445
- # public_task :foo, :bar, :baz
446
+ # public_command :foo
447
+ # public_command :foo, :bar, :baz
446
448
  #
447
- def public_task(*names)
449
+ def public_command(*names)
448
450
  names.each do |name|
449
451
  class_eval "def #{name}(*); super end"
450
452
  end
451
453
  end
454
+ alias public_task public_command
452
455
 
453
- def handle_no_task_error(task, has_namespace = $thor_runner) #:nodoc:
456
+ def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
454
457
  if has_namespace
455
- raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace."
458
+ raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
456
459
  else
457
- raise UndefinedTaskError, "Could not find task #{task.inspect}."
460
+ raise UndefinedCommandError, "Could not find command #{command.inspect}."
458
461
  end
459
462
  end
463
+ alias handle_no_task_error handle_no_command_error
460
464
 
461
- def handle_argument_error(task, error, arity=nil) #:nodoc:
462
- msg = "#{basename} #{task.name}"
463
- if arity
465
+ def handle_argument_error(command, error, arity=nil) #:nodoc:
466
+ msg = "#{basename} #{command.name}"
467
+ if arity && arity != 0
464
468
  required = arity < 0 ? (-1 - arity) : arity
465
469
  msg << " requires at least #{required} argument"
466
470
  msg << "s" if required > 1
@@ -468,7 +472,7 @@ class Thor
468
472
  msg = "call #{msg} as"
469
473
  end
470
474
 
471
- msg << ": #{self.banner(task).inspect}."
475
+ msg << ": #{self.banner(command).inspect}."
472
476
  raise InvocationError, msg
473
477
  end
474
478
 
@@ -546,28 +550,29 @@ class Thor
546
550
  end
547
551
  end
548
552
 
549
- # Finds a task with the given name. If the task belongs to the current
553
+ # Finds a command with the given name. If the command belongs to the current
550
554
  # 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
555
+ # current command hash.
556
+ def find_and_refresh_command(name) #:nodoc:
557
+ command = if command = commands[name.to_s]
558
+ command
559
+ elsif command = all_commands[name.to_s]
560
+ commands[name.to_s] = command.clone
557
561
  else
558
- raise ArgumentError, "You supplied :for => #{name.inspect}, but the task #{name.inspect} could not be found."
562
+ raise ArgumentError, "You supplied :for => #{name.inspect}, but the command #{name.inspect} could not be found."
559
563
  end
560
564
  end
565
+ alias find_and_refresh_task find_and_refresh_command
561
566
 
562
567
  # Everytime someone inherits from a Thor class, register the klass
563
568
  # and file into baseclass.
564
569
  def inherited(klass)
565
570
  Thor::Base.register_klass_file(klass)
566
- klass.instance_variable_set(:@no_tasks, false)
571
+ klass.instance_variable_set(:@no_commands, false)
567
572
  end
568
573
 
569
574
  # Fire this callback whenever a method is added. Added methods are
570
- # tracked as tasks by invoking the create_task method.
575
+ # tracked as commands by invoking the create_command method.
571
576
  def method_added(meth)
572
577
  meth = meth.to_s
573
578
 
@@ -577,12 +582,14 @@ class Thor
577
582
  end
578
583
 
579
584
  # 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)
585
+ return unless public_method_defined?(meth.to_sym)
586
+
587
+ # Return if attr_* added the method
588
+ return if caller.first.to_s[/`attr_(reader|writer|accessor)'/]
582
589
 
583
- return if @no_tasks || !create_task(meth)
590
+ return if @no_commands || !create_command(meth)
584
591
 
585
- is_thor_reserved_word?(meth, :task)
592
+ is_thor_reserved_word?(meth, :command)
586
593
  Thor::Base.register_klass_file(self)
587
594
  end
588
595
 
@@ -621,10 +628,11 @@ class Thor
621
628
  def baseclass #:nodoc:
622
629
  end
623
630
 
624
- # SIGNATURE: Creates a new task if valid_task? is true. This method is
631
+ # SIGNATURE: Creates a new command if valid_command? is true. This method is
625
632
  # called when a new method is added to the class.
626
- def create_task(meth) #:nodoc:
633
+ def create_command(meth) #:nodoc:
627
634
  end
635
+ alias create_task create_command
628
636
 
629
637
  # SIGNATURE: Defines behavior when the initialize method is added to the
630
638
  # class.
@@ -632,7 +640,7 @@ class Thor
632
640
  end
633
641
 
634
642
  # SIGNATURE: The hook invoked by start.
635
- def dispatch(task, given_args, given_opts, config) #:nodoc:
643
+ def dispatch(command, given_args, given_opts, config) #:nodoc:
636
644
  raise NotImplementedError
637
645
  end
638
646
 
@@ -1,5 +1,5 @@
1
1
  class Thor
2
- class Task < Struct.new(:name, :description, :long_description, :usage, :options)
2
+ class Command < Struct.new(:name, :description, :long_description, :usage, :options)
3
3
  FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
4
4
 
5
5
  def initialize(name, description, long_description, usage, options=nil)
@@ -15,27 +15,27 @@ class Thor
15
15
  false
16
16
  end
17
17
 
18
- # By default, a task invokes a method in the thor class. You can change this
19
- # implementation to create custom tasks.
18
+ # By default, a command invokes a method in the thor class. You can change this
19
+ # implementation to create custom commands.
20
20
  def run(instance, args=[])
21
21
  arity = nil
22
22
 
23
23
  if private_method?(instance)
24
- instance.class.handle_no_task_error(name)
24
+ instance.class.handle_no_command_error(name)
25
25
  elsif public_method?(instance)
26
26
  arity = instance.method(name).arity
27
27
  instance.__send__(name, *args)
28
28
  elsif local_method?(instance, :method_missing)
29
29
  instance.__send__(:method_missing, name.to_sym, *args)
30
30
  else
31
- instance.class.handle_no_task_error(name)
31
+ instance.class.handle_no_command_error(name)
32
32
  end
33
33
  rescue ArgumentError => e
34
34
  handle_argument_error?(instance, e, caller) ?
35
35
  instance.class.handle_argument_error(self, e, arity) : (raise e)
36
36
  rescue NoMethodError => e
37
37
  handle_no_method_error?(instance, e, caller) ?
38
- instance.class.handle_no_task_error(name) : (raise e)
38
+ instance.class.handle_no_command_error(name) : (raise e)
39
39
  end
40
40
 
41
41
  # Returns the formatted usage by injecting given required arguments
@@ -107,26 +107,30 @@ class Thor
107
107
  error.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/
108
108
  end
109
109
  end
110
+ Task = Command
110
111
 
111
- # A task that is hidden in help messages but still invocable.
112
- class HiddenTask < Task
112
+ # A command that is hidden in help messages but still invocable.
113
+ class HiddenCommand < Command
113
114
  def hidden?
114
115
  true
115
116
  end
116
117
  end
118
+ HiddenTask = HiddenCommand
117
119
 
118
- # A dynamic task that handles method missing scenarios.
119
- class DynamicTask < Task
120
+ # A dynamic command that handles method missing scenarios.
121
+ class DynamicCommand < Command
120
122
  def initialize(name, options=nil)
121
- super(name.to_s, "A dynamically-generated task", name.to_s, name.to_s, options)
123
+ super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options)
122
124
  end
123
125
 
124
126
  def run(instance, args=[])
125
127
  if (instance.methods & [name.to_s, name.to_sym]).empty?
126
128
  super
127
129
  else
128
- instance.class.handle_no_task_error(name)
130
+ instance.class.handle_no_command_error(name)
129
131
  end
130
132
  end
131
133
  end
134
+ DynamicTask = DynamicCommand
135
+
132
136
  end
@@ -45,6 +45,11 @@ class Thor
45
45
  self
46
46
  end
47
47
 
48
+ # Convert to a Hash with String keys.
49
+ def to_hash
50
+ Hash.new(default).merge!(self)
51
+ end
52
+
48
53
  protected
49
54
 
50
55
  def convert_key(key)
@@ -0,0 +1,12 @@
1
+ class IO #:nodoc:
2
+ class << self
3
+
4
+ def binread(file, *args)
5
+ raise ArgumentError, "wrong number of arguments (#{1 + args.size} for 1..3)" unless args.size < 3
6
+ File.open(file, 'rb') do |f|
7
+ f.read(*args)
8
+ end
9
+ end unless method_defined? :binread
10
+
11
+ end
12
+ end
@@ -5,17 +5,15 @@ class Thor
5
5
  # Errors that are caused by the developer, like declaring a method which
6
6
  # overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we
7
7
  # ensure that developer errors are shown with full backtrace.
8
- #
9
8
  class Error < StandardError
10
9
  end
11
10
 
12
- # Raised when a task was not found.
13
- #
14
- class UndefinedTaskError < Error
11
+ # Raised when a command was not found.
12
+ class UndefinedCommandError < Error
15
13
  end
14
+ UndefinedTaskError = UndefinedCommandError
16
15
 
17
- # Raised when a task was found, but not invoked properly.
18
- #
16
+ # Raised when a command was found, but not invoked properly.
19
17
  class InvocationError < Error
20
18
  end
21
19
 
@@ -29,7 +27,6 @@ class Thor
29
27
  end
30
28
 
31
29
  # Raised when a user tries to call a private method encoded in templated filename.
32
- #
33
30
  class PrivateMethodEncodedError < Error
34
31
  end
35
32
  end