thor 0.16.0 → 0.17.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.rdoc +8 -0
- data/Gemfile +12 -8
- data/lib/thor.rb +79 -10
- data/lib/thor/actions.rb +13 -13
- data/lib/thor/actions/directory.rb +29 -10
- data/lib/thor/actions/file_manipulation.rb +8 -2
- data/lib/thor/base.rb +24 -11
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +5 -0
- data/lib/thor/group.rb +5 -5
- data/lib/thor/parser/options.rb +63 -25
- data/lib/thor/rake_compat.rb +3 -2
- data/lib/thor/runner.rb +1 -1
- data/lib/thor/shell/basic.rb +16 -16
- data/lib/thor/shell/color.rb +9 -9
- data/lib/thor/shell/html.rb +9 -9
- data/lib/thor/task.rb +2 -2
- data/lib/thor/version.rb +1 -1
- data/spec/actions/create_file_spec.rb +30 -30
- data/spec/actions/create_link_spec.rb +12 -12
- data/spec/actions/directory_spec.rb +34 -27
- data/spec/actions/empty_directory_spec.rb +16 -16
- data/spec/actions/file_manipulation_spec.rb +62 -50
- data/spec/actions/inject_into_file_spec.rb +18 -18
- data/spec/actions_spec.rb +56 -56
- data/spec/base_spec.rb +69 -69
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +19 -14
- data/spec/core_ext/ordered_hash_spec.rb +29 -29
- data/spec/exit_condition_spec.rb +3 -3
- data/spec/fixtures/preserve/script.sh +3 -0
- data/spec/fixtures/script.thor +5 -0
- data/spec/group_spec.rb +55 -55
- data/spec/invocation_spec.rb +26 -26
- data/spec/parser/argument_spec.rb +12 -12
- data/spec/parser/arguments_spec.rb +12 -12
- data/spec/parser/option_spec.rb +47 -47
- data/spec/parser/options_spec.rb +137 -72
- data/spec/rake_compat_spec.rb +11 -11
- data/spec/register_spec.rb +70 -8
- data/spec/runner_spec.rb +38 -38
- data/spec/shell/basic_spec.rb +49 -37
- data/spec/shell/color_spec.rb +13 -13
- data/spec/shell/html_spec.rb +3 -3
- data/spec/shell_spec.rb +7 -7
- data/spec/spec_helper.rb +4 -0
- data/spec/task_spec.rb +11 -11
- data/spec/thor_spec.rb +161 -91
- data/spec/util_spec.rb +42 -42
- data/thor.gemspec +1 -7
- metadata +8 -118
- data/lib/thor/core_ext/dir_escape.rb +0 -0
data/.rspec
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
== 0.17.0, release 2013-01-24
|
2
|
+
* Add better support for tasks that accept arbitrary additional arguments (e.g. things like `bundle exec`)
|
3
|
+
* Add #stop_on_unknown_option!
|
4
|
+
* Only strip from stdin.gets if it wasn't ended with EOF
|
5
|
+
* Allow "send" as a task name
|
6
|
+
* Allow passing options as arguments after "--"
|
7
|
+
* Autoload Thor::Group
|
8
|
+
|
1
9
|
== 0.16.0, release 2012-08-14
|
2
10
|
* Add enum to string arguments
|
3
11
|
|
data/Gemfile
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
-
source
|
1
|
+
source :rubygems
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
platforms :mri_19 do
|
10
|
-
gem 'ruby-debug19'
|
11
|
-
end
|
5
|
+
gem 'rake', '~> 0.9'
|
6
|
+
gem 'rdoc', '~> 3.9'
|
12
7
|
|
13
8
|
group :development do
|
14
9
|
gem 'pry'
|
10
|
+
gem 'pry-debugger', :platforms => :mri_19
|
11
|
+
end
|
12
|
+
|
13
|
+
group :test do
|
14
|
+
gem 'childlabor'
|
15
|
+
gem 'fakeweb', '~> 1.3'
|
16
|
+
gem 'rspec', '~> 2.11'
|
17
|
+
gem 'rspec-mocks', :git => 'git://github.com/rspec/rspec-mocks.git'
|
18
|
+
gem 'simplecov'
|
15
19
|
end
|
data/lib/thor.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'set'
|
1
2
|
require 'thor/base'
|
2
3
|
|
3
4
|
class Thor
|
@@ -8,13 +9,13 @@ class Thor
|
|
8
9
|
# meth<Symbol>:: name of the default task
|
9
10
|
#
|
10
11
|
def default_task(meth=nil)
|
11
|
-
case meth
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
@default_task = case meth
|
13
|
+
when :none
|
14
|
+
'help'
|
15
|
+
when nil
|
16
|
+
@default_task || from_superclass(:default_task, 'help')
|
17
|
+
else
|
18
|
+
meth.to_s
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
@@ -210,7 +211,7 @@ class Thor
|
|
210
211
|
|
211
212
|
define_method(subcommand) do |*args|
|
212
213
|
args, opts = Thor::Arguments.split(args)
|
213
|
-
invoke subcommand_class, args, opts
|
214
|
+
invoke subcommand_class, args, opts, :invoked_via_subcommand => true
|
214
215
|
end
|
215
216
|
end
|
216
217
|
|
@@ -251,15 +252,83 @@ class Thor
|
|
251
252
|
end
|
252
253
|
end
|
253
254
|
|
255
|
+
# Stop parsing of options as soon as an unknown option or a regular
|
256
|
+
# argument is encountered. All remaining arguments are passed to the task.
|
257
|
+
# This is useful if you have a task that can receive arbitrary additional
|
258
|
+
# options, and where those additional options should not be handled by
|
259
|
+
# Thor.
|
260
|
+
#
|
261
|
+
# ==== Example
|
262
|
+
#
|
263
|
+
# To better understand how this is useful, let's consider a task that calls
|
264
|
+
# an external command. A user may want to pass arbitrary options and
|
265
|
+
# arguments to that command. The task itself also accepts some options,
|
266
|
+
# which should be handled by Thor.
|
267
|
+
#
|
268
|
+
# class_option "verbose", :type => :boolean
|
269
|
+
# stop_on_unknown_option! :exec
|
270
|
+
# check_unknown_options! :except => :exec
|
271
|
+
#
|
272
|
+
# desc "exec", "Run a shell command"
|
273
|
+
# def exec(*args)
|
274
|
+
# puts "diagnostic output" if options[:verbose]
|
275
|
+
# Kernel.exec(*args)
|
276
|
+
# end
|
277
|
+
#
|
278
|
+
# Here +exec+ can be called with +--verbose+ to get diagnostic output,
|
279
|
+
# e.g.:
|
280
|
+
#
|
281
|
+
# $ thor exec --verbose echo foo
|
282
|
+
# diagnostic output
|
283
|
+
# foo
|
284
|
+
#
|
285
|
+
# But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
|
286
|
+
#
|
287
|
+
# $ thor exec echo --verbose foo
|
288
|
+
# --verbose foo
|
289
|
+
#
|
290
|
+
# ==== Parameters
|
291
|
+
# Symbol ...:: A list of tasks that should be affected.
|
292
|
+
def stop_on_unknown_option!(*task_names)
|
293
|
+
@stop_on_unknown_option ||= Set.new
|
294
|
+
@stop_on_unknown_option.merge(task_names)
|
295
|
+
end
|
296
|
+
|
297
|
+
def stop_on_unknown_option?(task) #:nodoc:
|
298
|
+
!!@stop_on_unknown_option && @stop_on_unknown_option.include?(task.name.to_sym)
|
299
|
+
end
|
300
|
+
|
254
301
|
protected
|
255
302
|
|
256
303
|
# The method responsible for dispatching given the args.
|
257
304
|
def dispatch(meth, given_args, given_opts, config) #:nodoc:
|
258
|
-
|
259
|
-
task
|
305
|
+
# There is an edge case when dispatching from a subcommand.
|
306
|
+
# A problem occurs invoking the default task. This case occurs
|
307
|
+
# when arguments are passed and a default task is defined, and
|
308
|
+
# the first given_args does not match the default task.
|
309
|
+
# Thor use "help" by default so we skip that case.
|
310
|
+
# Note the call to retrieve_task_name. It's called with
|
311
|
+
# given_args.dup since that method calls args.shift. Then lookup
|
312
|
+
# the task normally. If the first item in given_args is not
|
313
|
+
# a task then use the default task. The given_args will be
|
314
|
+
# intact later since dup was used.
|
315
|
+
if config[:invoked_via_subcommand] && given_args.size >= 1 && default_task != "help" && given_args.first != default_task
|
316
|
+
meth ||= retrieve_task_name(given_args.dup)
|
317
|
+
task = all_tasks[normalize_task_name(meth)]
|
318
|
+
task ||= all_tasks[normalize_task_name(default_task)]
|
319
|
+
else
|
320
|
+
meth ||= retrieve_task_name(given_args)
|
321
|
+
task = all_tasks[normalize_task_name(meth)]
|
322
|
+
end
|
260
323
|
|
261
324
|
if task
|
262
325
|
args, opts = Thor::Options.split(given_args)
|
326
|
+
if stop_on_unknown_option?(task) && !args.empty?
|
327
|
+
# given_args starts with a non-option, so we treat everything as
|
328
|
+
# ordinary arguments
|
329
|
+
args.concat opts
|
330
|
+
opts.clear
|
331
|
+
end
|
263
332
|
else
|
264
333
|
args, opts = given_args, nil
|
265
334
|
task = Thor::DynamicTask.new(meth)
|
data/lib/thor/actions.rb
CHANGED
@@ -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
|
@@ -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
|
|
@@ -38,6 +38,7 @@ class Thor
|
|
38
38
|
# destination<String>:: the relative path to the destination root.
|
39
39
|
# config<Hash>:: give :verbose => false to not log the status.
|
40
40
|
# If :recursive => false, does not look for paths recursively.
|
41
|
+
# If :mode => :preserve, preserve the file mode from the source.
|
41
42
|
#
|
42
43
|
# ==== Examples
|
43
44
|
#
|
@@ -73,26 +74,44 @@ class Thor
|
|
73
74
|
def execute!
|
74
75
|
lookup = Util.escape_globs(source)
|
75
76
|
lookup = config[:recursive] ? File.join(lookup, '**') : lookup
|
76
|
-
lookup =
|
77
|
+
lookup = file_level_lookup(lookup)
|
77
78
|
|
78
|
-
|
79
|
+
files(lookup).sort.each do |file_source|
|
79
80
|
next if File.directory?(file_source)
|
80
81
|
file_destination = File.join(given_destination, file_source.gsub(source, '.'))
|
81
82
|
file_destination.gsub!('/./', '/')
|
82
83
|
|
83
84
|
case file_source
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
85
|
+
when /\.empty_directory$/
|
86
|
+
dirname = File.dirname(file_destination).gsub(/\/\.$/, '')
|
87
|
+
next if dirname == given_destination
|
88
|
+
base.empty_directory(dirname, config)
|
89
|
+
when /\.tt$/
|
90
|
+
destination = base.template(file_source, file_destination[0..-4], config, &@block)
|
91
|
+
else
|
92
|
+
destination = base.copy_file(file_source, file_destination, config, &@block)
|
92
93
|
end
|
93
94
|
end
|
94
95
|
end
|
95
96
|
|
97
|
+
if RUBY_VERSION < '2.0'
|
98
|
+
def file_level_lookup(previous_lookup)
|
99
|
+
File.join(previous_lookup, '{*,.[a-z]*}')
|
100
|
+
end
|
101
|
+
|
102
|
+
def files(lookup)
|
103
|
+
Dir[lookup]
|
104
|
+
end
|
105
|
+
else
|
106
|
+
def file_level_lookup(previous_lookup)
|
107
|
+
File.join(previous_lookup, '*')
|
108
|
+
end
|
109
|
+
|
110
|
+
def files(lookup)
|
111
|
+
Dir.glob(lookup, File::FNM_DOTMATCH)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
96
115
|
end
|
97
116
|
end
|
98
117
|
end
|
@@ -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
|
@@ -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
|
data/lib/thor/base.rb
CHANGED
@@ -10,6 +10,7 @@ require 'thor/util'
|
|
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)
|
@@ -58,7 +59,8 @@ 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_task]
|
63
|
+
opts = Thor::Options.new(parse_options, hash_options, stop_on_unknown)
|
62
64
|
self.options = opts.parse(array_options)
|
63
65
|
|
64
66
|
# If unknown options are disallowed, make sure that none of the
|
@@ -74,7 +76,7 @@ class Thor
|
|
74
76
|
to_parse += opts.remaining unless self.class.strict_args_position?(config)
|
75
77
|
|
76
78
|
thor_args = Thor::Arguments.new(self.class.arguments)
|
77
|
-
thor_args.parse(to_parse).each { |k,v|
|
79
|
+
thor_args.parse(to_parse).each { |k,v| __send__("#{k}=", v) }
|
78
80
|
@args = thor_args.remaining
|
79
81
|
end
|
80
82
|
|
@@ -142,6 +144,13 @@ class Thor
|
|
142
144
|
!!check_unknown_options
|
143
145
|
end
|
144
146
|
|
147
|
+
# If true, option parsing is suspended as soon as an unknown option or a
|
148
|
+
# regular argument is encountered. All remaining arguments are passed to
|
149
|
+
# the task as regular arguments.
|
150
|
+
def stop_on_unknown_option?(task_name) #:nodoc:
|
151
|
+
false
|
152
|
+
end
|
153
|
+
|
145
154
|
# If you want only strict string args (useful when cascading thor classes),
|
146
155
|
# call strict_args_position! This is disabled by default to allow dynamic
|
147
156
|
# invocations.
|
@@ -304,11 +313,11 @@ class Thor
|
|
304
313
|
# name<String|Symbol>
|
305
314
|
#
|
306
315
|
def group(name=nil)
|
307
|
-
case name
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
316
|
+
@group = case name
|
317
|
+
when nil
|
318
|
+
@group || from_superclass(:group, 'standard')
|
319
|
+
else
|
320
|
+
name.to_s
|
312
321
|
end
|
313
322
|
end
|
314
323
|
|
@@ -404,9 +413,9 @@ class Thor
|
|
404
413
|
# thor :my_task
|
405
414
|
#
|
406
415
|
def namespace(name=nil)
|
407
|
-
case name
|
416
|
+
@namespace = case name
|
408
417
|
when nil
|
409
|
-
@namespace
|
418
|
+
@namespace || Thor::Util.namespace_from_thor_class(self)
|
410
419
|
else
|
411
420
|
@namespace = name.to_s
|
412
421
|
end
|
@@ -462,8 +471,12 @@ class Thor
|
|
462
471
|
msg = "#{basename} #{task.name}"
|
463
472
|
if arity
|
464
473
|
required = arity < 0 ? (-1 - arity) : arity
|
465
|
-
|
466
|
-
|
474
|
+
if required == 0
|
475
|
+
msg << " should have no arguments"
|
476
|
+
else
|
477
|
+
msg << " requires at least #{required} argument"
|
478
|
+
msg << "s" if required > 1
|
479
|
+
end
|
467
480
|
else
|
468
481
|
msg = "call #{msg} as"
|
469
482
|
end
|
data/lib/thor/group.rb
CHANGED
@@ -14,11 +14,11 @@ class Thor::Group
|
|
14
14
|
# description<String>:: The description for this Thor::Group.
|
15
15
|
#
|
16
16
|
def desc(description=nil)
|
17
|
-
case description
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
@desc = case description
|
18
|
+
when nil
|
19
|
+
@desc || from_superclass(:desc, nil)
|
20
|
+
else
|
21
|
+
description
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
data/lib/thor/parser/options.rb
CHANGED
@@ -5,27 +5,32 @@ class Thor
|
|
5
5
|
EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
|
6
6
|
SHORT_SQ_RE = /^-([a-z]{2,})$/i # Allow either -x -v or -xv style for single char args
|
7
7
|
SHORT_NUM = /^(-[a-z])#{NUMERIC}$/i
|
8
|
+
OPTS_END = '--'.freeze
|
8
9
|
|
9
10
|
# Receives a hash and makes it switches.
|
10
11
|
def self.to_switches(options)
|
11
12
|
options.map do |key, value|
|
12
13
|
case value
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
when true
|
15
|
+
"--#{key}"
|
16
|
+
when Array
|
17
|
+
"--#{key} #{value.map{ |v| v.inspect }.join(' ')}"
|
18
|
+
when Hash
|
19
|
+
"--#{key} #{value.map{ |k,v| "#{k}:#{v}" }.join(' ')}"
|
20
|
+
when nil, false
|
21
|
+
""
|
22
|
+
else
|
23
|
+
"--#{key} #{value.inspect}"
|
23
24
|
end
|
24
25
|
end.join(" ")
|
25
26
|
end
|
26
27
|
|
27
28
|
# Takes a hash of Thor::Option and a hash with defaults.
|
28
|
-
|
29
|
+
#
|
30
|
+
# If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
|
31
|
+
# an unknown option or a regular argument.
|
32
|
+
def initialize(hash_options={}, defaults={}, stop_on_unknown=false)
|
33
|
+
@stop_on_unknown = stop_on_unknown
|
29
34
|
options = hash_options.values
|
30
35
|
super(options)
|
31
36
|
|
@@ -50,15 +55,30 @@ class Thor
|
|
50
55
|
@extra
|
51
56
|
end
|
52
57
|
|
58
|
+
def peek
|
59
|
+
return super unless @parsing_options
|
60
|
+
|
61
|
+
result = super
|
62
|
+
if result == OPTS_END
|
63
|
+
shift
|
64
|
+
@parsing_options = false
|
65
|
+
super
|
66
|
+
else
|
67
|
+
result
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
53
71
|
def parse(args)
|
54
72
|
@pile = args.dup
|
73
|
+
@parsing_options = true
|
55
74
|
|
56
75
|
while peek
|
57
|
-
|
58
|
-
|
76
|
+
if parsing_options?
|
77
|
+
match, is_switch = current_is_switch?
|
78
|
+
shifted = shift
|
59
79
|
|
60
|
-
|
61
|
-
|
80
|
+
if is_switch
|
81
|
+
case shifted
|
62
82
|
when SHORT_SQ_RE
|
63
83
|
unshift($1.split('').map { |f| "-#{f}" })
|
64
84
|
next
|
@@ -67,16 +87,23 @@ class Thor
|
|
67
87
|
switch = $1
|
68
88
|
when LONG_RE, SHORT_RE
|
69
89
|
switch = $1
|
90
|
+
end
|
91
|
+
|
92
|
+
switch = normalize_switch(switch)
|
93
|
+
option = switch_option(switch)
|
94
|
+
@assigns[option.human_name] = parse_peek(switch, option)
|
95
|
+
elsif @stop_on_unknown
|
96
|
+
@extra << shifted
|
97
|
+
@extra << shift while peek
|
98
|
+
break
|
99
|
+
elsif match
|
100
|
+
@extra << shifted
|
101
|
+
@extra << shift while peek && peek !~ /^-/
|
102
|
+
else
|
103
|
+
@extra << shifted
|
70
104
|
end
|
71
|
-
|
72
|
-
switch = normalize_switch(switch)
|
73
|
-
option = switch_option(switch)
|
74
|
-
@assigns[option.human_name] = parse_peek(switch, option)
|
75
|
-
elsif match
|
76
|
-
@extra << shifted
|
77
|
-
@extra << shift while peek && peek !~ /^-/
|
78
105
|
else
|
79
|
-
@extra <<
|
106
|
+
@extra << shift
|
80
107
|
end
|
81
108
|
end
|
82
109
|
|
@@ -95,8 +122,10 @@ class Thor
|
|
95
122
|
|
96
123
|
protected
|
97
124
|
|
98
|
-
#
|
125
|
+
# Check if the current value in peek is a registered switch.
|
99
126
|
#
|
127
|
+
# Two booleans are returned. The first is true if the current value
|
128
|
+
# starts with a hyphen; the second is true if it is a registered switch.
|
100
129
|
def current_is_switch?
|
101
130
|
case peek
|
102
131
|
when LONG_RE, SHORT_RE, EQ_RE, SHORT_NUM
|
@@ -117,6 +146,10 @@ class Thor
|
|
117
146
|
end
|
118
147
|
end
|
119
148
|
|
149
|
+
def current_is_value?
|
150
|
+
peek && (!parsing_options? || super)
|
151
|
+
end
|
152
|
+
|
120
153
|
def switch?(arg)
|
121
154
|
switch_option(normalize_switch(arg))
|
122
155
|
end
|
@@ -135,6 +168,11 @@ class Thor
|
|
135
168
|
(@shorts[arg] || arg).tr('_', '-')
|
136
169
|
end
|
137
170
|
|
171
|
+
def parsing_options?
|
172
|
+
peek
|
173
|
+
@parsing_options
|
174
|
+
end
|
175
|
+
|
138
176
|
# Parse boolean values which can be given as --foo=true, --foo or --no-foo.
|
139
177
|
#
|
140
178
|
def parse_boolean(switch)
|
@@ -156,7 +194,7 @@ class Thor
|
|
156
194
|
# Parse the value at the peek analyzing if it requires an input or not.
|
157
195
|
#
|
158
196
|
def parse_peek(switch, option)
|
159
|
-
if current_is_switch_formatted? || last?
|
197
|
+
if parsing_options? && (current_is_switch_formatted? || last?)
|
160
198
|
if option.boolean?
|
161
199
|
# No problem for boolean types
|
162
200
|
elsif no_or_skip?(switch)
|