wycats-thor 0.11.3 → 0.11.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/{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
|