wycats-thor 0.11.3 → 0.11.4
Sign up to get free protection for your applications and to get access to all the features.
- data/{README.markdown → README.rdoc} +31 -44
- data/lib/thor.rb +11 -15
- data/lib/thor/actions.rb +16 -14
- data/lib/thor/actions/directory.rb +1 -1
- data/lib/thor/actions/inject_into_file.rb +1 -1
- data/lib/thor/base.rb +14 -23
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +2 -2
- data/lib/thor/core_ext/ordered_hash.rb +1 -3
- data/lib/thor/error.rb +10 -10
- data/lib/thor/group.rb +3 -3
- data/lib/thor/invocation.rb +23 -17
- data/lib/thor/parser/argument.rb +1 -1
- data/lib/thor/parser/arguments.rb +1 -1
- data/lib/thor/parser/option.rb +1 -1
- data/lib/thor/parser/options.rb +1 -1
- data/lib/thor/runner.rb +1 -1
- data/lib/thor/shell.rb +1 -1
- data/lib/thor/shell/basic.rb +13 -13
- data/lib/thor/shell/color.rb +9 -7
- data/lib/thor/task.rb +7 -7
- data/lib/thor/tasks/install.rb +1 -1
- data/lib/thor/tasks/package.rb +1 -1
- data/lib/thor/tasks/spec.rb +2 -2
- data/lib/thor/util.rb +3 -2
- metadata +6 -5
@@ -1,5 +1,4 @@
|
|
1
|
-
thor
|
2
|
-
====
|
1
|
+
= thor
|
3
2
|
|
4
3
|
Map options to a class. Simply create a class with the appropriate annotations
|
5
4
|
and have options automatically map to functions and parameters.
|
@@ -34,26 +33,18 @@ That gets converted to:
|
|
34
33
|
App.new.install("myname")
|
35
34
|
# with {'force' => true} as options hash
|
36
35
|
|
37
|
-
1.
|
38
|
-
2.
|
39
|
-
3.
|
40
|
-
4.
|
41
|
-
|
42
|
-
Types for
|
43
|
-
|
44
|
-
|
45
|
-
<
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
<dd>is parsed as --option=VALUE</dd>
|
50
|
-
<dt><code>:numeric</code></dt>
|
51
|
-
<dd>is parsed as --option=N</dd>
|
52
|
-
<dt><code>:array</code></dt>
|
53
|
-
<dd>is parsed as --option=one two three</dd>
|
54
|
-
<dt><code>:hash</code></dt>
|
55
|
-
<dd>is parsed as --option=key:value key:value key:value</dd>
|
56
|
-
</dl>
|
36
|
+
1. Inherit from Thor to turn a class into an option mapper
|
37
|
+
2. Map additional non-valid identifiers to specific methods. In this case, convert -L to :list
|
38
|
+
3. Describe the method immediately below. The first parameter is the usage information, and the second parameter is the description
|
39
|
+
4. Provide any additional options that will be available the instance method options.
|
40
|
+
|
41
|
+
== Types for <tt>method_options</tt>
|
42
|
+
|
43
|
+
* :boolean - is parsed as <tt>--option</tt> or <tt>--option=true</tt>
|
44
|
+
* :string - is parsed as <tt>--option=VALUE</tt>
|
45
|
+
* :numeric - is parsed as <tt>--option=N</tt>
|
46
|
+
* :array - is parsed as <tt>--option=one two three</tt>
|
47
|
+
* :hash - is parsed as <tt>--option=name:string age:integer</tt>
|
57
48
|
|
58
49
|
Besides, method_option allows a default value to be given, examples:
|
59
50
|
|
@@ -66,9 +57,9 @@ Besides, method_option allows a default value to be given, examples:
|
|
66
57
|
method_options :threshold => 3.0
|
67
58
|
#=> Creates a numeric option with default value 3.0
|
68
59
|
|
69
|
-
You can also supply
|
60
|
+
You can also supply <tt>:option => :required</tt> to mark an option as required. The
|
70
61
|
type is assumed to be string. If you want a required hash with default values
|
71
|
-
as option, you can use
|
62
|
+
as option, you can use <tt>method_option</tt> which uses a more declarative style:
|
72
63
|
|
73
64
|
method_option :attributes, :type => :hash, :default => {}, :required => true
|
74
65
|
|
@@ -91,8 +82,7 @@ You can supply as many aliases as you want.
|
|
91
82
|
|
92
83
|
NOTE: Type :optional available in Thor 0.9.0 was deprecated. Use :string or :boolean instead.
|
93
84
|
|
94
|
-
Namespaces
|
95
|
-
----------
|
85
|
+
== Namespaces
|
96
86
|
|
97
87
|
By default, your Thor tasks are invoked using Ruby namespace. In the example
|
98
88
|
above, tasks are invoked as:
|
@@ -124,8 +114,7 @@ And then your tasks hould be invoked as:
|
|
124
114
|
|
125
115
|
thor myapp:install name --force
|
126
116
|
|
127
|
-
Invocations
|
128
|
-
-----------
|
117
|
+
== Invocations
|
129
118
|
|
130
119
|
Thor comes with a invocation-dependency system as well which allows a task to be
|
131
120
|
invoked only once. For example:
|
@@ -158,8 +147,7 @@ The output is "1 2 3", which means that the three task was invoked only once.
|
|
158
147
|
You can even invoke tasks from another class, so be sure to check the
|
159
148
|
documentation.
|
160
149
|
|
161
|
-
Thor::Group
|
162
|
-
-----------
|
150
|
+
== Thor::Group
|
163
151
|
|
164
152
|
Thor has a special class called Thor::Group. The main difference to Thor class
|
165
153
|
is that it invokes all tasks at once. The example above could be rewritten in
|
@@ -185,10 +173,10 @@ When invoked:
|
|
185
173
|
|
186
174
|
thor counter
|
187
175
|
|
188
|
-
It prints "1 2 3" as well. Notice you should
|
189
|
-
and not each task anymore. Thor::Group is a great tool to create
|
190
|
-
since you can define several steps which are invoked in the order they
|
191
|
-
defined (Thor::Group is the tool use in generators in Rails 3.0).
|
176
|
+
It prints "1 2 3" as well. Notice you should describe (using the method <tt>desc</tt>)
|
177
|
+
only the class and not each task anymore. Thor::Group is a great tool to create
|
178
|
+
generators, since you can define several steps which are invoked in the order they
|
179
|
+
are defined (Thor::Group is the tool use in generators in Rails 3.0).
|
192
180
|
|
193
181
|
Besides, Thor::Group can parse arguments and options as Thor tasks:
|
194
182
|
|
@@ -218,17 +206,17 @@ The counter above expects one parameter and has the folling outputs:
|
|
218
206
|
thor counter 11
|
219
207
|
# Prints "11 12 13"
|
220
208
|
|
221
|
-
You can also give options to Thor::Group, but instead of using
|
222
|
-
|
223
|
-
and class_options methods are available to Thor class as well.
|
209
|
+
You can also give options to Thor::Group, but instead of using <tt>method_option</tt>
|
210
|
+
and <tt>method_options</tt>, you should use <tt>class_option</tt> and <tt>class_options</tt>.
|
211
|
+
Both argument and class_options methods are available to Thor class as well.
|
224
212
|
|
225
|
-
Actions
|
226
|
-
-------
|
213
|
+
== Actions
|
227
214
|
|
228
215
|
Thor comes with several actions which helps with script and generator tasks. You
|
229
|
-
might be familiar with them since some came from Rails Templates. They are:
|
230
|
-
|
231
|
-
|
216
|
+
might be familiar with them since some came from Rails Templates. They are:
|
217
|
+
<tt>say</tt>, <tt>ask</tt>, <tt>yes?</tt>, <tt>no?</tt>, <tt>add_file</tt>,
|
218
|
+
<tt>remove_file</tt>, <tt>copy_file</tt>, <tt>template</tt>, <tt>directory</tt>,
|
219
|
+
<tt>inside</tt>, <tt>run</tt>, <tt>inject_into_file</tt> and a couple more.
|
232
220
|
|
233
221
|
To use them, you just need to include Thor::Actions in your Thor classes:
|
234
222
|
|
@@ -241,7 +229,6 @@ Some actions like copy file requires that a class method called source_root is
|
|
241
229
|
defined in your class. This is the directory where your templates should be
|
242
230
|
placed. Be sure to check the documentation.
|
243
231
|
|
244
|
-
License
|
245
|
-
-------
|
232
|
+
== License
|
246
233
|
|
247
234
|
See MIT LICENSE.
|
data/lib/thor.rb
CHANGED
@@ -101,8 +101,7 @@ class Thor
|
|
101
101
|
# :required - If the argument is required or not.
|
102
102
|
# :default - Default value for this argument. It cannot be required and have default values.
|
103
103
|
# :aliases - Aliases for this option.
|
104
|
-
# :type - The type of the argument, can be :string, :hash, :array, :numeric
|
105
|
-
# Default accepts arguments as booleans (--switch) or as strings (--switch=VALUE).
|
104
|
+
# :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
|
106
105
|
# :group - The group for this options. Use by class options to output options in different levels.
|
107
106
|
# :banner - String to show on usage notes.
|
108
107
|
#
|
@@ -160,18 +159,15 @@ class Thor
|
|
160
159
|
raise UndefinedTaskError, "task '#{meth}' could not be found in namespace '#{self.namespace}'" unless task
|
161
160
|
|
162
161
|
shell.say "Usage:"
|
163
|
-
shell.say " #{banner(task, options[:namespace])}"
|
162
|
+
shell.say " #{banner(task, options[:namespace], false)}"
|
164
163
|
shell.say
|
165
|
-
class_options_help(shell, "Class")
|
164
|
+
class_options_help(shell, "Class", :Method => task.options.map { |_, o| o })
|
166
165
|
shell.say task.description
|
167
166
|
else
|
168
167
|
list = (options[:short] ? tasks : all_tasks).map do |_, task|
|
169
|
-
item = [
|
170
|
-
item << if task.short_description
|
171
|
-
|
172
|
-
else
|
173
|
-
"\n"
|
174
|
-
end
|
168
|
+
item = [ banner(task, options[:namespace]), "\n" ]
|
169
|
+
item.last << "# #{task.short_description}\n" if task.short_description
|
170
|
+
item
|
175
171
|
end
|
176
172
|
|
177
173
|
if options[:short]
|
@@ -187,12 +183,12 @@ class Thor
|
|
187
183
|
protected
|
188
184
|
|
189
185
|
# The banner for this class. You can customize it if you are invoking the
|
190
|
-
# thor class by another
|
191
|
-
# the task that is going to be invoked and
|
192
|
-
# displayed.
|
186
|
+
# thor class by another ways which is not the Thor::Runner. It receives
|
187
|
+
# the task that is going to be invoked and a boolean which indicates if
|
188
|
+
# the namespace should be displayed as arguments.
|
193
189
|
#
|
194
|
-
def banner(task, namespace=true)
|
195
|
-
task.formatted_usage(self, namespace)
|
190
|
+
def banner(task, namespace=true, show_options=true)
|
191
|
+
task.formatted_usage(self, namespace, show_options)
|
196
192
|
end
|
197
193
|
|
198
194
|
def baseclass #:nodoc:
|
data/lib/thor/actions.rb
CHANGED
@@ -43,13 +43,11 @@ class Thor
|
|
43
43
|
# 3) Parents source paths
|
44
44
|
#
|
45
45
|
def source_paths_for_search
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
paths
|
52
|
-
end
|
46
|
+
paths = []
|
47
|
+
paths += self.source_paths
|
48
|
+
paths << self.source_root if self.respond_to?(:source_root)
|
49
|
+
paths += from_superclass(:source_paths, [])
|
50
|
+
paths
|
53
51
|
end
|
54
52
|
end
|
55
53
|
|
@@ -60,8 +58,7 @@ class Thor
|
|
60
58
|
# It also accepts :force, :skip and :pretend to set the behavior
|
61
59
|
# and the respective option.
|
62
60
|
#
|
63
|
-
# destination_root<String>:: The root directory needed for some actions.
|
64
|
-
# as destination root.
|
61
|
+
# destination_root<String>:: The root directory needed for some actions.
|
65
62
|
#
|
66
63
|
def initialize(args=[], options={}, config={})
|
67
64
|
self.behavior = case config[:behavior].to_s
|
@@ -80,7 +77,7 @@ class Thor
|
|
80
77
|
|
81
78
|
# Wraps an action object and call it accordingly to the thor class behavior.
|
82
79
|
#
|
83
|
-
def action(instance)
|
80
|
+
def action(instance) #:nodoc:
|
84
81
|
if behavior == :revoke
|
85
82
|
instance.revoke!
|
86
83
|
else
|
@@ -110,18 +107,23 @@ class Thor
|
|
110
107
|
remove_dot ? (path[2..-1] || '') : path
|
111
108
|
end
|
112
109
|
|
110
|
+
# Holds source paths in instance so they can be manipulated.
|
111
|
+
#
|
112
|
+
def source_paths
|
113
|
+
@source_paths ||= self.class.source_paths_for_search
|
114
|
+
end
|
115
|
+
|
113
116
|
# Receives a file or directory and search for it in the source paths.
|
114
117
|
#
|
115
118
|
def find_in_source_paths(file)
|
116
119
|
relative_root = relative_to_original_destination_root(destination_root, false)
|
117
|
-
paths = self.class.source_paths_for_search
|
118
120
|
|
119
|
-
|
121
|
+
source_paths.each do |source|
|
120
122
|
source_file = File.expand_path(file, File.join(source, relative_root))
|
121
123
|
return source_file if File.exists?(source_file)
|
122
124
|
end
|
123
125
|
|
124
|
-
if
|
126
|
+
if source_paths.empty?
|
125
127
|
raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " <<
|
126
128
|
"you can define a source_root in your class."
|
127
129
|
else
|
@@ -205,7 +207,7 @@ class Thor
|
|
205
207
|
end
|
206
208
|
|
207
209
|
say_status :run, desc, config.fetch(:verbose, true)
|
208
|
-
|
210
|
+
system(command) unless options[:pretend]
|
209
211
|
end
|
210
212
|
|
211
213
|
# Executes a ruby script (taking into account WIN32 platform quirks).
|
@@ -3,7 +3,7 @@ require 'thor/actions/empty_directory'
|
|
3
3
|
class Thor
|
4
4
|
module Actions
|
5
5
|
|
6
|
-
# Copies
|
6
|
+
# Copies recursively the files from source directory to root directory.
|
7
7
|
# If any of the files finishes with .tt, it's considered to be a template
|
8
8
|
# and is placed in the destination without the extension .tt. If any
|
9
9
|
# empty directory is found, it's copied and all .empty_directory files are
|
@@ -34,7 +34,7 @@ class Thor
|
|
34
34
|
action InjectIntoFile.new(self, destination, data, config)
|
35
35
|
end
|
36
36
|
|
37
|
-
class InjectIntoFile < EmptyDirectory
|
37
|
+
class InjectIntoFile < EmptyDirectory #:nodoc:
|
38
38
|
attr_reader :flag, :replacement
|
39
39
|
|
40
40
|
def initialize(base, destination, data, config)
|
data/lib/thor/base.rb
CHANGED
@@ -78,7 +78,6 @@ class Thor
|
|
78
78
|
|
79
79
|
# Whenever a class inherits from Thor or Thor::Group, we should track the
|
80
80
|
# class and the file on Thor::Base. This is the method responsable for it.
|
81
|
-
# Also adds the source root to the source paths if the klass respond to it.
|
82
81
|
#
|
83
82
|
def register_klass_file(klass) #:nodoc:
|
84
83
|
file = caller[1].match(/(.*):\d+/)[1]
|
@@ -246,7 +245,8 @@ class Thor
|
|
246
245
|
# Returns the tasks for this Thor class.
|
247
246
|
#
|
248
247
|
# ==== Returns
|
249
|
-
# OrderedHash:: An ordered hash with
|
248
|
+
# OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
|
249
|
+
# objects as values.
|
250
250
|
#
|
251
251
|
def tasks
|
252
252
|
@tasks ||= Thor::CoreExt::OrderedHash.new
|
@@ -255,7 +255,8 @@ class Thor
|
|
255
255
|
# Returns the tasks for this Thor class and all subclasses.
|
256
256
|
#
|
257
257
|
# ==== Returns
|
258
|
-
# OrderedHash
|
258
|
+
# OrderedHash:: An ordered hash with tasks names as keys and Thor::Task
|
259
|
+
# objects as values.
|
259
260
|
#
|
260
261
|
def all_tasks
|
261
262
|
@all_tasks ||= from_superclass(:all_tasks, Thor::CoreExt::OrderedHash.new)
|
@@ -342,7 +343,7 @@ class Thor
|
|
342
343
|
|
343
344
|
# Default way to start generators from the command line.
|
344
345
|
#
|
345
|
-
def start(given_args=ARGV, config={})
|
346
|
+
def start(given_args=ARGV, config={})
|
346
347
|
config[:shell] ||= Thor::Base.shell.new
|
347
348
|
yield
|
348
349
|
rescue Thor::Error => e
|
@@ -360,7 +361,7 @@ class Thor
|
|
360
361
|
# hooks to add extra options, one of them if the third argument called
|
361
362
|
# extra_group that should be a hash in the format :group => Array[Options].
|
362
363
|
#
|
363
|
-
# The second is by returning a
|
364
|
+
# The second is by returning a lambda used to print values. The lambda
|
364
365
|
# requires two options: the group name and the array of options.
|
365
366
|
#
|
366
367
|
def class_options_help(shell, ungrouped_name=nil, extra_group=nil) #:nodoc:
|
@@ -377,24 +378,14 @@ class Thor
|
|
377
378
|
|
378
379
|
options.each do |option|
|
379
380
|
item = [ option.usage(padding) ]
|
380
|
-
|
381
|
-
item << if option.description
|
382
|
-
"# #{option.description}"
|
383
|
-
else
|
384
|
-
""
|
385
|
-
end
|
381
|
+
item.push(option.description ? "# #{option.description}" : "")
|
386
382
|
|
387
383
|
list << item
|
388
384
|
list << [ "", "# Default: #{option.default}" ] if option.show_default?
|
389
385
|
end
|
390
386
|
|
391
387
|
unless list.empty?
|
392
|
-
|
393
|
-
shell.say "#{group_name} options:"
|
394
|
-
else
|
395
|
-
shell.say "Options:"
|
396
|
-
end
|
397
|
-
|
388
|
+
shell.say(group_name ? "#{group_name} options:" : "Options:")
|
398
389
|
shell.print_table(list, :ident => 2)
|
399
390
|
shell.say ""
|
400
391
|
end
|
@@ -412,7 +403,7 @@ class Thor
|
|
412
403
|
|
413
404
|
# Raises an error if the word given is a Thor reserved word.
|
414
405
|
#
|
415
|
-
def is_thor_reserved_word?(word, type)
|
406
|
+
def is_thor_reserved_word?(word, type) #:nodoc:
|
416
407
|
return false unless THOR_RESERVED_WORDS.include?(word.to_s)
|
417
408
|
raise "#{word.inspect} is a Thor reserved word and cannot be defined as #{type}"
|
418
409
|
end
|
@@ -423,7 +414,7 @@ class Thor
|
|
423
414
|
# name<Symbol>:: The name of the argument.
|
424
415
|
# options<Hash>:: Described in both class_option and method_option.
|
425
416
|
#
|
426
|
-
def build_option(name, options, scope)
|
417
|
+
def build_option(name, options, scope) #:nodoc:
|
427
418
|
scope[name] = Thor::Option.new(name, options[:desc], options[:required],
|
428
419
|
options[:type], options[:default], options[:banner],
|
429
420
|
options[:group], options[:aliases])
|
@@ -437,7 +428,7 @@ class Thor
|
|
437
428
|
# ==== Parameters
|
438
429
|
# Hash[Symbol => Object]
|
439
430
|
#
|
440
|
-
def build_options(options, scope)
|
431
|
+
def build_options(options, scope) #:nodoc:
|
441
432
|
options.each do |key, value|
|
442
433
|
scope[key] = Thor::Option.parse(key, value)
|
443
434
|
end
|
@@ -447,7 +438,7 @@ class Thor
|
|
447
438
|
# class, just return it, otherwise dup it and add the fresh copy to the
|
448
439
|
# current task hash.
|
449
440
|
#
|
450
|
-
def find_and_refresh_task(name)
|
441
|
+
def find_and_refresh_task(name) #:nodoc:
|
451
442
|
task = if task = tasks[name.to_s]
|
452
443
|
task
|
453
444
|
elsif task = all_tasks[name.to_s]
|
@@ -465,7 +456,7 @@ class Thor
|
|
465
456
|
end
|
466
457
|
|
467
458
|
# Fire this callback whenever a method is added. Added methods are
|
468
|
-
# tracked as tasks
|
459
|
+
# tracked as tasks by invoking the create_task method.
|
469
460
|
#
|
470
461
|
def method_added(meth)
|
471
462
|
meth = meth.to_s
|
@@ -486,7 +477,7 @@ class Thor
|
|
486
477
|
end
|
487
478
|
|
488
479
|
# Retrieves a value from superclass. If it reaches the baseclass,
|
489
|
-
# returns
|
480
|
+
# returns default.
|
490
481
|
#
|
491
482
|
def from_superclass(method, default=nil)
|
492
483
|
if self == baseclass || !superclass.respond_to?(method, true)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Thor
|
2
|
-
module CoreExt
|
2
|
+
module CoreExt #:nodoc:
|
3
3
|
|
4
4
|
# A hash with indifferent access and magic predicates.
|
5
5
|
#
|
@@ -9,7 +9,7 @@ class Thor
|
|
9
9
|
# hash['foo'] #=> 'bar'
|
10
10
|
# hash.foo? #=> true
|
11
11
|
#
|
12
|
-
class HashWithIndifferentAccess < ::Hash
|
12
|
+
class HashWithIndifferentAccess < ::Hash #:nodoc:
|
13
13
|
|
14
14
|
def initialize(hash={})
|
15
15
|
super()
|
data/lib/thor/error.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
class Thor
|
2
|
-
# Thor::Error is raised when it's caused by
|
3
|
-
#
|
2
|
+
# Thor::Error is raised when it's caused by wrong usage of thor classes. Those
|
3
|
+
# errors have their backtrace supressed and are nicely shown to the user.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# Errors that are caused by the developer, like declaring a method which
|
6
|
+
# overwrites a thor keyword, it SHOULD NOT raise a Thor::Error. This way, we
|
7
|
+
# ensure that developer errors are shown with full backtrace.
|
8
8
|
#
|
9
|
-
class Error < StandardError
|
9
|
+
class Error < StandardError
|
10
10
|
end
|
11
11
|
|
12
12
|
# Raised when a task was not found.
|
13
13
|
#
|
14
|
-
class UndefinedTaskError < Error
|
14
|
+
class UndefinedTaskError < Error
|
15
15
|
end
|
16
16
|
|
17
17
|
# Raised when a task was found, but not invoked properly.
|
18
18
|
#
|
19
|
-
class InvocationError < Error
|
19
|
+
class InvocationError < Error
|
20
20
|
end
|
21
21
|
|
22
|
-
class RequiredArgumentMissingError < InvocationError
|
22
|
+
class RequiredArgumentMissingError < InvocationError
|
23
23
|
end
|
24
24
|
|
25
|
-
class MalformattedArgumentError < InvocationError
|
25
|
+
class MalformattedArgumentError < InvocationError
|
26
26
|
end
|
27
27
|
end
|
data/lib/thor/group.rb
CHANGED
@@ -221,9 +221,9 @@ class Thor::Group
|
|
221
221
|
protected
|
222
222
|
|
223
223
|
# The banner for this class. You can customize it if you are invoking the
|
224
|
-
# thor class by another
|
224
|
+
# thor class by another ways which is not the Thor::Runner.
|
225
225
|
#
|
226
|
-
def banner
|
226
|
+
def banner
|
227
227
|
"#{self.namespace} #{self.arguments.map {|a| a.usage }.join(' ')}"
|
228
228
|
end
|
229
229
|
|
@@ -244,7 +244,7 @@ class Thor::Group
|
|
244
244
|
# Shortcut to invoke with padding and block handling. Use internally by
|
245
245
|
# invoke and invoke_from_option class methods.
|
246
246
|
#
|
247
|
-
def _invoke_for_class_method(klass, task=nil, *args, &block)
|
247
|
+
def _invoke_for_class_method(klass, task=nil, *args, &block) #:nodoc:
|
248
248
|
shell.padding += 1
|
249
249
|
|
250
250
|
result = if block_given?
|
data/lib/thor/invocation.rb
CHANGED
@@ -96,20 +96,8 @@ class Thor
|
|
96
96
|
task, args, opts, config = nil, task, args, opts if task.nil? || task.is_a?(Array)
|
97
97
|
args, opts, config = nil, args, opts if args.is_a?(Hash)
|
98
98
|
|
99
|
-
object, task
|
100
|
-
|
101
|
-
klass = object
|
102
|
-
|
103
|
-
stored_args, stored_opts, stored_config = @_initializer
|
104
|
-
args ||= stored_args.dup
|
105
|
-
opts ||= stored_opts.dup
|
106
|
-
|
107
|
-
config ||= {}
|
108
|
-
config = stored_config.merge(_shared_configuration).merge!(config)
|
109
|
-
instance = klass.new(args, opts, config)
|
110
|
-
else
|
111
|
-
klass, instance = object.class, object
|
112
|
-
end
|
99
|
+
object, task = _prepare_for_invocation(name, task)
|
100
|
+
klass, instance = _initialize_klass_with_initializer(object, args, opts, config)
|
113
101
|
|
114
102
|
method_args = []
|
115
103
|
current = @_invocations[klass]
|
@@ -134,7 +122,7 @@ class Thor
|
|
134
122
|
|
135
123
|
# Configuration values that are shared between invocations.
|
136
124
|
#
|
137
|
-
def _shared_configuration
|
125
|
+
def _shared_configuration #:nodoc:
|
138
126
|
{ :invocations => @_invocations }
|
139
127
|
end
|
140
128
|
|
@@ -154,13 +142,13 @@ class Thor
|
|
154
142
|
|
155
143
|
# If the object was not set, use self and use the name as task.
|
156
144
|
object, task = self, name unless object
|
157
|
-
return object,
|
145
|
+
return object, _validate_task(object, task)
|
158
146
|
end
|
159
147
|
|
160
148
|
# Check if the object given is a Thor class object and get a task object
|
161
149
|
# for it.
|
162
150
|
#
|
163
|
-
def
|
151
|
+
def _validate_task(object, task) #:nodoc:
|
164
152
|
klass = object.is_a?(Class) ? object : object.class
|
165
153
|
raise "Expected Thor class, got #{klass}" unless klass <= Thor::Base
|
166
154
|
|
@@ -168,5 +156,23 @@ class Thor
|
|
168
156
|
task = klass.all_tasks[task.to_s] || Task.dynamic(task) if task && !task.is_a?(Thor::Task)
|
169
157
|
task
|
170
158
|
end
|
159
|
+
|
160
|
+
# Initialize klass using values stored in the @_initializer.
|
161
|
+
#
|
162
|
+
def _initialize_klass_with_initializer(object, args, opts, config) #:nodoc:
|
163
|
+
if object.is_a?(Class)
|
164
|
+
klass = object
|
165
|
+
|
166
|
+
stored_args, stored_opts, stored_config = @_initializer
|
167
|
+
args ||= stored_args.dup
|
168
|
+
opts ||= stored_opts.dup
|
169
|
+
|
170
|
+
config ||= {}
|
171
|
+
config = stored_config.merge(_shared_configuration).merge!(config)
|
172
|
+
[ klass, klass.new(args, opts, config) ]
|
173
|
+
else
|
174
|
+
[ object.class, object ]
|
175
|
+
end
|
176
|
+
end
|
171
177
|
end
|
172
178
|
end
|
data/lib/thor/parser/argument.rb
CHANGED
data/lib/thor/parser/option.rb
CHANGED
data/lib/thor/parser/options.rb
CHANGED
@@ -2,7 +2,7 @@ class Thor
|
|
2
2
|
# This is a modified version of Daniel Berger's Getopt::Long class, licensed
|
3
3
|
# under Ruby's license.
|
4
4
|
#
|
5
|
-
class Options < Arguments
|
5
|
+
class Options < Arguments #:nodoc:
|
6
6
|
LONG_RE = /^(--\w+[-\w+]*)$/
|
7
7
|
SHORT_RE = /^(-[a-z])$/i
|
8
8
|
EQ_RE = /^(--\w+[-\w+]*|-[a-z])=(.*)$/i
|
data/lib/thor/runner.rb
CHANGED
data/lib/thor/shell.rb
CHANGED
data/lib/thor/shell/basic.rb
CHANGED
@@ -11,9 +11,9 @@ class Thor
|
|
11
11
|
@base, @padding = nil, 0
|
12
12
|
end
|
13
13
|
|
14
|
-
#
|
14
|
+
# Sets the output padding, not allowing less than zero values.
|
15
15
|
#
|
16
|
-
def padding=(value)
|
16
|
+
def padding=(value)
|
17
17
|
@padding = [0, value].max
|
18
18
|
end
|
19
19
|
|
@@ -52,7 +52,7 @@ class Thor
|
|
52
52
|
# in log_status, avoiding the message from being shown. If a Symbol is
|
53
53
|
# given in log_status, it's used as the color.
|
54
54
|
#
|
55
|
-
def say_status(status, message, log_status=true)
|
55
|
+
def say_status(status, message, log_status=true)
|
56
56
|
return if quiet? || log_status == false
|
57
57
|
spaces = " " * (padding + 1)
|
58
58
|
color = log_status.is_a?(Symbol) ? log_status : :green
|
@@ -103,7 +103,6 @@ class Thor
|
|
103
103
|
#
|
104
104
|
# ==== Options
|
105
105
|
# ident<Integer>:: Ident the first column by ident value.
|
106
|
-
# emphasize_last<Boolean>:: When true, add a different behavior to the last column.
|
107
106
|
#
|
108
107
|
def print_table(table, options={})
|
109
108
|
return if table.empty?
|
@@ -131,7 +130,7 @@ class Thor
|
|
131
130
|
#
|
132
131
|
# ==== Parameters
|
133
132
|
# destination<String>:: the destination file to solve conflicts
|
134
|
-
# block<Proc>:: an optional
|
133
|
+
# block<Proc>:: an optional block that returns the value to be used in diff
|
135
134
|
#
|
136
135
|
def file_collision(destination)
|
137
136
|
return true if @always_force
|
@@ -164,19 +163,20 @@ class Thor
|
|
164
163
|
# wrong, you can always raise an exception. If you raise a Thor::Error, it
|
165
164
|
# will be rescued and wrapped in the method below.
|
166
165
|
#
|
167
|
-
def error(statement)
|
166
|
+
def error(statement)
|
168
167
|
$stderr.puts statement
|
169
168
|
end
|
170
169
|
|
171
|
-
# Apply color to the given string with optional bold.
|
170
|
+
# Apply color to the given string with optional bold. Disabled in the
|
171
|
+
# Thor::Shell::Basic class.
|
172
172
|
#
|
173
|
-
def set_color(string, color, bold=false)
|
173
|
+
def set_color(string, color, bold=false) #:nodoc:
|
174
174
|
string
|
175
175
|
end
|
176
176
|
|
177
177
|
protected
|
178
178
|
|
179
|
-
def is?(value)
|
179
|
+
def is?(value) #:nodoc:
|
180
180
|
value = value.to_s
|
181
181
|
|
182
182
|
if value.size == 1
|
@@ -186,7 +186,7 @@ class Thor
|
|
186
186
|
end
|
187
187
|
end
|
188
188
|
|
189
|
-
def file_collision_help
|
189
|
+
def file_collision_help #:nodoc:
|
190
190
|
<<HELP
|
191
191
|
Y - yes, overwrite
|
192
192
|
n - no, do not overwrite
|
@@ -197,17 +197,17 @@ h - help, show this help
|
|
197
197
|
HELP
|
198
198
|
end
|
199
199
|
|
200
|
-
def show_diff(destination, content)
|
200
|
+
def show_diff(destination, content) #:nodoc:
|
201
201
|
diff_cmd = ENV['THOR_DIFF'] || ENV['RAILS_DIFF'] || 'diff -u'
|
202
202
|
|
203
203
|
Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp|
|
204
204
|
temp.write content
|
205
205
|
temp.rewind
|
206
|
-
|
206
|
+
system %(#{diff_cmd} "#{destination}" "#{temp.path}")
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
|
-
def quiet?
|
210
|
+
def quiet? #:nodoc:
|
211
211
|
base && base.options[:quiet]
|
212
212
|
end
|
213
213
|
|
data/lib/thor/shell/color.rb
CHANGED
@@ -2,7 +2,8 @@ require 'thor/shell/basic'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Shell
|
5
|
-
#
|
5
|
+
# Inherit from Thor::Shell::Basic and add set_color behavior. Check
|
6
|
+
# Thor::Shell::Basic to see all available methods.
|
6
7
|
#
|
7
8
|
class Color < Basic
|
8
9
|
# Embed in a String to clear all previous ANSI sequences.
|
@@ -44,9 +45,10 @@ class Thor
|
|
44
45
|
# Set the terminal's background ANSI color to white.
|
45
46
|
ON_WHITE = "\e[47m"
|
46
47
|
|
47
|
-
# Set color by using a string or one of the defined constants.
|
48
|
-
#
|
49
|
-
#
|
48
|
+
# Set color by using a string or one of the defined constants. If a third
|
49
|
+
# option is set to true, it also adds bold to the string. This is based
|
50
|
+
# on Highline implementation and it automatically appends CLEAR to the end
|
51
|
+
# of the returned String.
|
50
52
|
#
|
51
53
|
def set_color(string, color, bold=false)
|
52
54
|
color = self.class.const_get(color.to_s.upcase) if color.is_a?(Symbol)
|
@@ -59,7 +61,7 @@ class Thor
|
|
59
61
|
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
60
62
|
# available.
|
61
63
|
#
|
62
|
-
def show_diff(destination, content)
|
64
|
+
def show_diff(destination, content) #:nodoc:
|
63
65
|
if diff_lcs_loaded? && ENV['THOR_DIFF'].nil? && ENV['RAILS_DIFF'].nil?
|
64
66
|
actual = File.read(destination).to_s.split("\n")
|
65
67
|
content = content.to_s.split("\n")
|
@@ -72,7 +74,7 @@ class Thor
|
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
|
-
def output_diff_line(diff)
|
77
|
+
def output_diff_line(diff) #:nodoc:
|
76
78
|
case diff.action
|
77
79
|
when '-'
|
78
80
|
say "- #{diff.old_element.chomp}", :red, true
|
@@ -89,7 +91,7 @@ class Thor
|
|
89
91
|
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
90
92
|
# for diff.
|
91
93
|
#
|
92
|
-
def diff_lcs_loaded?
|
94
|
+
def diff_lcs_loaded? #:nodoc:
|
93
95
|
return true if defined?(Diff::LCS)
|
94
96
|
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
95
97
|
|
data/lib/thor/task.rb
CHANGED
@@ -12,7 +12,7 @@ class Thor
|
|
12
12
|
super(name.to_s, description, usage, options || {})
|
13
13
|
end
|
14
14
|
|
15
|
-
def initialize_copy(other)
|
15
|
+
def initialize_copy(other) #:nodoc:
|
16
16
|
super(other)
|
17
17
|
self.options = other.options.dup if other.options
|
18
18
|
end
|
@@ -36,11 +36,11 @@ class Thor
|
|
36
36
|
# Returns the formatted usage. If a class is given, the class arguments are
|
37
37
|
# injected in the usage.
|
38
38
|
#
|
39
|
-
def formatted_usage(klass=nil, namespace=false)
|
39
|
+
def formatted_usage(klass=nil, namespace=false, show_options=true)
|
40
40
|
formatted = ''
|
41
41
|
formatted << "#{klass.namespace.gsub(/^default/,'')}:" if klass && namespace
|
42
42
|
formatted << formatted_arguments(klass)
|
43
|
-
formatted << " #{formatted_options}"
|
43
|
+
formatted << " #{formatted_options}" if show_options
|
44
44
|
formatted.strip!
|
45
45
|
formatted
|
46
46
|
end
|
@@ -67,20 +67,20 @@ class Thor
|
|
67
67
|
|
68
68
|
# Given a target, checks if this class name is not a private/protected method.
|
69
69
|
#
|
70
|
-
def public_method?(instance)
|
70
|
+
def public_method?(instance) #:nodoc:
|
71
71
|
collection = instance.private_methods + instance.protected_methods
|
72
72
|
!(collection).include?(name.to_s) && !(collection).include?(name.to_sym) # For Ruby 1.9
|
73
73
|
end
|
74
74
|
|
75
75
|
# Clean everything that comes from the Thor gempath and remove the caller.
|
76
76
|
#
|
77
|
-
def sans_backtrace(backtrace, caller)
|
77
|
+
def sans_backtrace(backtrace, caller) #:nodoc:
|
78
78
|
dirname = /^#{Regexp.escape(File.dirname(__FILE__))}/
|
79
79
|
saned = backtrace.reject { |frame| frame =~ dirname }
|
80
80
|
saned -= caller
|
81
81
|
end
|
82
82
|
|
83
|
-
def parse_argument_error(instance, e, caller)
|
83
|
+
def parse_argument_error(instance, e, caller) #:nodoc:
|
84
84
|
backtrace = sans_backtrace(e.backtrace, caller)
|
85
85
|
|
86
86
|
if backtrace.empty? && e.message =~ /wrong number of arguments/
|
@@ -95,7 +95,7 @@ class Thor
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
def parse_no_method_error(instance, e)
|
98
|
+
def parse_no_method_error(instance, e) #:nodoc:
|
99
99
|
if e.message =~ /^undefined method `#{name}' for #{Regexp.escape(instance.to_s)}$/
|
100
100
|
raise UndefinedTaskError, "The #{instance.class.namespace} namespace " <<
|
101
101
|
"doesn't have a '#{name}' task"
|
data/lib/thor/tasks/install.rb
CHANGED
data/lib/thor/tasks/package.rb
CHANGED
data/lib/thor/tasks/spec.rb
CHANGED
@@ -15,12 +15,12 @@ class Thor
|
|
15
15
|
#
|
16
16
|
# All other options are added to rspec.
|
17
17
|
#
|
18
|
-
def self.spec_task(files, options={})
|
18
|
+
def self.spec_task(files, options={}) #:nodoc:
|
19
19
|
name = (options.delete(:name) || 'spec').to_s
|
20
20
|
tasks[name] = Thor::SpecTask.new(name, files, options)
|
21
21
|
end
|
22
22
|
|
23
|
-
class SpecTask < Task
|
23
|
+
class SpecTask < Task #:nodoc:
|
24
24
|
attr_accessor :name, :files, :rcov_dir, :rcov_config, :spec_config
|
25
25
|
|
26
26
|
def initialize(name, files, config={})
|
data/lib/thor/util.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'rbconfig'
|
2
2
|
|
3
3
|
class Thor
|
4
|
-
module Sandbox
|
4
|
+
module Sandbox #:nodoc:
|
5
|
+
end
|
5
6
|
|
6
7
|
# This module holds several utilities:
|
7
8
|
#
|
@@ -214,7 +215,7 @@ class Thor
|
|
214
215
|
# Return the path to the ruby interpreter taking into account multiple
|
215
216
|
# installations and windows extensions.
|
216
217
|
#
|
217
|
-
def self.ruby_command
|
218
|
+
def self.ruby_command
|
218
219
|
@ruby_command ||= begin
|
219
220
|
ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
|
220
221
|
ruby << Config::CONFIG['EXEEXT']
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wycats-thor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.4
|
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-08-03 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -21,11 +21,11 @@ executables:
|
|
21
21
|
extensions: []
|
22
22
|
|
23
23
|
extra_rdoc_files:
|
24
|
-
- README.
|
24
|
+
- README.rdoc
|
25
25
|
- LICENSE
|
26
26
|
- CHANGELOG.rdoc
|
27
27
|
files:
|
28
|
-
- README.
|
28
|
+
- README.rdoc
|
29
29
|
- LICENSE
|
30
30
|
- CHANGELOG.rdoc
|
31
31
|
- Rakefile
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/thor/task.rb
|
68
68
|
has_rdoc: true
|
69
69
|
homepage: http://yehudakatz.com
|
70
|
+
licenses:
|
70
71
|
post_install_message:
|
71
72
|
rdoc_options: []
|
72
73
|
|
@@ -87,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
88
|
requirements: []
|
88
89
|
|
89
90
|
rubyforge_project: thor
|
90
|
-
rubygems_version: 1.
|
91
|
+
rubygems_version: 1.3.5
|
91
92
|
signing_key:
|
92
93
|
specification_version: 3
|
93
94
|
summary: A scripting framework that replaces rake, sake and rubigen
|