thor 0.18.1 → 0.19.0
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.
- checksums.yaml +7 -0
- data/README.md +13 -7
- data/Thorfile +4 -5
- data/bin/thor +1 -1
- data/lib/thor.rb +78 -67
- data/lib/thor/actions.rb +57 -56
- data/lib/thor/actions/create_file.rb +33 -35
- data/lib/thor/actions/create_link.rb +2 -3
- data/lib/thor/actions/directory.rb +37 -38
- data/lib/thor/actions/empty_directory.rb +67 -69
- data/lib/thor/actions/file_manipulation.rb +17 -15
- data/lib/thor/actions/inject_into_file.rb +27 -29
- data/lib/thor/base.rb +193 -189
- data/lib/thor/command.rb +20 -23
- data/lib/thor/core_ext/hash_with_indifferent_access.rb +21 -24
- data/lib/thor/core_ext/io_binary_read.rb +2 -4
- data/lib/thor/core_ext/ordered_hash.rb +9 -11
- data/lib/thor/error.rb +5 -1
- data/lib/thor/group.rb +53 -54
- data/lib/thor/invocation.rb +44 -38
- data/lib/thor/line_editor.rb +17 -0
- data/lib/thor/line_editor/basic.rb +35 -0
- data/lib/thor/line_editor/readline.rb +88 -0
- data/lib/thor/parser.rb +4 -4
- data/lib/thor/parser/argument.rb +28 -29
- data/lib/thor/parser/arguments.rb +102 -98
- data/lib/thor/parser/option.rb +26 -22
- data/lib/thor/parser/options.rb +86 -86
- data/lib/thor/rake_compat.rb +9 -10
- data/lib/thor/runner.rb +141 -141
- data/lib/thor/shell.rb +27 -34
- data/lib/thor/shell/basic.rb +91 -63
- data/lib/thor/shell/color.rb +44 -43
- data/lib/thor/shell/html.rb +59 -60
- data/lib/thor/util.rb +24 -27
- data/lib/thor/version.rb +1 -1
- data/spec/actions/create_file_spec.rb +25 -27
- data/spec/actions/create_link_spec.rb +19 -18
- data/spec/actions/directory_spec.rb +31 -31
- data/spec/actions/empty_directory_spec.rb +18 -18
- data/spec/actions/file_manipulation_spec.rb +38 -28
- data/spec/actions/inject_into_file_spec.rb +13 -13
- data/spec/actions_spec.rb +43 -43
- data/spec/base_spec.rb +45 -38
- data/spec/command_spec.rb +13 -14
- data/spec/core_ext/hash_with_indifferent_access_spec.rb +19 -19
- data/spec/core_ext/ordered_hash_spec.rb +6 -6
- data/spec/exit_condition_spec.rb +4 -4
- data/spec/fixtures/invoke.thor +19 -0
- data/spec/fixtures/script.thor +1 -1
- data/spec/group_spec.rb +30 -24
- data/spec/helper.rb +28 -15
- data/spec/invocation_spec.rb +39 -19
- data/spec/line_editor/basic_spec.rb +28 -0
- data/spec/line_editor/readline_spec.rb +69 -0
- data/spec/line_editor_spec.rb +43 -0
- data/spec/parser/argument_spec.rb +12 -12
- data/spec/parser/arguments_spec.rb +11 -11
- data/spec/parser/option_spec.rb +33 -25
- data/spec/parser/options_spec.rb +66 -52
- data/spec/quality_spec.rb +75 -0
- data/spec/rake_compat_spec.rb +10 -10
- data/spec/register_spec.rb +60 -30
- data/spec/runner_spec.rb +67 -62
- data/spec/sandbox/application.rb +2 -0
- data/spec/sandbox/app{1}/README +3 -0
- data/spec/sandbox/bundle/execute.rb +6 -0
- data/spec/sandbox/bundle/main.thor +1 -0
- data/spec/sandbox/command.thor +10 -0
- data/spec/sandbox/doc/%file_name%.rb.tt +1 -0
- data/spec/sandbox/doc/COMMENTER +11 -0
- data/spec/sandbox/doc/README +3 -0
- data/spec/sandbox/doc/block_helper.rb +3 -0
- data/spec/sandbox/doc/config.rb +1 -0
- data/spec/sandbox/doc/config.yaml.tt +1 -0
- data/spec/sandbox/doc/excluding/%file_name%.rb.tt +1 -0
- data/spec/sandbox/enum.thor +10 -0
- data/spec/sandbox/group.thor +128 -0
- data/spec/sandbox/invoke.thor +131 -0
- data/spec/sandbox/path with spaces b/data/spec/sandbox/path with → spaces +0 -0
- data/spec/sandbox/preserve/script.sh +3 -0
- data/spec/sandbox/script.thor +220 -0
- data/spec/sandbox/subcommand.thor +17 -0
- data/spec/shell/basic_spec.rb +107 -86
- data/spec/shell/color_spec.rb +32 -8
- data/spec/shell/html_spec.rb +3 -4
- data/spec/shell_spec.rb +7 -7
- data/spec/subcommand_spec.rb +20 -2
- data/spec/thor_spec.rb +111 -97
- data/spec/util_spec.rb +30 -30
- data/thor.gemspec +14 -14
- metadata +69 -25
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e171d5182116b3c46ec1cf9207ca4e95c9412a6
|
4
|
+
data.tar.gz: dec1d983eca1b3b1eefe3102dee412ef4305c609
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 496ebeb3755de7ad56efab9b8686a3b84f22d8c9592b891a8a9434939d49015b2b36d315c22258b51496b482f65a7b591acf4275484209a37787b67642ff7ac4
|
7
|
+
data.tar.gz: 195addb56fb393d916eecd4b8cdeb64536c6fa50b5d413a89c39f6b6838e0b137946acae37f48804208c041f8432fa759eaa1c455c21fa13662eb365980fae53
|
data/README.md
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
-
[](https://rubygems.org/gems/thor)
|
2
|
-
[](http://travis-ci.org/wycats/thor)
|
3
|
-
[](https://gemnasium.com/wycats/thor)
|
4
|
-
[](https://codeclimate.com/github/wycats/thor)
|
5
|
-
[](https://coveralls.io/r/wycats/thor)
|
6
|
-
|
7
1
|
Thor
|
8
2
|
====
|
9
3
|
|
4
|
+
[][gem]
|
5
|
+
[][travis]
|
6
|
+
[][gemnasium]
|
7
|
+
[][codeclimate]
|
8
|
+
[][coveralls]
|
9
|
+
|
10
|
+
[gem]: https://rubygems.org/gems/thor
|
11
|
+
[travis]: http://travis-ci.org/erikhuda/thor
|
12
|
+
[gemnasium]: https://gemnasium.com/erikhuda/thor
|
13
|
+
[codeclimate]: https://codeclimate.com/github/erikhuda/thor
|
14
|
+
[coveralls]: https://coveralls.io/r/erikhuda/thor
|
15
|
+
|
10
16
|
Description
|
11
17
|
-----------
|
12
18
|
Thor is a simple and efficient tool for building self-documenting command line
|
@@ -25,7 +31,7 @@ Usage and documentation
|
|
25
31
|
-----------------------
|
26
32
|
Please see the [wiki][] for basic usage and other documentation on using Thor. You can also checkout the [official homepage][homepage].
|
27
33
|
|
28
|
-
[wiki]: https://github.com/
|
34
|
+
[wiki]: https://github.com/erikhuda/thor/wiki
|
29
35
|
[homepage]: http://whatisthor.com/
|
30
36
|
|
31
37
|
License
|
data/Thorfile
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
$:.unshift File.expand_path("../lib", __FILE__)
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
3
2
|
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "bundler"
|
4
|
+
require "thor/rake_compat"
|
6
5
|
|
7
6
|
class Default < Thor
|
8
7
|
include Thor::RakeCompat
|
@@ -25,6 +24,6 @@ class Default < Thor
|
|
25
24
|
|
26
25
|
desc "spec", "Run RSpec code examples"
|
27
26
|
def spec
|
28
|
-
exec "rspec
|
27
|
+
exec "rspec spec"
|
29
28
|
end
|
30
29
|
end
|
data/bin/thor
CHANGED
data/lib/thor.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "set"
|
2
|
+
require "thor/base"
|
3
3
|
|
4
|
-
class Thor
|
4
|
+
class Thor # rubocop:disable ClassLength
|
5
5
|
class << self
|
6
6
|
# Allows for custom "Command" package naming.
|
7
7
|
#
|
@@ -9,8 +9,8 @@ class Thor
|
|
9
9
|
# name<String>
|
10
10
|
# options<Hash>
|
11
11
|
#
|
12
|
-
def package_name(name, options={})
|
13
|
-
@package_name = name.nil? || name ==
|
12
|
+
def package_name(name, options = {})
|
13
|
+
@package_name = name.nil? || name == "" ? nil : name
|
14
14
|
end
|
15
15
|
|
16
16
|
# Sets the default command when thor is executed without an explicit command to be called.
|
@@ -18,17 +18,14 @@ class Thor
|
|
18
18
|
# ==== Parameters
|
19
19
|
# meth<Symbol>:: name of the default command
|
20
20
|
#
|
21
|
-
def default_command(meth=nil)
|
22
|
-
|
23
|
-
|
24
|
-
'help'
|
25
|
-
when nil
|
26
|
-
@default_command || from_superclass(:default_command, 'help')
|
21
|
+
def default_command(meth = nil)
|
22
|
+
if meth
|
23
|
+
@default_command = meth == :none ? "help" : meth.to_s
|
27
24
|
else
|
28
|
-
|
25
|
+
@default_command ||= from_superclass(:default_command, "help")
|
29
26
|
end
|
30
27
|
end
|
31
|
-
|
28
|
+
alias_method :default_task, :default_command
|
32
29
|
|
33
30
|
# Registers another Thor subclass as a command.
|
34
31
|
#
|
@@ -37,7 +34,7 @@ class Thor
|
|
37
34
|
# command<String>:: Subcommand name to use
|
38
35
|
# usage<String>:: Short usage for the subcommand
|
39
36
|
# description<String>:: Description for the subcommand
|
40
|
-
def register(klass, subcommand_name, usage, description, options={})
|
37
|
+
def register(klass, subcommand_name, usage, description, options = {})
|
41
38
|
if klass <= Thor::Group
|
42
39
|
desc usage, description, options
|
43
40
|
define_method(subcommand_name) { |*args| invoke(klass, args) }
|
@@ -54,7 +51,7 @@ class Thor
|
|
54
51
|
# description<String>
|
55
52
|
# options<String>
|
56
53
|
#
|
57
|
-
def desc(usage, description, options={})
|
54
|
+
def desc(usage, description, options = {})
|
58
55
|
if options[:for]
|
59
56
|
command = find_and_refresh_command(options[:for])
|
60
57
|
command.usage = usage if usage
|
@@ -69,7 +66,7 @@ class Thor
|
|
69
66
|
# ==== Parameters
|
70
67
|
# long description<String>
|
71
68
|
#
|
72
|
-
def long_desc(long_description, options={})
|
69
|
+
def long_desc(long_description, options = {})
|
73
70
|
if options[:for]
|
74
71
|
command = find_and_refresh_command(options[:for])
|
75
72
|
command.long_description = long_description if long_description
|
@@ -91,13 +88,13 @@ class Thor
|
|
91
88
|
# ==== Parameters
|
92
89
|
# Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
|
93
90
|
#
|
94
|
-
def map(mappings=nil)
|
91
|
+
def map(mappings = nil)
|
95
92
|
@map ||= from_superclass(:map, {})
|
96
93
|
|
97
94
|
if mappings
|
98
95
|
mappings.each do |key, value|
|
99
96
|
if key.respond_to?(:each)
|
100
|
-
key.each {|subkey| @map[subkey] = value}
|
97
|
+
key.each { |subkey| @map[subkey] = value }
|
101
98
|
else
|
102
99
|
@map[key] = value
|
103
100
|
end
|
@@ -114,13 +111,13 @@ class Thor
|
|
114
111
|
# is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
|
115
112
|
# or :required (string). If you give a value, the type of the value is used.
|
116
113
|
#
|
117
|
-
def method_options(options=nil)
|
114
|
+
def method_options(options = nil)
|
118
115
|
@method_options ||= {}
|
119
116
|
build_options(options, @method_options) if options
|
120
117
|
@method_options
|
121
118
|
end
|
122
119
|
|
123
|
-
|
120
|
+
alias_method :options, :method_options
|
124
121
|
|
125
122
|
# Adds an option to the set of method options. If :for is given as option,
|
126
123
|
# it allows you to change the options from a previous defined command.
|
@@ -148,7 +145,7 @@ class Thor
|
|
148
145
|
# :banner - String to show on usage notes.
|
149
146
|
# :hide - If you want to hide this option from the help.
|
150
147
|
#
|
151
|
-
def method_option(name, options={})
|
148
|
+
def method_option(name, options = {})
|
152
149
|
scope = if options[:for]
|
153
150
|
find_and_refresh_command(options[:for]).options
|
154
151
|
else
|
@@ -157,7 +154,7 @@ class Thor
|
|
157
154
|
|
158
155
|
build_option(name, options, scope)
|
159
156
|
end
|
160
|
-
|
157
|
+
alias_method :option, :method_option
|
161
158
|
|
162
159
|
# Prints help information for the given command.
|
163
160
|
#
|
@@ -181,7 +178,7 @@ class Thor
|
|
181
178
|
shell.say command.description
|
182
179
|
end
|
183
180
|
end
|
184
|
-
|
181
|
+
alias_method :task_help, :command_help
|
185
182
|
|
186
183
|
# Prints help information for this class.
|
187
184
|
#
|
@@ -193,9 +190,9 @@ class Thor
|
|
193
190
|
Thor::Util.thor_classes_in(self).each do |klass|
|
194
191
|
list += klass.printable_commands(false)
|
195
192
|
end
|
196
|
-
list.sort!{ |a,b| a[0] <=> b[0] }
|
193
|
+
list.sort! { |a, b| a[0] <=> b[0] }
|
197
194
|
|
198
|
-
if @package_name
|
195
|
+
if defined?(@package_name) && @package_name
|
199
196
|
shell.say "#{@package_name} commands:"
|
200
197
|
else
|
201
198
|
shell.say "Commands:"
|
@@ -212,34 +209,40 @@ class Thor
|
|
212
209
|
next if command.hidden?
|
213
210
|
item = []
|
214
211
|
item << banner(command, false, subcommand)
|
215
|
-
item << (command.description ? "# #{command.description.gsub(/\s+/m,' ')}" : "")
|
212
|
+
item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "")
|
216
213
|
item
|
217
214
|
end.compact
|
218
215
|
end
|
219
|
-
|
216
|
+
alias_method :printable_tasks, :printable_commands
|
220
217
|
|
221
218
|
def subcommands
|
222
219
|
@subcommands ||= from_superclass(:subcommands, [])
|
223
220
|
end
|
224
|
-
|
221
|
+
alias_method :subtasks, :subcommands
|
222
|
+
|
223
|
+
def subcommand_classes
|
224
|
+
@subcommand_classes ||= {}
|
225
|
+
end
|
225
226
|
|
226
227
|
def subcommand(subcommand, subcommand_class)
|
227
|
-
|
228
|
+
subcommands << subcommand.to_s
|
228
229
|
subcommand_class.subcommand_help subcommand
|
230
|
+
subcommand_classes[subcommand.to_s] = subcommand_class
|
229
231
|
|
230
232
|
define_method(subcommand) do |*args|
|
231
233
|
args, opts = Thor::Arguments.split(args)
|
234
|
+
args.unshift("help") if opts.include? "--help" or opts.include? "-h"
|
232
235
|
invoke subcommand_class, args, opts, :invoked_via_subcommand => true, :class_options => options
|
233
236
|
end
|
234
237
|
end
|
235
|
-
|
238
|
+
alias_method :subtask, :subcommand
|
236
239
|
|
237
240
|
# Extend check unknown options to accept a hash of conditions.
|
238
241
|
#
|
239
242
|
# === Parameters
|
240
243
|
# options<Hash>: A hash containing :only and/or :except keys
|
241
|
-
def check_unknown_options!(options={})
|
242
|
-
@check_unknown_options ||=
|
244
|
+
def check_unknown_options!(options = {})
|
245
|
+
@check_unknown_options ||= {}
|
243
246
|
options.each do |key, value|
|
244
247
|
if value
|
245
248
|
@check_unknown_options[key] = Array(value)
|
@@ -309,35 +312,28 @@ class Thor
|
|
309
312
|
# ==== Parameters
|
310
313
|
# Symbol ...:: A list of commands that should be affected.
|
311
314
|
def stop_on_unknown_option!(*command_names)
|
312
|
-
|
313
|
-
@stop_on_unknown_option.merge(command_names)
|
315
|
+
stop_on_unknown_option.merge(command_names)
|
314
316
|
end
|
315
317
|
|
316
318
|
def stop_on_unknown_option?(command) #:nodoc:
|
317
|
-
|
319
|
+
command && stop_on_unknown_option.include?(command.name.to_sym)
|
318
320
|
end
|
319
321
|
|
320
322
|
protected
|
323
|
+
def stop_on_unknown_option #:nodoc:
|
324
|
+
@stop_on_unknown_option ||= Set.new
|
325
|
+
end
|
321
326
|
|
322
327
|
# The method responsible for dispatching given the args.
|
323
|
-
def dispatch(meth, given_args, given_opts, config) #:nodoc:
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
# a command then use the default command. The given_args will be
|
333
|
-
# intact later since dup was used.
|
334
|
-
if config[:invoked_via_subcommand] && given_args.size >= 1 && default_command != "help" && given_args.first != default_command
|
335
|
-
meth ||= retrieve_command_name(given_args.dup)
|
336
|
-
command = all_commands[normalize_command_name(meth)]
|
337
|
-
command ||= all_commands[normalize_command_name(default_command)]
|
338
|
-
else
|
339
|
-
meth ||= retrieve_command_name(given_args)
|
340
|
-
command = all_commands[normalize_command_name(meth)]
|
328
|
+
def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
|
329
|
+
meth ||= retrieve_command_name(given_args)
|
330
|
+
command = all_commands[normalize_command_name(meth)]
|
331
|
+
|
332
|
+
if !command && config[:invoked_via_subcommand]
|
333
|
+
# We're a subcommand and our first argument didn't match any of our
|
334
|
+
# commands. So we put it back and call our default command.
|
335
|
+
given_args.unshift(meth)
|
336
|
+
command = all_commands[normalize_command_name(default_command)]
|
341
337
|
end
|
342
338
|
|
343
339
|
if command
|
@@ -350,7 +346,7 @@ class Thor
|
|
350
346
|
end
|
351
347
|
else
|
352
348
|
args, opts = given_args, nil
|
353
|
-
command =
|
349
|
+
command = dynamic_command_class.new(meth)
|
354
350
|
end
|
355
351
|
|
356
352
|
opts = given_opts || opts || []
|
@@ -376,13 +372,21 @@ class Thor
|
|
376
372
|
Thor
|
377
373
|
end
|
378
374
|
|
375
|
+
def dynamic_command_class #:nodoc:
|
376
|
+
Thor::DynamicCommand
|
377
|
+
end
|
378
|
+
|
379
379
|
def create_command(meth) #:nodoc:
|
380
|
+
@usage ||= nil
|
381
|
+
@desc ||= nil
|
382
|
+
@long_desc ||= nil
|
383
|
+
|
380
384
|
if @usage && @desc
|
381
385
|
base_class = @hide ? Thor::HiddenCommand : Thor::Command
|
382
386
|
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
|
383
387
|
@usage, @desc, @long_desc, @method_options, @hide = nil
|
384
388
|
true
|
385
|
-
elsif
|
389
|
+
elsif all_commands[meth] || meth == "method_missing"
|
386
390
|
true
|
387
391
|
else
|
388
392
|
puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " <<
|
@@ -391,7 +395,7 @@ class Thor
|
|
391
395
|
false
|
392
396
|
end
|
393
397
|
end
|
394
|
-
|
398
|
+
alias_method :create_task, :create_command
|
395
399
|
|
396
400
|
def initialize_added #:nodoc:
|
397
401
|
class_options.merge!(method_options)
|
@@ -407,7 +411,7 @@ class Thor
|
|
407
411
|
nil
|
408
412
|
end
|
409
413
|
end
|
410
|
-
|
414
|
+
alias_method :retrieve_task_name, :retrieve_command_name
|
411
415
|
|
412
416
|
# receives a (possibly nil) command name and returns a name that is in
|
413
417
|
# the commands hash. In addition to normalizing aliases, this logic
|
@@ -417,11 +421,11 @@ class Thor
|
|
417
421
|
# +normalize_command_name+ also converts names like +animal-prison+
|
418
422
|
# into +animal_prison+.
|
419
423
|
def normalize_command_name(meth) #:nodoc:
|
420
|
-
return default_command.to_s.gsub(
|
424
|
+
return default_command.to_s.gsub("-", "_") unless meth
|
421
425
|
|
422
426
|
possibilities = find_command_possibilities(meth)
|
423
427
|
if possibilities.size > 1
|
424
|
-
|
428
|
+
fail AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]"
|
425
429
|
elsif possibilities.size < 1
|
426
430
|
meth = meth || default_command
|
427
431
|
elsif map[meth]
|
@@ -430,9 +434,9 @@ class Thor
|
|
430
434
|
meth = possibilities.first
|
431
435
|
end
|
432
436
|
|
433
|
-
meth.to_s.gsub(
|
437
|
+
meth.to_s.gsub("-", "_") # treat foo-bar as foo_bar
|
434
438
|
end
|
435
|
-
|
439
|
+
alias_method :normalize_task_name, :normalize_command_name
|
436
440
|
|
437
441
|
# this is the logic that takes the command name passed in by the user
|
438
442
|
# and determines whether it is an unambiguous substrings of a command or
|
@@ -450,16 +454,15 @@ class Thor
|
|
450
454
|
possibilities
|
451
455
|
end
|
452
456
|
end
|
453
|
-
|
457
|
+
alias_method :find_task_possibilities, :find_command_possibilities
|
454
458
|
|
455
459
|
def subcommand_help(cmd)
|
456
460
|
desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
|
457
|
-
class_eval
|
461
|
+
class_eval "
|
458
462
|
def help(command = nil, subcommand = true); super; end
|
459
|
-
|
463
|
+
"
|
460
464
|
end
|
461
|
-
|
462
|
-
|
465
|
+
alias_method :subtask_help, :subcommand_help
|
463
466
|
end
|
464
467
|
|
465
468
|
include Thor::Base
|
@@ -468,6 +471,14 @@ class Thor
|
|
468
471
|
|
469
472
|
desc "help [COMMAND]", "Describe available commands or one specific command"
|
470
473
|
def help(command = nil, subcommand = false)
|
471
|
-
|
474
|
+
if command
|
475
|
+
if self.class.subcommands.include? command
|
476
|
+
self.class.subcommand_classes[command].help(shell, true)
|
477
|
+
else
|
478
|
+
self.class.command_help(shell, command)
|
479
|
+
end
|
480
|
+
else
|
481
|
+
self.class.help(shell, subcommand)
|
482
|
+
end
|
472
483
|
end
|
473
484
|
end
|
data/lib/thor/actions.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
1
|
+
require "fileutils"
|
2
|
+
require "uri"
|
3
|
+
require "thor/core_ext/io_binary_read"
|
4
|
+
require "thor/actions/create_file"
|
5
|
+
require "thor/actions/create_link"
|
6
|
+
require "thor/actions/directory"
|
7
|
+
require "thor/actions/empty_directory"
|
8
|
+
require "thor/actions/file_manipulation"
|
9
|
+
require "thor/actions/inject_into_file"
|
10
10
|
|
11
11
|
class Thor
|
12
12
|
module Actions
|
@@ -26,9 +26,9 @@ class Thor
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# Stores and return the source root for this class
|
29
|
-
def source_root(path=nil)
|
29
|
+
def source_root(path = nil)
|
30
30
|
@_source_root = path if path
|
31
|
-
@_source_root
|
31
|
+
@_source_root ||= nil
|
32
32
|
end
|
33
33
|
|
34
34
|
# Returns the source paths in the following order:
|
@@ -39,8 +39,8 @@ class Thor
|
|
39
39
|
#
|
40
40
|
def source_paths_for_search
|
41
41
|
paths = []
|
42
|
-
paths +=
|
43
|
-
paths <<
|
42
|
+
paths += source_paths
|
43
|
+
paths << source_root if source_root
|
44
44
|
paths += from_superclass(:source_paths, [])
|
45
45
|
paths
|
46
46
|
end
|
@@ -71,17 +71,16 @@ class Thor
|
|
71
71
|
#
|
72
72
|
# destination_root<String>:: The root directory needed for some actions.
|
73
73
|
#
|
74
|
-
def initialize(args=[], options={}, config={})
|
74
|
+
def initialize(args = [], options = {}, config = {})
|
75
75
|
self.behavior = case config[:behavior].to_s
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
76
|
+
when "force", "skip"
|
77
|
+
_cleanup_options_and_set(options, config[:behavior])
|
78
|
+
:invoke
|
79
|
+
when "revoke"
|
80
|
+
:revoke
|
81
|
+
else
|
82
|
+
:invoke
|
83
|
+
end
|
85
84
|
super
|
86
85
|
self.destination_root = config[:destination_root]
|
87
86
|
end
|
@@ -107,16 +106,16 @@ class Thor
|
|
107
106
|
#
|
108
107
|
def destination_root=(root)
|
109
108
|
@destination_stack ||= []
|
110
|
-
@destination_stack[0] = File.expand_path(root ||
|
109
|
+
@destination_stack[0] = File.expand_path(root || "")
|
111
110
|
end
|
112
111
|
|
113
112
|
# Returns the given path relative to the absolute root (ie, root where
|
114
113
|
# the script started).
|
115
114
|
#
|
116
|
-
def relative_to_original_destination_root(path, remove_dot=true)
|
115
|
+
def relative_to_original_destination_root(path, remove_dot = true)
|
117
116
|
path = path.dup
|
118
|
-
if path.gsub!(@destination_stack[0],
|
119
|
-
remove_dot ? (path[2..-1] ||
|
117
|
+
if path.gsub!(@destination_stack[0], ".")
|
118
|
+
remove_dot ? (path[2..-1] || "") : path
|
120
119
|
else
|
121
120
|
path
|
122
121
|
end
|
@@ -130,12 +129,15 @@ class Thor
|
|
130
129
|
|
131
130
|
# Receives a file or directory and search for it in the source paths.
|
132
131
|
#
|
133
|
-
def find_in_source_paths(file)
|
132
|
+
def find_in_source_paths(file) # rubocop:disable MethodLength
|
133
|
+
possible_files = [file, file + TEMPLATE_EXTNAME]
|
134
134
|
relative_root = relative_to_original_destination_root(destination_root, false)
|
135
135
|
|
136
136
|
source_paths.each do |source|
|
137
|
-
|
138
|
-
|
137
|
+
possible_files.each do |f|
|
138
|
+
source_file = File.expand_path(f, File.join(source, relative_root))
|
139
|
+
return source_file if File.exist?(source_file)
|
140
|
+
end
|
139
141
|
end
|
140
142
|
|
141
143
|
message = "Could not find #{file.inspect} in any of your source paths. "
|
@@ -150,7 +152,7 @@ class Thor
|
|
150
152
|
message << "Your current source paths are: \n#{source_paths.join("\n")}"
|
151
153
|
end
|
152
154
|
|
153
|
-
|
155
|
+
fail Error, message
|
154
156
|
end
|
155
157
|
|
156
158
|
# Do something in the root or on a provided subfolder. If a relative path
|
@@ -162,7 +164,7 @@ class Thor
|
|
162
164
|
# dir<String>:: the directory to move to.
|
163
165
|
# config<Hash>:: give :verbose => true to log and use padding.
|
164
166
|
#
|
165
|
-
def inside(dir=
|
167
|
+
def inside(dir = "", config = {}, &block)
|
166
168
|
verbose = config.fetch(:verbose, false)
|
167
169
|
pretend = options[:pretend]
|
168
170
|
|
@@ -204,18 +206,18 @@ class Thor
|
|
204
206
|
#
|
205
207
|
# apply "recipes/jquery.rb"
|
206
208
|
#
|
207
|
-
def apply(path, config={})
|
209
|
+
def apply(path, config = {})
|
208
210
|
verbose = config.fetch(:verbose, true)
|
209
|
-
is_uri = path =~
|
211
|
+
is_uri = path =~ %r{^https?\://}
|
210
212
|
path = find_in_source_paths(path) unless is_uri
|
211
213
|
|
212
214
|
say_status :apply, path, verbose
|
213
215
|
shell.padding += 1 if verbose
|
214
216
|
|
215
217
|
if is_uri
|
216
|
-
contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
|
218
|
+
contents = open(path, "Accept" => "application/x-thor-template") { |io| io.read }
|
217
219
|
else
|
218
|
-
contents = open(path) {|io| io.read }
|
220
|
+
contents = open(path) { |io| io.read }
|
219
221
|
end
|
220
222
|
|
221
223
|
instance_eval(contents, path)
|
@@ -227,7 +229,7 @@ class Thor
|
|
227
229
|
# ==== Parameters
|
228
230
|
# command<String>:: the command to be executed.
|
229
231
|
# config<Hash>:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with
|
230
|
-
# to append an executable to command
|
232
|
+
# to append an executable to command execution.
|
231
233
|
#
|
232
234
|
# ==== Example
|
233
235
|
#
|
@@ -235,7 +237,7 @@ class Thor
|
|
235
237
|
# run('ln -s ~/edge rails')
|
236
238
|
# end
|
237
239
|
#
|
238
|
-
def run(command, config={})
|
240
|
+
def run(command, config = {})
|
239
241
|
return unless behavior == :invoke
|
240
242
|
|
241
243
|
destination = relative_to_original_destination_root(destination_root, false)
|
@@ -259,7 +261,7 @@ class Thor
|
|
259
261
|
# command<String>:: the command to be executed.
|
260
262
|
# config<Hash>:: give :verbose => false to not log the status.
|
261
263
|
#
|
262
|
-
def run_ruby_script(command, config={})
|
264
|
+
def run_ruby_script(command, config = {})
|
263
265
|
return unless behavior == :invoke
|
264
266
|
run command, config.merge(:with => Thor::Util.ruby_command)
|
265
267
|
end
|
@@ -290,29 +292,28 @@ class Thor
|
|
290
292
|
|
291
293
|
args.unshift(command)
|
292
294
|
args.push Thor::Options.to_switches(config)
|
293
|
-
command = args.join(
|
295
|
+
command = args.join(" ").strip
|
294
296
|
|
295
297
|
run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
|
296
298
|
end
|
297
299
|
|
298
|
-
|
300
|
+
protected
|
299
301
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
302
|
+
# Allow current root to be shared between invocations.
|
303
|
+
#
|
304
|
+
def _shared_configuration #:nodoc:
|
305
|
+
super.merge!(:destination_root => destination_root)
|
306
|
+
end
|
305
307
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
end
|
308
|
+
def _cleanup_options_and_set(options, key) #:nodoc:
|
309
|
+
case options
|
310
|
+
when Array
|
311
|
+
%w[--force -f --skip -s].each { |i| options.delete(i) }
|
312
|
+
options << "--#{key}"
|
313
|
+
when Hash
|
314
|
+
[:force, :skip, "force", "skip"].each { |i| options.delete(i) }
|
315
|
+
options.merge!(key => true)
|
315
316
|
end
|
316
|
-
|
317
|
+
end
|
317
318
|
end
|
318
319
|
end
|