bundler 1.14.6 → 1.15.0.pre.1
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.
- checksums.yaml +5 -5
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +131 -43
- data/.travis.yml +5 -5
- data/CHANGELOG.md +52 -8
- data/CONTRIBUTING.md +10 -29
- data/README.md +13 -6
- data/Rakefile +4 -2
- data/bin/rubocop +1 -1
- data/doc/README.md +30 -0
- data/doc/TROUBLESHOOTING.md +64 -0
- data/doc/contributing/BUG_TRIAGE.md +36 -0
- data/doc/contributing/COMMUNITY.md +13 -0
- data/doc/contributing/GETTING_HELP.md +11 -0
- data/doc/contributing/HOW_YOU_CAN_HELP.md +27 -0
- data/doc/contributing/ISSUES.md +51 -0
- data/doc/contributing/README.md +38 -0
- data/doc/development/NEW_FEATURES.md +10 -0
- data/doc/development/PULL_REQUESTS.md +40 -0
- data/doc/development/README.md +19 -0
- data/doc/development/RELEASING.md +9 -0
- data/doc/development/SETUP.md +29 -0
- data/doc/documentation/README.md +29 -0
- data/doc/documentation/VISION.md +26 -0
- data/doc/documentation/WRITING.md +54 -0
- data/exe/bundle +4 -1
- data/lib/bundler.rb +20 -13
- data/lib/bundler/cli.rb +67 -3
- data/lib/bundler/cli/add.rb +26 -0
- data/lib/bundler/cli/config.rb +24 -6
- data/lib/bundler/cli/gem.rb +13 -8
- data/lib/bundler/cli/info.rb +51 -0
- data/lib/bundler/cli/inject.rb +8 -2
- data/lib/bundler/cli/install.rb +1 -1
- data/lib/bundler/cli/issue.rb +40 -0
- data/lib/bundler/cli/outdated.rb +16 -18
- data/lib/bundler/cli/pristine.rb +33 -0
- data/lib/bundler/cli/viz.rb +1 -1
- data/lib/bundler/definition.rb +64 -48
- data/lib/bundler/dsl.rb +6 -0
- data/lib/bundler/endpoint_specification.rb +3 -9
- data/lib/bundler/env.rb +3 -3
- data/lib/bundler/errors.rb +1 -1
- data/lib/bundler/fetcher/downloader.rb +3 -2
- data/lib/bundler/gem_helper.rb +5 -0
- data/lib/bundler/index.rb +9 -3
- data/lib/bundler/injector.rb +32 -11
- data/lib/bundler/installer.rb +1 -1
- data/lib/bundler/installer/parallel_installer.rb +15 -1
- data/lib/bundler/lazy_specification.rb +6 -0
- data/lib/bundler/lockfile_parser.rb +42 -34
- data/lib/bundler/mirror.rb +2 -0
- data/lib/bundler/plugin.rb +5 -1
- data/lib/bundler/plugin/api/source.rb +1 -1
- data/lib/bundler/plugin/index.rb +2 -0
- data/lib/bundler/remote_specification.rb +16 -7
- data/lib/bundler/resolver.rb +13 -3
- data/lib/bundler/rubygems_ext.rb +8 -3
- data/lib/bundler/rubygems_integration.rb +85 -36
- data/lib/bundler/runtime.rb +4 -1
- data/lib/bundler/settings.rb +2 -1
- data/lib/bundler/setup.rb +1 -1
- data/lib/bundler/shared_helpers.rb +26 -1
- data/lib/bundler/source.rb +17 -1
- data/lib/bundler/source/git.rb +16 -0
- data/lib/bundler/source/path.rb +13 -3
- data/lib/bundler/source/path/installer.rb +2 -2
- data/lib/bundler/source/rubygems.rb +5 -2
- data/lib/bundler/spec_set.rb +22 -13
- data/lib/bundler/stub_specification.rb +64 -2
- data/lib/bundler/templates/Executable +1 -1
- data/lib/bundler/templates/Executable.standalone +5 -5
- data/lib/bundler/templates/newgem/Gemfile.tt +2 -2
- data/lib/bundler/templates/newgem/LICENSE.txt.tt +1 -1
- data/lib/bundler/templates/newgem/README.md.tt +12 -6
- data/lib/bundler/templates/newgem/Rakefile.tt +5 -5
- data/lib/bundler/templates/newgem/ext/newgem/newgem.c.tt +4 -4
- data/lib/bundler/templates/newgem/ext/newgem/newgem.h.tt +3 -3
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +6 -6
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +4 -4
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +9 -9
- data/lib/bundler/templates/newgem/spec/spec_helper.rb.tt +3 -0
- data/lib/bundler/templates/newgem/test/newgem_test.rb.tt +1 -1
- data/lib/bundler/templates/newgem/test/test_helper.rb.tt +3 -3
- data/lib/bundler/ui/shell.rb +9 -6
- data/lib/bundler/vendor/thor/lib/thor.rb +31 -23
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +21 -22
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +8 -8
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +23 -12
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +10 -14
- data/lib/bundler/vendor/thor/lib/thor/base.rb +30 -30
- data/lib/bundler/vendor/thor/lib/thor/command.rb +9 -9
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +9 -1
- data/lib/bundler/vendor/thor/lib/thor/core_ext/io_binary_read.rb +7 -5
- data/lib/bundler/vendor/thor/lib/thor/core_ext/ordered_hash.rb +94 -63
- data/lib/bundler/vendor/thor/lib/thor/error.rb +3 -3
- data/lib/bundler/vendor/thor/lib/thor/group.rb +12 -12
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +4 -5
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +4 -7
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +16 -16
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +40 -19
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +7 -5
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +25 -25
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +41 -26
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +4 -4
- data/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/version.rb +14 -1
- data/lib/bundler/version_ranges.rb +75 -0
- data/lib/bundler/worker.rb +2 -1
- data/man/bundle-check.ronn +26 -0
- data/man/bundle-clean.ronn +18 -0
- data/man/bundle-config.ronn +4 -1
- data/man/bundle-info.ronn +17 -0
- data/man/bundle-init.ronn +18 -0
- data/man/bundle-inject.ronn +22 -0
- data/man/bundle-open.ronn +19 -0
- data/man/bundle-show.ronn +20 -0
- data/man/bundle-update.ronn +5 -2
- data/man/bundle-viz.ronn +30 -0
- data/man/bundle.ronn +3 -0
- data/man/gemfile.5.ronn +24 -64
- data/task/release.rake +115 -0
- metadata +49 -5
- data/DEVELOPMENT.md +0 -150
- data/ISSUES.md +0 -117
@@ -3,7 +3,7 @@ class Bundler::Thor
|
|
3
3
|
# errors have their backtrace suppressed and are nicely shown to the user.
|
4
4
|
#
|
5
5
|
# Errors that are caused by the developer, like declaring a method which
|
6
|
-
# overwrites a thor keyword,
|
6
|
+
# overwrites a thor keyword, SHOULD NOT raise a Bundler::Thor::Error. This way, we
|
7
7
|
# ensure that developer errors are shown with full backtrace.
|
8
8
|
class Error < StandardError
|
9
9
|
end
|
@@ -11,11 +11,11 @@ class Bundler::Thor
|
|
11
11
|
# Raised when a command was not found.
|
12
12
|
class UndefinedCommandError < Error
|
13
13
|
end
|
14
|
-
UndefinedTaskError = UndefinedCommandError
|
14
|
+
UndefinedTaskError = UndefinedCommandError
|
15
15
|
|
16
16
|
class AmbiguousCommandError < Error
|
17
17
|
end
|
18
|
-
AmbiguousTaskError = AmbiguousCommandError
|
18
|
+
AmbiguousTaskError = AmbiguousCommandError
|
19
19
|
|
20
20
|
# Raised when a command was found, but not invoked properly.
|
21
21
|
class InvocationError < Error
|
@@ -4,7 +4,7 @@ require "bundler/vendor/thor/lib/thor/base"
|
|
4
4
|
# is that it invokes all commands at once. It also include some methods that allows
|
5
5
|
# invocations to be done at the class method, which are not available to Bundler::Thor
|
6
6
|
# commands.
|
7
|
-
class Bundler::Thor::Group
|
7
|
+
class Bundler::Thor::Group
|
8
8
|
class << self
|
9
9
|
# The description for this Bundler::Thor::Group. If none is provided, but a source root
|
10
10
|
# exists, tries to find the USAGE one folder above it, otherwise searches
|
@@ -53,7 +53,7 @@ class Bundler::Thor::Group # rubocop:disable ClassLength
|
|
53
53
|
# The namespace/class given will have its options showed on the help
|
54
54
|
# usage. Check invoke_from_option for more information.
|
55
55
|
#
|
56
|
-
def invoke(*names, &block)
|
56
|
+
def invoke(*names, &block)
|
57
57
|
options = names.last.is_a?(Hash) ? names.pop : {}
|
58
58
|
verbose = options.fetch(:verbose, true)
|
59
59
|
|
@@ -62,7 +62,7 @@ class Bundler::Thor::Group # rubocop:disable ClassLength
|
|
62
62
|
invocation_blocks[name] = block if block_given?
|
63
63
|
|
64
64
|
class_eval <<-METHOD, __FILE__, __LINE__
|
65
|
-
def _invoke_#{name.to_s.gsub(/\W/,
|
65
|
+
def _invoke_#{name.to_s.gsub(/\W/, '_')}
|
66
66
|
klass, command = self.class.prepare_for_invocation(nil, #{name.inspect})
|
67
67
|
|
68
68
|
if klass
|
@@ -107,21 +107,21 @@ class Bundler::Thor::Group # rubocop:disable ClassLength
|
|
107
107
|
# invoked. The block receives two parameters, an instance of the current
|
108
108
|
# class and the klass to be invoked.
|
109
109
|
#
|
110
|
-
def invoke_from_option(*names, &block)
|
110
|
+
def invoke_from_option(*names, &block)
|
111
111
|
options = names.last.is_a?(Hash) ? names.pop : {}
|
112
112
|
verbose = options.fetch(:verbose, :white)
|
113
113
|
|
114
114
|
names.each do |name|
|
115
115
|
unless class_options.key?(name)
|
116
|
-
|
117
|
-
|
116
|
+
raise ArgumentError, "You have to define the option #{name.inspect} " \
|
117
|
+
"before setting invoke_from_option."
|
118
118
|
end
|
119
119
|
|
120
120
|
invocations[name] = true
|
121
121
|
invocation_blocks[name] = block if block_given?
|
122
122
|
|
123
123
|
class_eval <<-METHOD, __FILE__, __LINE__
|
124
|
-
def _invoke_from_option_#{name.to_s.gsub(/\W/,
|
124
|
+
def _invoke_from_option_#{name.to_s.gsub(/\W/, '_')}
|
125
125
|
return unless options[#{name.inspect}]
|
126
126
|
|
127
127
|
value = options[#{name.inspect}]
|
@@ -188,7 +188,7 @@ class Bundler::Thor::Group # rubocop:disable ClassLength
|
|
188
188
|
group_options[human_name] ||= []
|
189
189
|
group_options[human_name] += klass.class_options.values.select do |class_option|
|
190
190
|
base_options[class_option.name.to_sym].nil? && class_option.group.nil? &&
|
191
|
-
|
191
|
+
!group_options.values.flatten.any? { |i| i.name == class_option.name }
|
192
192
|
end
|
193
193
|
|
194
194
|
yield klass if block_given?
|
@@ -204,11 +204,11 @@ class Bundler::Thor::Group # rubocop:disable ClassLength
|
|
204
204
|
end
|
205
205
|
alias_method :printable_tasks, :printable_commands
|
206
206
|
|
207
|
-
def handle_argument_error(command, error,
|
207
|
+
def handle_argument_error(command, error, _args, arity) #:nodoc:
|
208
208
|
msg = "#{basename} #{command.name} takes #{arity} argument"
|
209
209
|
msg << "s" if arity > 1
|
210
210
|
msg << ", but it should not."
|
211
|
-
|
211
|
+
raise error, msg
|
212
212
|
end
|
213
213
|
|
214
214
|
protected
|
@@ -267,9 +267,9 @@ protected
|
|
267
267
|
if block
|
268
268
|
case block.arity
|
269
269
|
when 3
|
270
|
-
|
270
|
+
yield(self, klass, command)
|
271
271
|
when 2
|
272
|
-
|
272
|
+
yield(self, klass)
|
273
273
|
when 1
|
274
274
|
instance_exec(klass, &block)
|
275
275
|
end
|
@@ -108,8 +108,8 @@ class Bundler::Thor
|
|
108
108
|
command, args, opts, config = args
|
109
109
|
|
110
110
|
klass, command = _retrieve_class_and_command(name, command)
|
111
|
-
|
112
|
-
|
111
|
+
raise "Missing Bundler::Thor class for invoke #{name}" unless klass
|
112
|
+
raise "Expected Bundler::Thor class, got #{klass}" unless klass <= Bundler::Thor::Base
|
113
113
|
|
114
114
|
args, opts, config = _parse_initialization_options(args, opts, config)
|
115
115
|
klass.send(:dispatch, command, args, opts, config) do |instance|
|
@@ -150,10 +150,9 @@ class Bundler::Thor
|
|
150
150
|
# use the given name and return self as class. Otherwise, call
|
151
151
|
# prepare_for_invocation in the current class.
|
152
152
|
def _retrieve_class_and_command(name, sent_command = nil) #:nodoc:
|
153
|
-
|
154
|
-
when name.nil?
|
153
|
+
if name.nil?
|
155
154
|
[self.class, nil]
|
156
|
-
|
155
|
+
elsif self.class.all_commands[name.to_s]
|
157
156
|
[self.class, name.to_s]
|
158
157
|
else
|
159
158
|
klass, command = self.class.prepare_for_invocation(nil, name)
|
@@ -10,8 +10,8 @@ class Bundler::Thor
|
|
10
10
|
|
11
11
|
type = options[:type]
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
raise ArgumentError, "#{class_name} name can't be nil." if name.nil?
|
14
|
+
raise ArgumentError, "Type :#{type} is not valid for #{class_name.downcase}s." if type && !valid_type?(type)
|
15
15
|
|
16
16
|
@name = name.to_s
|
17
17
|
@description = options[:desc]
|
@@ -44,11 +44,8 @@ class Bundler::Thor
|
|
44
44
|
protected
|
45
45
|
|
46
46
|
def validate!
|
47
|
-
if required? && !default.nil?
|
48
|
-
|
49
|
-
elsif @enum && !@enum.is_a?(Array)
|
50
|
-
fail ArgumentError, "An argument cannot have an enum other than an array."
|
51
|
-
end
|
47
|
+
raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
|
48
|
+
raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array)
|
52
49
|
end
|
53
50
|
|
54
51
|
def valid_type?(type)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Bundler::Thor
|
2
2
|
class Arguments #:nodoc: # rubocop:disable ClassLength
|
3
|
-
NUMERIC = /(\d*\.\d+|\d+)/
|
3
|
+
NUMERIC = /[-+]?(\d*\.\d+|\d+)/
|
4
4
|
|
5
5
|
# Receives an array of args and returns two arrays, one with arguments
|
6
6
|
# and one with switches.
|
@@ -24,7 +24,8 @@ class Bundler::Thor
|
|
24
24
|
# Takes an array of Bundler::Thor::Argument objects.
|
25
25
|
#
|
26
26
|
def initialize(arguments = [])
|
27
|
-
@assigns
|
27
|
+
@assigns = {}
|
28
|
+
@non_assigned_required = []
|
28
29
|
@switches = arguments
|
29
30
|
|
30
31
|
arguments.each do |argument|
|
@@ -49,7 +50,7 @@ class Bundler::Thor
|
|
49
50
|
@assigns
|
50
51
|
end
|
51
52
|
|
52
|
-
def remaining
|
53
|
+
def remaining
|
53
54
|
@pile
|
54
55
|
end
|
55
56
|
|
@@ -73,7 +74,7 @@ class Bundler::Thor
|
|
73
74
|
end
|
74
75
|
|
75
76
|
def unshift(arg)
|
76
|
-
if arg.
|
77
|
+
if arg.is_a?(Array)
|
77
78
|
@pile = arg + @pile
|
78
79
|
else
|
79
80
|
@pile.unshift(arg)
|
@@ -99,6 +100,7 @@ class Bundler::Thor
|
|
99
100
|
|
100
101
|
while current_is_value? && peek.include?(":")
|
101
102
|
key, value = shift.split(":", 2)
|
103
|
+
raise MalformattedArgumentError, "You can't specify '#{key}' more than once in option '#{name}'; got #{key}:#{hash[key]} and #{key}:#{value}" if hash.include? key
|
102
104
|
hash[key] = value
|
103
105
|
end
|
104
106
|
hash
|
@@ -128,13 +130,13 @@ class Bundler::Thor
|
|
128
130
|
return shift if peek.is_a?(Numeric)
|
129
131
|
|
130
132
|
unless peek =~ NUMERIC && $& == peek
|
131
|
-
|
133
|
+
raise MalformattedArgumentError, "Expected numeric value for '#{name}'; got #{peek.inspect}"
|
132
134
|
end
|
133
135
|
|
134
136
|
value = $&.index(".") ? shift.to_f : shift.to_i
|
135
137
|
if @switches.is_a?(Hash) && switch = @switches[name]
|
136
138
|
if switch.enum && !switch.enum.include?(value)
|
137
|
-
|
139
|
+
raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
|
138
140
|
end
|
139
141
|
end
|
140
142
|
value
|
@@ -150,9 +152,9 @@ class Bundler::Thor
|
|
150
152
|
nil
|
151
153
|
else
|
152
154
|
value = shift
|
153
|
-
if @switches.is_a?(Hash) && switch = @switches[name]
|
155
|
+
if @switches.is_a?(Hash) && switch = @switches[name]
|
154
156
|
if switch.enum && !switch.enum.include?(value)
|
155
|
-
|
157
|
+
raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
|
156
158
|
end
|
157
159
|
end
|
158
160
|
value
|
@@ -162,14 +164,12 @@ class Bundler::Thor
|
|
162
164
|
# Raises an error if @non_assigned_required array is not empty.
|
163
165
|
#
|
164
166
|
def check_requirement!
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
fail RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
|
172
|
-
end
|
167
|
+
return if @non_assigned_required.empty?
|
168
|
+
names = @non_assigned_required.map do |o|
|
169
|
+
o.respond_to?(:switch_name) ? o.switch_name : o.human_name
|
170
|
+
end.join("', '")
|
171
|
+
class_name = self.class.name.split("::").last.downcase
|
172
|
+
raise RequiredArgumentMissingError, "No value provided for required #{class_name} '#{names}'"
|
173
173
|
end
|
174
174
|
end
|
175
175
|
end
|
@@ -40,31 +40,33 @@ class Bundler::Thor
|
|
40
40
|
#
|
41
41
|
# By default all options are optional, unless :required is given.
|
42
42
|
#
|
43
|
-
def self.parse(key, value)
|
43
|
+
def self.parse(key, value)
|
44
44
|
if key.is_a?(Array)
|
45
45
|
name, *aliases = key
|
46
46
|
else
|
47
|
-
name
|
47
|
+
name = key
|
48
|
+
aliases = []
|
48
49
|
end
|
49
50
|
|
50
51
|
name = name.to_s
|
51
52
|
default = value
|
52
53
|
|
53
54
|
type = case value
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
55
|
+
when Symbol
|
56
|
+
default = nil
|
57
|
+
if VALID_TYPES.include?(value)
|
58
|
+
value
|
59
|
+
elsif required = (value == :required) # rubocop:disable AssignmentInCondition
|
60
|
+
:string
|
61
|
+
end
|
62
|
+
when TrueClass, FalseClass
|
63
|
+
:boolean
|
64
|
+
when Numeric
|
65
|
+
:numeric
|
66
|
+
when Hash, Array, String
|
67
|
+
value.class.name.downcase.to_sym
|
68
|
+
end
|
69
|
+
|
68
70
|
new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
|
69
71
|
end
|
70
72
|
|
@@ -86,7 +88,7 @@ class Bundler::Thor
|
|
86
88
|
sample = "[#{sample}]" unless required?
|
87
89
|
|
88
90
|
if boolean?
|
89
|
-
sample << ", [#{dasherize(
|
91
|
+
sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
|
90
92
|
end
|
91
93
|
|
92
94
|
if aliases.empty?
|
@@ -107,7 +109,26 @@ class Bundler::Thor
|
|
107
109
|
protected
|
108
110
|
|
109
111
|
def validate!
|
110
|
-
|
112
|
+
raise ArgumentError, "An option cannot be boolean and required." if boolean? && required?
|
113
|
+
validate_default_type!
|
114
|
+
end
|
115
|
+
|
116
|
+
def validate_default_type!
|
117
|
+
default_type = case @default
|
118
|
+
when nil
|
119
|
+
return
|
120
|
+
when TrueClass, FalseClass
|
121
|
+
required? ? :string : :boolean
|
122
|
+
when Numeric
|
123
|
+
:numeric
|
124
|
+
when Symbol
|
125
|
+
:string
|
126
|
+
when Hash, Array, String
|
127
|
+
@default.class.name.downcase.to_sym
|
128
|
+
end
|
129
|
+
|
130
|
+
# TODO: This should raise an ArgumentError in a future version of Bundler::Thor
|
131
|
+
warn "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type
|
111
132
|
end
|
112
133
|
|
113
134
|
def dasherized?
|
@@ -119,7 +140,7 @@ class Bundler::Thor
|
|
119
140
|
end
|
120
141
|
|
121
142
|
def dasherize(str)
|
122
|
-
(str.length > 1 ? "--" : "-") + str.
|
143
|
+
(str.length > 1 ? "--" : "-") + str.tr("_", "-")
|
123
144
|
end
|
124
145
|
end
|
125
146
|
end
|
@@ -14,7 +14,7 @@ class Bundler::Thor
|
|
14
14
|
when true
|
15
15
|
"--#{key}"
|
16
16
|
when Array
|
17
|
-
"--#{key} #{value.map
|
17
|
+
"--#{key} #{value.map(&:inspect).join(' ')}"
|
18
18
|
when Hash
|
19
19
|
"--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}"
|
20
20
|
when nil, false
|
@@ -40,7 +40,9 @@ class Bundler::Thor
|
|
40
40
|
@non_assigned_required.delete(hash_options[key])
|
41
41
|
end
|
42
42
|
|
43
|
-
@shorts
|
43
|
+
@shorts = {}
|
44
|
+
@switches = {}
|
45
|
+
@extra = []
|
44
46
|
|
45
47
|
options.each do |option|
|
46
48
|
@switches[option.switch_name] = option
|
@@ -52,7 +54,7 @@ class Bundler::Thor
|
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
|
-
def remaining
|
57
|
+
def remaining
|
56
58
|
@extra
|
57
59
|
end
|
58
60
|
|
@@ -119,7 +121,7 @@ class Bundler::Thor
|
|
119
121
|
def check_unknown!
|
120
122
|
# an unknown option starts with - or -- and has no more --'s afterward.
|
121
123
|
unknown = @extra.select { |str| str =~ /^--?(?:(?!--).)*$/ }
|
122
|
-
|
124
|
+
raise UnknownArgumentError, "Unknown switches '#{unknown.join(', ')}'" unless unknown.empty?
|
123
125
|
end
|
124
126
|
|
125
127
|
protected
|
@@ -207,7 +209,7 @@ class Bundler::Thor
|
|
207
209
|
elsif option.lazy_default
|
208
210
|
return option.lazy_default
|
209
211
|
else
|
210
|
-
|
212
|
+
raise MalformattedArgumentError, "No value provided for option '#{switch}'"
|
211
213
|
end
|
212
214
|
end
|
213
215
|
|
@@ -11,10 +11,18 @@ require "pathname"
|
|
11
11
|
class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength
|
12
12
|
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
|
13
13
|
|
14
|
+
def self.banner(command, all = false, subcommand = false)
|
15
|
+
"thor " + command.formatted_usage(self, all, subcommand)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.exit_on_failure?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
14
22
|
# Override Bundler::Thor#help so it can give information about any class and any method.
|
15
23
|
#
|
16
24
|
def help(meth = nil)
|
17
|
-
if meth && !
|
25
|
+
if meth && !respond_to?(meth)
|
18
26
|
initialize_thorfiles(meth)
|
19
27
|
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
|
20
28
|
self.class.handle_no_command_error(command, false) if klass.nil?
|
@@ -45,16 +53,18 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
45
53
|
# command in said directory.
|
46
54
|
begin
|
47
55
|
if File.directory?(File.expand_path(name))
|
48
|
-
base
|
49
|
-
|
56
|
+
base = File.join(name, "main.thor")
|
57
|
+
package = :directory
|
58
|
+
contents = open(base, &:read)
|
50
59
|
else
|
51
|
-
base
|
52
|
-
|
60
|
+
base = name
|
61
|
+
package = :file
|
62
|
+
contents = open(name, &:read)
|
53
63
|
end
|
54
64
|
rescue OpenURI::HTTPError
|
55
65
|
raise Error, "Error opening URI '#{name}'"
|
56
66
|
rescue Errno::ENOENT
|
57
|
-
|
67
|
+
raise Error, "Error opening file '#{name}'"
|
58
68
|
end
|
59
69
|
|
60
70
|
say "Your Bundler::Thorfile contains:"
|
@@ -108,9 +118,9 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
108
118
|
|
109
119
|
desc "uninstall NAME", "Uninstall a named Bundler::Thor module"
|
110
120
|
def uninstall(name)
|
111
|
-
|
121
|
+
raise Error, "Can't find module '#{name}'" unless thor_yaml[name]
|
112
122
|
say "Uninstalling #{name}."
|
113
|
-
FileUtils.rm_rf(File.join(thor_root,
|
123
|
+
FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s))
|
114
124
|
|
115
125
|
thor_yaml.delete(name)
|
116
126
|
save_yaml(thor_yaml)
|
@@ -120,7 +130,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
120
130
|
|
121
131
|
desc "update NAME", "Update a Bundler::Thor file from its original location"
|
122
132
|
def update(name)
|
123
|
-
|
133
|
+
raise Error, "Can't find module '#{name}'" if !thor_yaml[name] || !thor_yaml[name][:location]
|
124
134
|
|
125
135
|
say "Updating '#{name}' from #{thor_yaml[name][:location]}"
|
126
136
|
|
@@ -138,9 +148,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
138
148
|
filename = install(thor_yaml[name][:location])
|
139
149
|
end
|
140
150
|
|
141
|
-
unless filename == old_filename
|
142
|
-
File.delete(File.join(thor_root, old_filename))
|
143
|
-
end
|
151
|
+
File.delete(File.join(thor_root, old_filename)) unless filename == old_filename
|
144
152
|
end
|
145
153
|
|
146
154
|
desc "installed", "List the installed Bundler::Thor modules and commands"
|
@@ -168,10 +176,6 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
168
176
|
|
169
177
|
private
|
170
178
|
|
171
|
-
def self.banner(command, all = false, subcommand = false)
|
172
|
-
"thor " + command.formatted_usage(self, all, subcommand)
|
173
|
-
end
|
174
|
-
|
175
179
|
def thor_root
|
176
180
|
Bundler::Thor::Util.thor_root
|
177
181
|
end
|
@@ -198,10 +202,6 @@ private
|
|
198
202
|
File.open(yaml_file, "w") { |f| f.puts yaml.to_yaml }
|
199
203
|
end
|
200
204
|
|
201
|
-
def self.exit_on_failure?
|
202
|
-
true
|
203
|
-
end
|
204
|
-
|
205
205
|
# Load the Bundler::Thorfiles. If relevant_to is supplied, looks for specific files
|
206
206
|
# in the thor_root instead of loading them all.
|
207
207
|
#
|
@@ -263,11 +263,11 @@ private
|
|
263
263
|
def thorfiles_relevant_to(meth)
|
264
264
|
lookup = [meth, meth.split(":")[0...-1].join(":")]
|
265
265
|
|
266
|
-
files = thor_yaml.select do |
|
266
|
+
files = thor_yaml.select do |_, v|
|
267
267
|
v[:namespaces] && !(v[:namespaces] & lookup).empty?
|
268
268
|
end
|
269
269
|
|
270
|
-
files.map { |
|
270
|
+
files.map { |_, v| File.join(thor_root, (v[:filename]).to_s) }
|
271
271
|
end
|
272
272
|
|
273
273
|
# Display information about the given klasses. If with_module is given,
|
@@ -276,7 +276,7 @@ private
|
|
276
276
|
def display_klasses(with_modules = false, show_internal = false, klasses = Bundler::Thor::Base.subclasses)
|
277
277
|
klasses -= [Bundler::Thor, Bundler::Thor::Runner, Bundler::Thor::Group] unless show_internal
|
278
278
|
|
279
|
-
|
279
|
+
raise Error, "No Bundler::Thor commands available" if klasses.empty?
|
280
280
|
show_modules if with_modules && !thor_yaml.empty?
|
281
281
|
|
282
282
|
list = Hash.new { |h, k| h[k] = [] }
|
@@ -306,8 +306,8 @@ private
|
|
306
306
|
alias_method :display_tasks, :display_commands
|
307
307
|
|
308
308
|
def show_modules #:nodoc:
|
309
|
-
info
|
310
|
-
labels = %w
|
309
|
+
info = []
|
310
|
+
labels = %w(Modules Namespaces)
|
311
311
|
|
312
312
|
info << labels
|
313
313
|
info << ["-" * labels[0].size, "-" * labels[1].size]
|