github_cli 0.5.3 → 0.5.4

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