josevalim-thor 0.10.21 → 0.10.22
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/thor/actions.rb +6 -1
- data/lib/thor/base.rb +11 -29
- data/lib/thor/invocation.rb +3 -2
- data/lib/thor/parser/argument.rb +7 -6
- data/lib/thor/parser/arguments.rb +16 -11
- data/lib/thor/parser/option.rb +14 -5
- data/lib/thor/parser/options.rb +23 -28
- data/lib/thor/runner.rb +2 -2
- data/lib/thor.rb +2 -1
- metadata +2 -2
data/lib/thor/actions.rb
CHANGED
@@ -142,6 +142,7 @@ class Thor
|
|
142
142
|
# chmod "script/*", 0755
|
143
143
|
#
|
144
144
|
def chmod(path, mode, log_status=true)
|
145
|
+
return unless behavior == :invoke
|
145
146
|
path = File.expand_path(path, root)
|
146
147
|
say_status :chmod, relative_to_absolute_root(path), log_status
|
147
148
|
FileUtils.chmod_R(mode, path) unless options[:pretend]
|
@@ -161,6 +162,7 @@ class Thor
|
|
161
162
|
# end
|
162
163
|
#
|
163
164
|
def run(command, log_status=true)
|
165
|
+
return unless behavior == :invoke
|
164
166
|
say_status :run, "#{command} from #{relative_to_absolute_root(root, false)}", log_status
|
165
167
|
`#{command}` unless options[:pretend]
|
166
168
|
end
|
@@ -218,6 +220,7 @@ class Thor
|
|
218
220
|
# remove_file 'app/controllers/application_controller.rb'
|
219
221
|
#
|
220
222
|
def remove_file(path, log_status=true)
|
223
|
+
return unless behavior == :invoke
|
221
224
|
path = File.expand_path(path, root)
|
222
225
|
say_status :remove, relative_to_absolute_root(path), log_status
|
223
226
|
|
@@ -242,6 +245,7 @@ class Thor
|
|
242
245
|
# end
|
243
246
|
#
|
244
247
|
def gsub_file(path, flag, *args, &block)
|
248
|
+
return unless behavior == :invoke
|
245
249
|
log_status = args.last.is_a?(Symbol) || [ true, false ].include?(args.last) ? args.pop : true
|
246
250
|
|
247
251
|
path = File.expand_path(path, root)
|
@@ -267,9 +271,9 @@ class Thor
|
|
267
271
|
# append_file 'config/environments/test.rb', 'config.gem "rspec"'
|
268
272
|
#
|
269
273
|
def append_file(path, data=nil, log_status=true, &block)
|
274
|
+
return unless behavior == :invoke
|
270
275
|
path = File.expand_path(path, root)
|
271
276
|
say_status :append, relative_to_absolute_root(path), log_status
|
272
|
-
|
273
277
|
File.open(path, 'ab') { |file| file.write(data || block.call) } unless options[:pretend]
|
274
278
|
end
|
275
279
|
|
@@ -286,6 +290,7 @@ class Thor
|
|
286
290
|
# prepend_file 'config/environments/test.rb', 'config.gem "rspec"'
|
287
291
|
#
|
288
292
|
def prepend_file(path, data=nil, log_status=true, &block)
|
293
|
+
return unless behavior == :invoke
|
289
294
|
path = File.expand_path(path, root)
|
290
295
|
say_status :prepend, relative_to_absolute_root(path), log_status
|
291
296
|
|
data/lib/thor/base.rb
CHANGED
@@ -35,36 +35,19 @@ class Thor
|
|
35
35
|
send("#{key}=", value)
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
task_options = config.delete(:task_options)
|
40
|
-
parse_options = self.class.class_options
|
41
|
-
parse_options = parse_options.merge(task_options) if task_options
|
38
|
+
parse_options = self.class.class_options
|
42
39
|
|
43
|
-
|
44
|
-
|
40
|
+
options = if options.is_a?(Array)
|
41
|
+
task_options = config.delete(:task_options) # hook for start
|
42
|
+
parse_options = parse_options.merge(task_options) if task_options
|
43
|
+
Thor::Options.parse(parse_options, options)
|
44
|
+
else
|
45
|
+
Thor::Options.parse(parse_options, []).merge(options)
|
45
46
|
end
|
46
47
|
|
47
|
-
_set_default_options(options, self.class.class_options)
|
48
48
|
self.options = Thor::CoreExt::HashWithIndifferentAccess.new(options).freeze
|
49
49
|
end
|
50
50
|
|
51
|
-
protected
|
52
|
-
|
53
|
-
# Receives a hash of options, stringify keys and merge with default
|
54
|
-
# values from thor options.
|
55
|
-
#
|
56
|
-
def _set_default_options(options, default_options)
|
57
|
-
options.each_key do |key|
|
58
|
-
next unless key.is_a?(Symbol)
|
59
|
-
options[key.to_s] = options.delete(key)
|
60
|
-
end
|
61
|
-
|
62
|
-
default_options.each do |key, option|
|
63
|
-
next if option.default.nil? || options.key?(option.human_name.to_s)
|
64
|
-
options[option.human_name.to_s] ||= option.default
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
51
|
class << self
|
69
52
|
def included(base) #:nodoc:
|
70
53
|
base.send :extend, ClassMethods
|
@@ -178,7 +161,7 @@ class Thor
|
|
178
161
|
|
179
162
|
# Adds a bunch of options to the set of class options.
|
180
163
|
#
|
181
|
-
# class_options :foo =>
|
164
|
+
# class_options :foo => false, :bar => :required, :baz => :string
|
182
165
|
#
|
183
166
|
# If you prefer more detailed declaration, check class_option.
|
184
167
|
#
|
@@ -200,11 +183,10 @@ class Thor
|
|
200
183
|
# ==== Options
|
201
184
|
# :desc - Description for the argument.
|
202
185
|
# :required - If the argument is required or not.
|
203
|
-
# :default - Default value for this argument.
|
186
|
+
# :default - Default value for this argument.
|
204
187
|
# :group - The group for this options. Use by class options to output options in different levels.
|
205
188
|
# :aliases - Aliases for this option.
|
206
|
-
# :type - The type of the argument, can be :string, :hash, :array, :numeric
|
207
|
-
# Default accepts arguments as booleans (--switch) or as strings (--switch=VALUE).
|
189
|
+
# :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
|
208
190
|
# :banner - String to show on usage notes.
|
209
191
|
#
|
210
192
|
def class_option(name, options)
|
@@ -433,7 +415,7 @@ class Thor
|
|
433
415
|
# Receives a hash of options, parse them and add to the scope. This is a
|
434
416
|
# fast way to set a bunch of options:
|
435
417
|
#
|
436
|
-
# build_options :foo =>
|
418
|
+
# build_options :foo => true, :bar => :required, :baz => :string
|
437
419
|
#
|
438
420
|
# ==== Parameters
|
439
421
|
# Hash[Symbol => Object]
|
data/lib/thor/invocation.rb
CHANGED
@@ -76,9 +76,10 @@ class Thor
|
|
76
76
|
# invoke Rspec::RR, [], :style => :foo
|
77
77
|
#
|
78
78
|
def invoke(name=nil, task=nil, args=nil, opts=nil, config=nil)
|
79
|
-
task, args, opts, config = nil, task, args, opts if task.is_a?(Array)
|
80
|
-
|
79
|
+
task, args, opts, config = nil, task, args, opts if task.nil? || task.is_a?(Array)
|
80
|
+
args, opts, config = nil, args, opts if args.is_a?(Hash)
|
81
81
|
|
82
|
+
object, task = _setup_for_invoke(name, task)
|
82
83
|
if object.is_a?(Class)
|
83
84
|
klass = object
|
84
85
|
|
data/lib/thor/parser/argument.rb
CHANGED
@@ -9,15 +9,16 @@ class Thor
|
|
9
9
|
class_name = self.class.name.split("::").last
|
10
10
|
|
11
11
|
raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
|
12
|
-
raise ArgumentError, "#{class_name} cannot be required and have default value." if required && !default.nil?
|
13
12
|
raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
|
14
13
|
|
15
14
|
@name = name.to_s
|
16
15
|
@description = description
|
17
16
|
@required = required || false
|
18
|
-
@type = (type || :
|
17
|
+
@type = (type || :string).to_sym
|
19
18
|
@default = default
|
20
19
|
@banner = banner || default_banner
|
20
|
+
|
21
|
+
validate! # Trigger specific validations
|
21
22
|
end
|
22
23
|
|
23
24
|
def usage
|
@@ -37,12 +38,12 @@ class Thor
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
40
|
-
def input_required?
|
41
|
-
[ :numeric, :hash, :array, :string ].include?(type)
|
42
|
-
end
|
43
|
-
|
44
41
|
protected
|
45
42
|
|
43
|
+
def validate!
|
44
|
+
raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
|
45
|
+
end
|
46
|
+
|
46
47
|
def valid_type?(type)
|
47
48
|
VALID_TYPES.include?(type.to_sym)
|
48
49
|
end
|
@@ -23,24 +23,29 @@ class Thor
|
|
23
23
|
# Takes an array of Thor::Argument objects.
|
24
24
|
#
|
25
25
|
def initialize(arguments=[])
|
26
|
-
@
|
27
|
-
@
|
26
|
+
@assigns, @non_assigned_required = {}, []
|
27
|
+
@switches = arguments
|
28
|
+
|
29
|
+
arguments.each do |argument|
|
30
|
+
if argument.default
|
31
|
+
@assigns[argument.human_name] = argument.default
|
32
|
+
elsif argument.required?
|
33
|
+
@non_assigned_required << argument
|
34
|
+
end
|
35
|
+
end
|
28
36
|
end
|
29
37
|
|
30
38
|
def parse(args)
|
31
|
-
@pile
|
39
|
+
@pile = args.dup
|
32
40
|
|
33
|
-
@
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
else
|
38
|
-
argument.default
|
39
|
-
end
|
41
|
+
@switches.each do |argument|
|
42
|
+
break unless peek
|
43
|
+
@non_assigned_required.delete(argument)
|
44
|
+
@assigns[argument.human_name] = send(:"parse_#{argument.type}", argument.human_name)
|
40
45
|
end
|
41
46
|
|
42
47
|
check_requirement!
|
43
|
-
assigns
|
48
|
+
@assigns
|
44
49
|
end
|
45
50
|
|
46
51
|
private
|
data/lib/thor/parser/option.rb
CHANGED
@@ -2,10 +2,10 @@ class Thor
|
|
2
2
|
class Option < Argument
|
3
3
|
attr_reader :aliases, :group
|
4
4
|
|
5
|
-
VALID_TYPES = [:boolean, :numeric, :hash, :array, :string
|
5
|
+
VALID_TYPES = [:boolean, :numeric, :hash, :array, :string]
|
6
6
|
|
7
7
|
def initialize(name, description=nil, required=nil, type=nil, default=nil, banner=nil, group=nil, aliases=nil)
|
8
|
-
super(name, description, required, type
|
8
|
+
super(name, description, required, type, default, banner)
|
9
9
|
@aliases = [*aliases].compact
|
10
10
|
@group = group.to_s.capitalize if group
|
11
11
|
end
|
@@ -22,9 +22,6 @@ class Thor
|
|
22
22
|
# parse :foo => :required
|
23
23
|
# #=> Required option foo without default value
|
24
24
|
#
|
25
|
-
# parse :foo => :optional
|
26
|
-
# #=> Optional foo without default value
|
27
|
-
#
|
28
25
|
# parse :foo => 2
|
29
26
|
# #=> Option foo with default value 2 and type numeric
|
30
27
|
#
|
@@ -58,6 +55,10 @@ class Thor
|
|
58
55
|
value
|
59
56
|
elsif required = (value == :required)
|
60
57
|
:string
|
58
|
+
elsif value == :optional
|
59
|
+
# TODO Remove this warning in the future.
|
60
|
+
warn "Optional type is deprecated. Choose :boolean or :string instead. Assumed to be :boolean."
|
61
|
+
:boolean
|
61
62
|
end
|
62
63
|
when TrueClass, FalseClass
|
63
64
|
:boolean
|
@@ -94,8 +95,16 @@ class Thor
|
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
98
|
+
def input_required?
|
99
|
+
type != :boolean
|
100
|
+
end
|
101
|
+
|
97
102
|
protected
|
98
103
|
|
104
|
+
def validate!
|
105
|
+
raise ArgumentError, "An option cannot be boolean and required." if type == :boolean && required?
|
106
|
+
end
|
107
|
+
|
99
108
|
def valid_type?(type)
|
100
109
|
VALID_TYPES.include?(type.to_sym)
|
101
110
|
end
|
data/lib/thor/parser/options.rb
CHANGED
@@ -30,23 +30,22 @@ class Thor
|
|
30
30
|
|
31
31
|
# Takes a hash of Thor::Option objects.
|
32
32
|
#
|
33
|
-
def initialize(
|
34
|
-
|
33
|
+
def initialize(options={})
|
34
|
+
options = options.values
|
35
|
+
super(options)
|
36
|
+
@shorts, @switches = {}, {}
|
35
37
|
|
36
|
-
|
37
|
-
@
|
38
|
+
options.each do |option|
|
39
|
+
@switches[option.switch_name] = option
|
38
40
|
|
39
41
|
option.aliases.each do |short|
|
40
42
|
@shorts[short.to_s] ||= option.switch_name
|
41
43
|
end
|
42
|
-
|
43
|
-
mem[option.switch_name] = option
|
44
|
-
mem
|
45
44
|
end
|
46
45
|
end
|
47
46
|
|
48
47
|
def parse(args)
|
49
|
-
@pile
|
48
|
+
@pile = args.dup
|
50
49
|
|
51
50
|
while peek
|
52
51
|
if current_is_switch?
|
@@ -64,19 +63,14 @@ class Thor
|
|
64
63
|
switch = normalize_switch(switch)
|
65
64
|
next unless option = switch_option(switch)
|
66
65
|
|
67
|
-
|
68
|
-
raise RequiredArgumentMissingError, "no value provided for required option '#{switch}'" if peek.nil?
|
69
|
-
raise MalformattedArgumentError, "cannot pass switch '#{peek}' as an argument" unless current_is_value?
|
70
|
-
end
|
71
|
-
|
72
|
-
options[option.human_name] = parse_peek(switch, option)
|
66
|
+
@assigns[option.human_name] = parse_peek(switch, option)
|
73
67
|
else
|
74
68
|
shift
|
75
69
|
end
|
76
70
|
end
|
77
71
|
|
78
72
|
check_requirement!
|
79
|
-
|
73
|
+
@assigns
|
80
74
|
end
|
81
75
|
|
82
76
|
protected
|
@@ -97,13 +91,18 @@ class Thor
|
|
97
91
|
end
|
98
92
|
|
99
93
|
def switch_option(arg)
|
100
|
-
if
|
101
|
-
@switches[arg] || @switches["--#{
|
94
|
+
if match = no_or_skip?(arg)
|
95
|
+
@switches[arg] || @switches["--#{match}"]
|
102
96
|
else
|
103
97
|
@switches[arg]
|
104
98
|
end
|
105
99
|
end
|
106
100
|
|
101
|
+
def no_or_skip?(arg)
|
102
|
+
arg =~ /^--(no|skip)-([-\w]+)$/
|
103
|
+
$2
|
104
|
+
end
|
105
|
+
|
107
106
|
# Check if the given argument is actually a shortcut.
|
108
107
|
#
|
109
108
|
def normalize_switch(arg)
|
@@ -116,24 +115,20 @@ class Thor
|
|
116
115
|
if current_is_value?
|
117
116
|
["true", "TRUE", "t", "T", true].include?(shift)
|
118
117
|
else
|
119
|
-
@switches.key?(switch) || switch
|
118
|
+
@switches.key?(switch) || !no_or_skip?(switch)
|
120
119
|
end
|
121
120
|
end
|
122
121
|
|
123
|
-
#
|
124
|
-
# value to it. Also removes the option from the array where non assigned
|
125
|
-
# required are kept.
|
122
|
+
# Parse the value at the peek analyzing if it requires an input or not.
|
126
123
|
#
|
127
124
|
def parse_peek(switch, option)
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
current_is_value? ? :string : :boolean
|
132
|
-
else
|
133
|
-
option.type
|
125
|
+
if option.input_required?
|
126
|
+
return nil if no_or_skip?(switch)
|
127
|
+
raise MalformattedArgumentError, "no value provided for option '#{switch}'" unless current_is_value?
|
134
128
|
end
|
135
129
|
|
136
|
-
|
130
|
+
@non_assigned_required.delete(option)
|
131
|
+
send(:"parse_#{option.type}", switch)
|
137
132
|
end
|
138
133
|
|
139
134
|
end
|
data/lib/thor/runner.rb
CHANGED
@@ -31,7 +31,7 @@ class Thor::Runner < Thor
|
|
31
31
|
end
|
32
32
|
|
33
33
|
desc "install NAME", "Install a Thor file into your system tasks, optionally named for future updates"
|
34
|
-
method_options :as => :
|
34
|
+
method_options :as => :string, :relative => :boolean
|
35
35
|
def install(name)
|
36
36
|
initialize_thorfiles
|
37
37
|
|
@@ -132,7 +132,7 @@ class Thor::Runner < Thor
|
|
132
132
|
|
133
133
|
desc "list [SEARCH]",
|
134
134
|
"List the available thor tasks (--substring means SEARCH anywhere in the namespace)"
|
135
|
-
method_options :substring => :boolean, :group => :
|
135
|
+
method_options :substring => :boolean, :group => :string, :all => :boolean
|
136
136
|
def list(search="")
|
137
137
|
initialize_thorfiles
|
138
138
|
|
data/lib/thor.rb
CHANGED
@@ -72,7 +72,8 @@ class Thor
|
|
72
72
|
#
|
73
73
|
# ==== Parameters
|
74
74
|
# Hash[Symbol => Object]:: The hash key is the name of the option and the value
|
75
|
-
# is the type of the option. Can be :
|
75
|
+
# is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
|
76
|
+
# or :required (string). If you give a value, the type of the value is used.
|
76
77
|
#
|
77
78
|
def method_options(options=nil)
|
78
79
|
@method_options ||= {}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: josevalim-thor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yehuda Katz
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-01 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|