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.
- data/.travis.yml +14 -3
- data/CHANGELOG.md +15 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +41 -44
- data/README.md +77 -14
- data/Rakefile +4 -2
- data/features/assignee.feature +1 -0
- data/features/blob.feature +1 -0
- data/features/collaborator.feature +1 -0
- data/features/commit.feature +2 -1
- data/features/config.feature +27 -28
- data/features/event.feature +1 -0
- data/features/init.feature +20 -23
- data/features/key.feature +5 -5
- data/features/milestone.feature +3 -2
- data/features/reference.feature +3 -2
- data/features/starring.feature +1 -0
- data/features/support/hooks.rb +1 -1
- data/features/tag.feature +2 -1
- data/features/tree.feature +17 -0
- data/features/watching.feature +1 -0
- data/fixtures/simple_config +3 -5
- data/github_cli.gemspec +1 -1
- data/lib/github_cli/api.rb +11 -6
- data/lib/github_cli/apis/event.rb +8 -8
- data/lib/github_cli/apis/label.rb +0 -12
- data/lib/github_cli/apis/starring.rb +5 -5
- data/lib/github_cli/apis/watching.rb +5 -5
- data/lib/github_cli/cli.rb +21 -30
- data/lib/github_cli/command.rb +1 -1
- data/lib/github_cli/commands/authorizations.rb +28 -2
- data/lib/github_cli/commands/collaborators.rb +12 -12
- data/lib/github_cli/commands/commits.rb +18 -2
- data/lib/github_cli/commands/events.rb +6 -8
- data/lib/github_cli/commands/followers.rb +1 -1
- data/lib/github_cli/commands/labels.rb +22 -20
- data/lib/github_cli/commands/milestones.rb +43 -13
- data/lib/github_cli/commands/references.rb +21 -6
- data/lib/github_cli/commands/starring.rb +3 -2
- data/lib/github_cli/commands/tags.rb +16 -1
- data/lib/github_cli/commands/trees.rb +11 -5
- data/lib/github_cli/commands/watching.rb +3 -2
- data/lib/github_cli/config.rb +15 -6
- data/lib/github_cli/dsl.rb +2 -2
- data/lib/github_cli/formatter.rb +2 -3
- data/lib/github_cli/formatters/csv.rb +29 -14
- data/lib/github_cli/formatters/table.rb +2 -3
- data/lib/github_cli/man/gcli-config.1 +17 -13
- data/lib/github_cli/man/gcli-config.1.txt +23 -21
- data/lib/github_cli/vendor/thor/actions/create_link.rb +3 -0
- data/lib/github_cli/vendor/thor/actions/directory.rb +29 -10
- data/lib/github_cli/vendor/thor/actions/file_manipulation.rb +9 -3
- data/lib/github_cli/vendor/thor/actions.rb +18 -18
- data/lib/github_cli/vendor/thor/base.rb +97 -89
- data/lib/github_cli/vendor/thor/{task.rb → command.rb} +16 -12
- data/lib/github_cli/vendor/thor/core_ext/hash_with_indifferent_access.rb +5 -0
- data/lib/github_cli/vendor/thor/core_ext/io_binary_read.rb +12 -0
- data/lib/github_cli/vendor/thor/error.rb +4 -7
- data/lib/github_cli/vendor/thor/group.rb +34 -32
- data/lib/github_cli/vendor/thor/invocation.rb +28 -26
- data/lib/github_cli/vendor/thor/parser/options.rb +66 -26
- data/lib/github_cli/vendor/thor/rake_compat.rb +3 -2
- data/lib/github_cli/vendor/thor/runner.rb +21 -20
- data/lib/github_cli/vendor/thor/shell/basic.rb +20 -16
- data/lib/github_cli/vendor/thor/shell/color.rb +13 -9
- data/lib/github_cli/vendor/thor/shell/html.rb +13 -9
- data/lib/github_cli/vendor/thor/util.rb +214 -210
- data/lib/github_cli/vendor/thor/version.rb +1 -1
- data/lib/github_cli/vendor/thor.rb +232 -153
- data/lib/github_cli/version.rb +1 -1
- data/man/gcli-config.1.ronn +14 -11
- data/spec/github_cli/commands/assignees_spec.rb +20 -0
- data/spec/github_cli/commands/blobs_spec.rb +21 -0
- data/spec/github_cli/commands/collaborators_spec.rb +31 -0
- data/spec/github_cli/commands/commits_spec.rb +26 -0
- data/spec/github_cli/commands/emails_spec.rb +24 -0
- data/spec/github_cli/commands/events_spec.rb +56 -0
- data/spec/github_cli/commands/followers_spec.rb +44 -0
- data/spec/github_cli/commands/keys_spec.rb +36 -0
- data/spec/github_cli/commands/labels_spec.rb +61 -0
- data/spec/github_cli/commands/milestones_spec.rb +47 -0
- data/spec/github_cli/commands/references_spec.rb +42 -0
- data/spec/github_cli/commands/starring_spec.rb +40 -0
- data/spec/github_cli/commands/tags_spec.rb +26 -0
- data/spec/github_cli/commands/trees_spec.rb +32 -0
- data/spec/github_cli/commands/watching_spec.rb +40 -0
- data/spec/github_cli/config_spec.rb +109 -116
- data/spec/github_cli/util/convert_value_spec.rb +19 -0
- data/spec/github_cli/util/convert_values_spec.rb +14 -0
- data/spec/github_cli/util_spec.rb +0 -29
- metadata +51 -19
- data/lib/github_cli/vendor/thor/core_ext/dir_escape.rb +0 -0
- data/lib/github_cli/vendor/thor/core_ext/file_binary_read.rb +0 -9
- 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
|
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*)
|
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/
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
-
#
|
272
|
-
# args<Array>:: arguments to the
|
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(
|
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
|
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
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
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/
|
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
|
-
|
50
|
-
parse_options = parse_options.merge(
|
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
|
-
|
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
|
164
|
+
# thor command NAME
|
167
165
|
#
|
168
166
|
# Instead of:
|
169
167
|
#
|
170
|
-
# thor
|
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
|
-
|
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
|
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
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
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
|
313
|
+
# Returns the commands for this Thor class.
|
316
314
|
#
|
317
315
|
# ==== Returns
|
318
|
-
# OrderedHash:: An ordered hash with
|
316
|
+
# OrderedHash:: An ordered hash with commands names as keys and Thor::Command
|
319
317
|
# objects as values.
|
320
318
|
#
|
321
|
-
def
|
322
|
-
@
|
319
|
+
def commands
|
320
|
+
@commands ||= Thor::CoreExt::OrderedHash.new
|
323
321
|
end
|
322
|
+
alias tasks commands
|
324
323
|
|
325
|
-
# Returns the
|
324
|
+
# Returns the commands for this Thor class and all subclasses.
|
326
325
|
#
|
327
326
|
# ==== Returns
|
328
|
-
# OrderedHash:: An ordered hash with
|
327
|
+
# OrderedHash:: An ordered hash with commands names as keys and Thor::Command
|
329
328
|
# objects as values.
|
330
329
|
#
|
331
|
-
def
|
332
|
-
@
|
333
|
-
@
|
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
|
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
|
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
|
345
|
-
# options<Hash>:: You can give :undefine => true if you want
|
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
|
348
|
+
def remove_command(*names)
|
349
349
|
options = names.last.is_a?(Hash) ? names.pop : {}
|
350
350
|
|
351
351
|
names.each do |name|
|
352
|
-
|
353
|
-
|
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
|
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
|
-
#
|
364
|
-
# def
|
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
|
370
|
+
# You can also add the method and remove it from the command list:
|
370
371
|
#
|
371
372
|
# class MyScript < Thor
|
372
|
-
# def
|
373
|
+
# def this_is_not_a_command
|
373
374
|
# end
|
374
|
-
#
|
375
|
+
# remove_command :this_is_not_a_command
|
375
376
|
# end
|
376
377
|
#
|
377
|
-
def
|
378
|
-
@
|
378
|
+
def no_commands
|
379
|
+
@no_commands = true
|
379
380
|
yield
|
380
381
|
ensure
|
381
|
-
@
|
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
|
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
|
404
|
+
# Your commands can be invoked with a shortcut. Instead of:
|
403
405
|
#
|
404
|
-
# thor :
|
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
|
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
|
416
|
-
# and invoke the
|
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(:
|
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
|
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
|
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
|
442
|
+
# names<Array>:: Method names to be used as commands
|
441
443
|
#
|
442
444
|
# ==== Examples
|
443
445
|
#
|
444
|
-
#
|
445
|
-
#
|
446
|
+
# public_command :foo
|
447
|
+
# public_command :foo, :bar, :baz
|
446
448
|
#
|
447
|
-
def
|
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
|
456
|
+
def handle_no_command_error(command, has_namespace = $thor_runner) #:nodoc:
|
454
457
|
if has_namespace
|
455
|
-
raise
|
458
|
+
raise UndefinedCommandError, "Could not find command #{command.inspect} in #{namespace.inspect} namespace."
|
456
459
|
else
|
457
|
-
raise
|
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(
|
462
|
-
msg = "#{basename} #{
|
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(
|
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
|
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
|
552
|
-
def
|
553
|
-
|
554
|
-
|
555
|
-
elsif
|
556
|
-
|
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
|
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(:@
|
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
|
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
|
581
|
-
|
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 @
|
590
|
+
return if @no_commands || !create_command(meth)
|
584
591
|
|
585
|
-
is_thor_reserved_word?(meth, :
|
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
|
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
|
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(
|
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
|
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
|
19
|
-
# implementation to create custom
|
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.
|
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.
|
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.
|
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
|
112
|
-
class
|
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
|
119
|
-
class
|
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
|
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.
|
130
|
+
instance.class.handle_no_command_error(name)
|
129
131
|
end
|
130
132
|
end
|
131
133
|
end
|
134
|
+
DynamicTask = DynamicCommand
|
135
|
+
|
132
136
|
end
|
@@ -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
|
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
|
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
|