bundler 1.2.0.pre.1 → 1.2.0.rc
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- data/CHANGELOG.md +27 -1
- data/ISSUES.md +3 -3
- data/lib/bundler.rb +7 -5
- data/lib/bundler/cli.rb +17 -20
- data/lib/bundler/definition.rb +5 -0
- data/lib/bundler/dsl.rb +1 -1
- data/lib/bundler/fetcher.rb +5 -6
- data/lib/bundler/gem_path_manipulation.rb +8 -0
- data/lib/bundler/ruby_version.rb +4 -2
- data/lib/bundler/runtime.rb +46 -19
- data/lib/bundler/source.rb +25 -10
- data/lib/bundler/templates/newgem/{LICENSE.tt → LICENSE.txt.tt} +0 -0
- data/lib/bundler/templates/newgem/Rakefile.tt +0 -1
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +6 -4
- data/lib/bundler/vendor/thor.rb +49 -28
- data/lib/bundler/vendor/thor/actions.rb +7 -3
- data/lib/bundler/vendor/thor/actions/create_link.rb +1 -1
- data/lib/bundler/vendor/thor/actions/directory.rb +9 -4
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +24 -5
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +39 -1
- data/lib/bundler/vendor/thor/base.rb +65 -24
- data/lib/bundler/vendor/thor/core_ext/dir_escape.rb +0 -0
- data/lib/bundler/vendor/thor/error.rb +6 -1
- data/lib/bundler/vendor/thor/group.rb +21 -9
- data/lib/bundler/vendor/thor/invocation.rb +4 -2
- data/lib/bundler/vendor/thor/parser/arguments.rb +4 -0
- data/lib/bundler/vendor/thor/parser/option.rb +3 -2
- data/lib/bundler/vendor/thor/parser/options.rb +13 -7
- data/lib/bundler/vendor/thor/rake_compat.rb +13 -8
- data/lib/bundler/vendor/thor/runner.rb +15 -3
- data/lib/bundler/vendor/thor/shell.rb +4 -4
- data/lib/bundler/vendor/thor/shell/basic.rb +169 -82
- data/lib/bundler/vendor/thor/shell/color.rb +40 -4
- data/lib/bundler/vendor/thor/shell/html.rb +28 -26
- data/lib/bundler/vendor/thor/task.rb +24 -5
- data/lib/bundler/vendor/thor/util.rb +43 -6
- data/lib/bundler/vendor/thor/version.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/man/bundle-config.ronn +2 -2
- data/spec/bundler/definition_spec.rb +25 -0
- data/spec/cache/git_spec.rb +47 -0
- data/spec/cache/path_spec.rb +18 -0
- data/spec/install/git_spec.rb +21 -6
- data/spec/lock/lockfile_spec.rb +1 -1
- data/spec/other/check_spec.rb +14 -1
- data/spec/other/newgem_spec.rb +1 -0
- data/spec/other/platform_spec.rb +164 -0
- data/spec/runtime/setup_spec.rb +87 -0
- data/spec/runtime/with_clean_env_spec.rb +14 -0
- metadata +78 -133
File without changes
|
@@ -1,17 +1,19 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require '<%=config[:name]%>/version'
|
3
5
|
|
4
6
|
Gem::Specification.new do |gem|
|
7
|
+
gem.name = <%=config[:name].inspect%>
|
8
|
+
gem.version = <%=config[:constant_name]%>::VERSION
|
5
9
|
gem.authors = [<%=config[:author].inspect%>]
|
6
10
|
gem.email = [<%=config[:email].inspect%>]
|
7
11
|
gem.description = %q{TODO: Write a gem description}
|
8
12
|
gem.summary = %q{TODO: Write a gem summary}
|
9
13
|
gem.homepage = ""
|
10
14
|
|
11
|
-
gem.files = `git ls-files`.split(
|
15
|
+
gem.files = `git ls-files`.split($/)
|
12
16
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
-
gem.name = <%=config[:name].inspect%>
|
15
18
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version = <%=config[:constant_name]%>::VERSION
|
17
19
|
end
|
data/lib/bundler/vendor/thor.rb
CHANGED
@@ -5,7 +5,7 @@ class Thor
|
|
5
5
|
# Sets the default task when thor is executed without an explicit task to be called.
|
6
6
|
#
|
7
7
|
# ==== Parameters
|
8
|
-
# meth<Symbol>:: name of the
|
8
|
+
# meth<Symbol>:: name of the default task
|
9
9
|
#
|
10
10
|
def default_task(meth=nil)
|
11
11
|
case meth
|
@@ -28,7 +28,7 @@ class Thor
|
|
28
28
|
def register(klass, subcommand_name, usage, description, options={})
|
29
29
|
if klass <= Thor::Group
|
30
30
|
desc usage, description, options
|
31
|
-
define_method(subcommand_name) { invoke
|
31
|
+
define_method(subcommand_name) { |*args| invoke(klass, args) }
|
32
32
|
else
|
33
33
|
desc usage, description, options
|
34
34
|
subcommand subcommand_name, klass
|
@@ -108,6 +108,8 @@ class Thor
|
|
108
108
|
@method_options
|
109
109
|
end
|
110
110
|
|
111
|
+
alias options method_options
|
112
|
+
|
111
113
|
# Adds an option to the set of method options. If :for is given as option,
|
112
114
|
# it allows you to change the options from a previous defined task.
|
113
115
|
#
|
@@ -132,6 +134,7 @@ class Thor
|
|
132
134
|
# :aliases - Aliases for this option.
|
133
135
|
# :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
|
134
136
|
# :banner - String to show on usage notes.
|
137
|
+
# :hide - If you want to hide this option from the help.
|
135
138
|
#
|
136
139
|
def method_option(name, options={})
|
137
140
|
scope = if options[:for]
|
@@ -143,6 +146,8 @@ class Thor
|
|
143
146
|
build_option(name, options, scope)
|
144
147
|
end
|
145
148
|
|
149
|
+
alias option method_option
|
150
|
+
|
146
151
|
# Prints help information for the given task.
|
147
152
|
#
|
148
153
|
# ==== Parameters
|
@@ -160,7 +165,7 @@ class Thor
|
|
160
165
|
class_options_help(shell, nil => task.options.map { |_, o| o })
|
161
166
|
if task.long_description
|
162
167
|
shell.say "Description:"
|
163
|
-
shell.print_wrapped(task.long_description, :
|
168
|
+
shell.print_wrapped(task.long_description, :indent => 2)
|
164
169
|
else
|
165
170
|
shell.say task.description
|
166
171
|
end
|
@@ -179,7 +184,7 @@ class Thor
|
|
179
184
|
list.sort!{ |a,b| a[0] <=> b[0] }
|
180
185
|
|
181
186
|
shell.say "Tasks:"
|
182
|
-
shell.print_table(list, :
|
187
|
+
shell.print_table(list, :indent => 2, :truncate => true)
|
183
188
|
shell.say
|
184
189
|
class_options_help(shell)
|
185
190
|
end
|
@@ -202,7 +207,11 @@ class Thor
|
|
202
207
|
def subcommand(subcommand, subcommand_class)
|
203
208
|
self.subcommands << subcommand.to_s
|
204
209
|
subcommand_class.subcommand_help subcommand
|
205
|
-
|
210
|
+
|
211
|
+
define_method(subcommand) do |*args|
|
212
|
+
args, opts = Thor::Arguments.split(args)
|
213
|
+
invoke subcommand_class, args, opts
|
214
|
+
end
|
206
215
|
end
|
207
216
|
|
208
217
|
# Extend check unknown options to accept a hash of conditions.
|
@@ -259,8 +268,11 @@ class Thor
|
|
259
268
|
opts = given_opts || opts || []
|
260
269
|
config.merge!(:current_task => task, :task_options => task.options)
|
261
270
|
|
271
|
+
instance = new(args, opts, config)
|
272
|
+
yield instance if block_given?
|
273
|
+
args = instance.args
|
262
274
|
trailing = args[Range.new(arguments.size, -1)]
|
263
|
-
|
275
|
+
instance.invoke_task(task, trailing || [])
|
264
276
|
end
|
265
277
|
|
266
278
|
# The banner for this class. You can customize it if you are invoking the
|
@@ -300,7 +312,6 @@ class Thor
|
|
300
312
|
# Retrieve the task name from given args.
|
301
313
|
def retrieve_task_name(args) #:nodoc:
|
302
314
|
meth = args.first.to_s unless args.empty?
|
303
|
-
|
304
315
|
if meth && (map[meth] || meth !~ /^\-/)
|
305
316
|
args.shift
|
306
317
|
else
|
@@ -308,35 +319,45 @@ class Thor
|
|
308
319
|
end
|
309
320
|
end
|
310
321
|
|
311
|
-
#
|
312
|
-
#
|
322
|
+
# receives a (possibly nil) task name and returns a name that is in
|
323
|
+
# the tasks hash. In addition to normalizing aliases, this logic
|
324
|
+
# will determine if a shortened command is an unambiguous prefix of
|
325
|
+
# a task or alias.
|
326
|
+
#
|
327
|
+
# +normalize_task_name+ also converts names like +animal-prison+
|
328
|
+
# into +animal_prison+.
|
313
329
|
def normalize_task_name(meth) #:nodoc:
|
314
|
-
|
315
|
-
meth.to_s.gsub('-','_') # treat foo-bar > foo_bar
|
316
|
-
end
|
317
|
-
|
318
|
-
# terrible hack that overwrites ARGV
|
319
|
-
def find_subcommand_and_update_argv(subcmd_name) #:nodoc:
|
320
|
-
return unless subcmd_name
|
321
|
-
cmd = find_subcommand(subcmd_name)
|
322
|
-
ARGV[0] = cmd if cmd
|
323
|
-
cmd
|
324
|
-
end
|
330
|
+
return default_task.to_s.gsub('-', '_') unless meth
|
325
331
|
|
326
|
-
|
327
|
-
possibilities = find_subcommand_possibilities subcmd_name
|
332
|
+
possibilities = find_task_possibilities(meth)
|
328
333
|
if possibilities.size > 1
|
329
|
-
raise "Ambiguous
|
334
|
+
raise ArgumentError, "Ambiguous task #{meth} matches [#{possibilities.join(', ')}]"
|
330
335
|
elsif possibilities.size < 1
|
331
|
-
|
336
|
+
meth = meth || default_task
|
337
|
+
elsif map[meth]
|
338
|
+
meth = map[meth]
|
339
|
+
else
|
340
|
+
meth = possibilities.first
|
332
341
|
end
|
333
342
|
|
334
|
-
|
343
|
+
meth.to_s.gsub('-','_') # treat foo-bar as foo_bar
|
335
344
|
end
|
336
345
|
|
337
|
-
|
338
|
-
|
339
|
-
|
346
|
+
# this is the logic that takes the task name passed in by the user
|
347
|
+
# and determines whether it is an unambiguous prefix of a task or
|
348
|
+
# alias name.
|
349
|
+
def find_task_possibilities(meth)
|
350
|
+
len = meth.to_s.length
|
351
|
+
possibilities = all_tasks.merge(map).keys.select { |n| meth == n[0, len] }.sort
|
352
|
+
unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
|
353
|
+
|
354
|
+
if possibilities.include?(meth)
|
355
|
+
[meth]
|
356
|
+
elsif unique_possibilities.size == 1
|
357
|
+
unique_possibilities
|
358
|
+
else
|
359
|
+
possibilities
|
360
|
+
end
|
340
361
|
end
|
341
362
|
|
342
363
|
def subcommand_help(cmd)
|
@@ -55,7 +55,7 @@ class Thor
|
|
55
55
|
:desc => "Run but do not make any changes"
|
56
56
|
|
57
57
|
class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
|
58
|
-
:desc => "
|
58
|
+
:desc => "Suppress status output"
|
59
59
|
|
60
60
|
class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
|
61
61
|
:desc => "Skip files that already exist"
|
@@ -114,8 +114,12 @@ class Thor
|
|
114
114
|
# the script started).
|
115
115
|
#
|
116
116
|
def relative_to_original_destination_root(path, remove_dot=true)
|
117
|
-
path
|
118
|
-
|
117
|
+
if path =~ /^#{@destination_stack[0]}/
|
118
|
+
path = path.gsub(@destination_stack[0], '.')
|
119
|
+
path = remove_dot ? (path[2..-1] || '') : path
|
120
|
+
end
|
121
|
+
|
122
|
+
path
|
119
123
|
end
|
120
124
|
|
121
125
|
# Holds source paths in instance so they can be manipulated.
|
@@ -41,7 +41,7 @@ class Thor
|
|
41
41
|
invoke_with_conflict_check do
|
42
42
|
FileUtils.mkdir_p(File.dirname(destination))
|
43
43
|
# Create a symlink by default
|
44
|
-
config[:symbolic]
|
44
|
+
config[:symbolic] = true if config[:symbolic].nil?
|
45
45
|
File.unlink(destination) if exists?
|
46
46
|
if config[:symbolic]
|
47
47
|
File.symlink(render, destination)
|
@@ -2,13 +2,13 @@ require 'thor/actions/empty_directory'
|
|
2
2
|
|
3
3
|
class Thor
|
4
4
|
module Actions
|
5
|
-
|
6
5
|
# Copies recursively the files from source directory to root directory.
|
7
6
|
# If any of the files finishes with .tt, it's considered to be a template
|
8
7
|
# and is placed in the destination without the extension .tt. If any
|
9
8
|
# empty directory is found, it's copied and all .empty_directory files are
|
10
|
-
# ignored.
|
11
|
-
#
|
9
|
+
# ignored. If any file name is wrapped within % signs, the text within
|
10
|
+
# the % signs will be executed as a method and replaced with the returned
|
11
|
+
# value. Let's suppose a doc directory with the following files:
|
12
12
|
#
|
13
13
|
# doc/
|
14
14
|
# components/.empty_directory
|
@@ -29,6 +29,10 @@ class Thor
|
|
29
29
|
# rdoc.rb
|
30
30
|
# blog.rb
|
31
31
|
#
|
32
|
+
# <b>Encoded path note:</b> Since Thor internals use Object#respond_to? to check if it can
|
33
|
+
# expand %something%, this `something` should be a public method in the class calling
|
34
|
+
# #directory. If a method is private, Thor stack raises PrivateMethodEncodedError.
|
35
|
+
#
|
32
36
|
# ==== Parameters
|
33
37
|
# source<String>:: the relative path to the source root.
|
34
38
|
# destination<String>:: the relative path to the destination root.
|
@@ -67,7 +71,8 @@ class Thor
|
|
67
71
|
protected
|
68
72
|
|
69
73
|
def execute!
|
70
|
-
lookup =
|
74
|
+
lookup = Util.escape_globs(source)
|
75
|
+
lookup = config[:recursive] ? File.join(lookup, '**') : lookup
|
71
76
|
lookup = File.join(lookup, '{*,.[a-z]*}')
|
72
77
|
|
73
78
|
Dir[lookup].sort.each do |file_source|
|
@@ -90,16 +90,35 @@ class Thor
|
|
90
90
|
|
91
91
|
# Filenames in the encoded form are converted. If you have a file:
|
92
92
|
#
|
93
|
-
# %
|
93
|
+
# %file_name%.rb
|
94
94
|
#
|
95
|
-
# It
|
95
|
+
# It calls #file_name from the base and replaces %-string with the
|
96
|
+
# return value (should be String) of #file_name:
|
96
97
|
#
|
97
98
|
# user.rb
|
98
99
|
#
|
100
|
+
# The method referenced by %-string SHOULD be public. Otherwise you
|
101
|
+
# get the exception with the corresponding error message.
|
102
|
+
#
|
99
103
|
def convert_encoded_instructions(filename)
|
100
|
-
filename.gsub(/%(.*?)%/) do |
|
101
|
-
|
102
|
-
|
104
|
+
filename.gsub(/%(.*?)%/) do |initial_string|
|
105
|
+
call_public_method($1.strip) or initial_string
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Calls `base`'s public method `sym`.
|
110
|
+
# Returns:: result of `base.sym` or `nil` if `sym` wasn't found in
|
111
|
+
# `base`
|
112
|
+
# Raises:: Thor::PrivateMethodEncodedError if `sym` references
|
113
|
+
# a private method.
|
114
|
+
def call_public_method(sym)
|
115
|
+
if base.respond_to?(sym)
|
116
|
+
base.send(sym)
|
117
|
+
elsif base.respond_to?(sym, true)
|
118
|
+
raise Thor::PrivateMethodEncodedError,
|
119
|
+
"Method #{base.class}##{sym} should be public, not private"
|
120
|
+
else
|
121
|
+
nil
|
103
122
|
end
|
104
123
|
end
|
105
124
|
|
@@ -187,7 +187,7 @@ class Thor
|
|
187
187
|
#
|
188
188
|
# ==== Examples
|
189
189
|
#
|
190
|
-
# inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n"
|
190
|
+
# inject_into_class "app/controllers/application_controller.rb", ApplicationController, " filter_parameter :password\n"
|
191
191
|
#
|
192
192
|
# inject_into_class "app/controllers/application_controller.rb", ApplicationController do
|
193
193
|
# " filter_parameter :password\n"
|
@@ -229,6 +229,44 @@ class Thor
|
|
229
229
|
end
|
230
230
|
end
|
231
231
|
|
232
|
+
# Uncomment all lines matching a given regex. It will leave the space
|
233
|
+
# which existed before the comment hash in tact but will remove any spacing
|
234
|
+
# between the comment hash and the beginning of the line.
|
235
|
+
#
|
236
|
+
# ==== Parameters
|
237
|
+
# path<String>:: path of the file to be changed
|
238
|
+
# flag<Regexp|String>:: the regexp or string used to decide which lines to uncomment
|
239
|
+
# config<Hash>:: give :verbose => false to not log the status.
|
240
|
+
#
|
241
|
+
# ==== Example
|
242
|
+
#
|
243
|
+
# uncomment_lines 'config/initializers/session_store.rb', /active_record/
|
244
|
+
#
|
245
|
+
def uncomment_lines(path, flag, *args)
|
246
|
+
flag = flag.respond_to?(:source) ? flag.source : flag
|
247
|
+
|
248
|
+
gsub_file(path, /^(\s*)#\s*(.*#{flag})/, '\1\2', *args)
|
249
|
+
end
|
250
|
+
|
251
|
+
# Comment all lines matching a given regex. It will leave the space
|
252
|
+
# which existed before the beginning of the line in tact and will insert
|
253
|
+
# a single space after the comment hash.
|
254
|
+
#
|
255
|
+
# ==== Parameters
|
256
|
+
# path<String>:: path of the file to be changed
|
257
|
+
# flag<Regexp|String>:: the regexp or string used to decide which lines to comment
|
258
|
+
# config<Hash>:: give :verbose => false to not log the status.
|
259
|
+
#
|
260
|
+
# ==== Example
|
261
|
+
#
|
262
|
+
# comment_lines 'config/initializers/session_store.rb', /cookie_store/
|
263
|
+
#
|
264
|
+
def comment_lines(path, flag, *args)
|
265
|
+
flag = flag.respond_to?(:source) ? flag.source : flag
|
266
|
+
|
267
|
+
gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
|
268
|
+
end
|
269
|
+
|
232
270
|
# Removes a file at the given location.
|
233
271
|
#
|
234
272
|
# ==== Parameters
|
@@ -19,7 +19,7 @@ class Thor
|
|
19
19
|
action add_file create_file in_root inside run run_ruby_script)
|
20
20
|
|
21
21
|
module Base
|
22
|
-
attr_accessor :options
|
22
|
+
attr_accessor :options, :parent_options, :args
|
23
23
|
|
24
24
|
# It receives arguments in an Array and two hashes, one for options and
|
25
25
|
# other for configuration.
|
@@ -38,22 +38,43 @@ class Thor
|
|
38
38
|
# config<Hash>:: Configuration for this Thor class.
|
39
39
|
#
|
40
40
|
def initialize(args=[], options={}, config={})
|
41
|
-
args = Thor::Arguments.parse(self.class.arguments, args)
|
42
|
-
args.each { |key, value| send("#{key}=", value) }
|
43
|
-
|
44
41
|
parse_options = self.class.class_options
|
45
42
|
|
43
|
+
# The start method splits inbound arguments at the first argument
|
44
|
+
# that looks like an option (starts with - or --). It then calls
|
45
|
+
# new, passing in the two halves of the arguments Array as the
|
46
|
+
# first two parameters.
|
47
|
+
|
46
48
|
if options.is_a?(Array)
|
47
49
|
task_options = config.delete(:task_options) # hook for start
|
48
50
|
parse_options = parse_options.merge(task_options) if task_options
|
49
51
|
array_options, hash_options = options, {}
|
50
52
|
else
|
53
|
+
# Handle the case where the class was explicitly instantiated
|
54
|
+
# with pre-parsed options.
|
51
55
|
array_options, hash_options = [], options
|
52
56
|
end
|
53
57
|
|
58
|
+
# Let Thor::Options parse the options first, so it can remove
|
59
|
+
# declared options from the array. This will leave us with
|
60
|
+
# a list of arguments that weren't declared.
|
54
61
|
opts = Thor::Options.new(parse_options, hash_options)
|
55
62
|
self.options = opts.parse(array_options)
|
63
|
+
|
64
|
+
# If unknown options are disallowed, make sure that none of the
|
65
|
+
# remaining arguments looks like an option.
|
56
66
|
opts.check_unknown! if self.class.check_unknown_options?(config)
|
67
|
+
|
68
|
+
# Add the remaining arguments from the options parser to the
|
69
|
+
# arguments passed in to initialize. Then remove any positional
|
70
|
+
# arguments declared using #argument (this is primarily used
|
71
|
+
# by Thor::Group). Tis will leave us with the remaining
|
72
|
+
# positional arguments.
|
73
|
+
thor_args = Thor::Arguments.new(self.class.arguments)
|
74
|
+
thor_args.parse(args + opts.remaining).each { |k,v| send("#{k}=", v) }
|
75
|
+
args = thor_args.remaining
|
76
|
+
|
77
|
+
@args = args
|
57
78
|
end
|
58
79
|
|
59
80
|
class << self
|
@@ -210,13 +231,14 @@ class Thor
|
|
210
231
|
# options<Hash>:: Described below.
|
211
232
|
#
|
212
233
|
# ==== Options
|
213
|
-
# :desc
|
214
|
-
# :required
|
215
|
-
# :default
|
216
|
-
# :group
|
217
|
-
# :aliases
|
218
|
-
# :type
|
219
|
-
# :banner
|
234
|
+
# :desc:: -- Description for the argument.
|
235
|
+
# :required:: -- If the argument is required or not.
|
236
|
+
# :default:: -- Default value for this argument.
|
237
|
+
# :group:: -- The group for this options. Use by class options to output options in different levels.
|
238
|
+
# :aliases:: -- Aliases for this option. <b>Note:</b> Thor follows a convention of one-dash-one-letter options. Thus aliases like "-something" wouldn't be parsed; use either "\--something" or "-s" instead.
|
239
|
+
# :type:: -- The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
|
240
|
+
# :banner:: -- String to show on usage notes.
|
241
|
+
# :hide:: -- If you want to hide this option from the help.
|
220
242
|
#
|
221
243
|
def class_option(name, options={})
|
222
244
|
build_option(name, options, class_options)
|
@@ -225,7 +247,7 @@ class Thor
|
|
225
247
|
# Removes a previous defined argument. If :undefine is given, undefine
|
226
248
|
# accessors as well.
|
227
249
|
#
|
228
|
-
# ====
|
250
|
+
# ==== Parameters
|
229
251
|
# names<Array>:: Arguments to be removed
|
230
252
|
#
|
231
253
|
# ==== Examples
|
@@ -244,7 +266,7 @@ class Thor
|
|
244
266
|
|
245
267
|
# Removes a previous defined class option.
|
246
268
|
#
|
247
|
-
# ====
|
269
|
+
# ==== Parameters
|
248
270
|
# names<Array>:: Class options to be removed
|
249
271
|
#
|
250
272
|
# ==== Examples
|
@@ -387,11 +409,17 @@ class Thor
|
|
387
409
|
rescue Thor::Error => e
|
388
410
|
ENV["THOR_DEBUG"] == "1" ? (raise e) : config[:shell].error(e.message)
|
389
411
|
exit(1) if exit_on_failure?
|
412
|
+
rescue Errno::EPIPE
|
413
|
+
# This happens if a thor task is piped to something like `head`,
|
414
|
+
# which closes the pipe when it's done reading. This will also
|
415
|
+
# mean that if the pipe is closed, further unnecessary
|
416
|
+
# computation will not occur.
|
417
|
+
exit(0)
|
390
418
|
end
|
391
419
|
|
392
420
|
# Allows to use private methods from parent in child classes as tasks.
|
393
421
|
#
|
394
|
-
# ====
|
422
|
+
# ==== Parameters
|
395
423
|
# names<Array>:: Method names to be used as tasks
|
396
424
|
#
|
397
425
|
# ==== Examples
|
@@ -405,16 +433,26 @@ class Thor
|
|
405
433
|
end
|
406
434
|
end
|
407
435
|
|
408
|
-
def handle_no_task_error(task) #:nodoc:
|
409
|
-
if
|
436
|
+
def handle_no_task_error(task, has_namespace = $thor_runner) #:nodoc:
|
437
|
+
if has_namespace
|
410
438
|
raise UndefinedTaskError, "Could not find task #{task.inspect} in #{namespace.inspect} namespace."
|
411
439
|
else
|
412
440
|
raise UndefinedTaskError, "Could not find task #{task.inspect}."
|
413
441
|
end
|
414
442
|
end
|
415
443
|
|
416
|
-
def handle_argument_error(task, error) #:nodoc:
|
417
|
-
|
444
|
+
def handle_argument_error(task, error, arity=nil) #:nodoc:
|
445
|
+
msg = "#{basename} #{task.name}"
|
446
|
+
if arity
|
447
|
+
required = arity < 0 ? (-1 - arity) : arity
|
448
|
+
msg << " requires at least #{required} argument"
|
449
|
+
msg << "s" if required > 1
|
450
|
+
else
|
451
|
+
msg = "call #{msg} as"
|
452
|
+
end
|
453
|
+
|
454
|
+
msg << ": #{self.banner(task).inspect}."
|
455
|
+
raise InvocationError, msg
|
418
456
|
end
|
419
457
|
|
420
458
|
protected
|
@@ -447,15 +485,17 @@ class Thor
|
|
447
485
|
padding = options.collect{ |o| o.aliases.size }.max.to_i * 4
|
448
486
|
|
449
487
|
options.each do |option|
|
450
|
-
|
451
|
-
|
488
|
+
unless option.hide
|
489
|
+
item = [ option.usage(padding) ]
|
490
|
+
item.push(option.description ? "# #{option.description}" : "")
|
452
491
|
|
453
|
-
|
454
|
-
|
492
|
+
list << item
|
493
|
+
list << [ "", "# Default: #{option.default}" ] if option.show_default?
|
494
|
+
end
|
455
495
|
end
|
456
496
|
|
457
497
|
shell.say(group_name ? "#{group_name} options:" : "Options:")
|
458
|
-
shell.print_table(list, :
|
498
|
+
shell.print_table(list, :indent => 2)
|
459
499
|
shell.say ""
|
460
500
|
end
|
461
501
|
|
@@ -473,7 +513,7 @@ class Thor
|
|
473
513
|
def build_option(name, options, scope) #:nodoc:
|
474
514
|
scope[name] = Thor::Option.new(name, options[:desc], options[:required],
|
475
515
|
options[:type], options[:default], options[:banner],
|
476
|
-
options[:lazy_default], options[:group], options[:aliases])
|
516
|
+
options[:lazy_default], options[:group], options[:aliases], options[:hide])
|
477
517
|
end
|
478
518
|
|
479
519
|
# Receives a hash of options, parse them and add to the scope. This is a
|
@@ -506,6 +546,7 @@ class Thor
|
|
506
546
|
# and file into baseclass.
|
507
547
|
def inherited(klass)
|
508
548
|
Thor::Base.register_klass_file(klass)
|
549
|
+
klass.instance_variable_set(:@no_tasks, false)
|
509
550
|
end
|
510
551
|
|
511
552
|
# Fire this callback whenever a method is added. Added methods are
|