bundler 2.4.21 → 2.4.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/README.md +1 -2
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/gem.rb +3 -0
- data/lib/bundler/definition.rb +1 -1
- data/lib/bundler/endpoint_specification.rb +1 -1
- data/lib/bundler/errors.rb +15 -0
- data/lib/bundler/gem_helpers.rb +7 -0
- data/lib/bundler/installer/gem_installer.rb +5 -5
- data/lib/bundler/lazy_specification.rb +4 -0
- data/lib/bundler/plugin/index.rb +8 -0
- data/lib/bundler/plugin.rb +9 -2
- data/lib/bundler/rubygems_ext.rb +3 -4
- data/lib/bundler/rubygems_gem_installer.rb +23 -8
- data/lib/bundler/source/git/git_proxy.rb +9 -1
- data/lib/bundler/source/metadata.rb +1 -1
- data/lib/bundler/spec_set.rb +5 -2
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/lib/bundler/ui/shell.rb +1 -1
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +1 -0
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +21 -9
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
- data/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +8 -10
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -4
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +15 -15
- data/lib/bundler/vendor/thor/lib/thor/base.rb +140 -14
- data/lib/bundler/vendor/thor/lib/thor/command.rb +13 -4
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +4 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +16 -25
- data/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/nested_context.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +20 -1
- data/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +33 -17
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +27 -8
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +44 -6
- data/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +40 -30
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +26 -150
- data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +4 -46
- data/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -45
- data/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb +49 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +134 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
- data/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- 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/vendor/thor/lib/thor.rb +155 -8
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/yaml_serializer.rb +6 -1
- data/lib/bundler.rb +0 -8
- metadata +8 -3
@@ -1,5 +1,5 @@
|
|
1
1
|
class Bundler::Thor
|
2
|
-
class Options < Arguments #:nodoc:
|
2
|
+
class Options < Arguments #:nodoc:
|
3
3
|
LONG_RE = /^(--\w+(?:-\w+)*)$/
|
4
4
|
SHORT_RE = /^(-[a-z])$/i
|
5
5
|
EQ_RE = /^(--\w+(?:-\w+)*|-[a-z])=(.*)$/i
|
@@ -29,8 +29,10 @@ class Bundler::Thor
|
|
29
29
|
#
|
30
30
|
# If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
|
31
31
|
# an unknown option or a regular argument.
|
32
|
-
def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false)
|
32
|
+
def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false, relations = {})
|
33
33
|
@stop_on_unknown = stop_on_unknown
|
34
|
+
@exclusives = (relations[:exclusive_option_names] || []).select{|array| !array.empty?}
|
35
|
+
@at_least_ones = (relations[:at_least_one_option_names] || []).select{|array| !array.empty?}
|
34
36
|
@disable_required_check = disable_required_check
|
35
37
|
options = hash_options.values
|
36
38
|
super(options)
|
@@ -50,8 +52,7 @@ class Bundler::Thor
|
|
50
52
|
options.each do |option|
|
51
53
|
@switches[option.switch_name] = option
|
52
54
|
|
53
|
-
option.aliases.each do |
|
54
|
-
name = short.to_s.sub(/^(?!\-)/, "-")
|
55
|
+
option.aliases.each do |name|
|
55
56
|
@shorts[name] ||= option.switch_name
|
56
57
|
end
|
57
58
|
end
|
@@ -85,7 +86,7 @@ class Bundler::Thor
|
|
85
86
|
super(arg)
|
86
87
|
end
|
87
88
|
|
88
|
-
def parse(args) # rubocop:disable MethodLength
|
89
|
+
def parse(args) # rubocop:disable Metrics/MethodLength
|
89
90
|
@pile = args.dup
|
90
91
|
@is_treated_as_value = false
|
91
92
|
@parsing_options = true
|
@@ -132,12 +133,38 @@ class Bundler::Thor
|
|
132
133
|
end
|
133
134
|
|
134
135
|
check_requirement! unless @disable_required_check
|
136
|
+
check_exclusive!
|
137
|
+
check_at_least_one!
|
135
138
|
|
136
139
|
assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
|
137
140
|
assigns.freeze
|
138
141
|
assigns
|
139
142
|
end
|
140
143
|
|
144
|
+
def check_exclusive!
|
145
|
+
opts = @assigns.keys
|
146
|
+
# When option A and B are exclusive, if A and B are given at the same time,
|
147
|
+
# the diffrence of argument array size will decrease.
|
148
|
+
found = @exclusives.find{ |ex| (ex - opts).size < ex.size - 1 }
|
149
|
+
if found
|
150
|
+
names = names_to_switch_names(found & opts).map{|n| "'#{n}'"}
|
151
|
+
class_name = self.class.name.split("::").last.downcase
|
152
|
+
fail ExclusiveArgumentError, "Found exclusive #{class_name} #{names.join(", ")}"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def check_at_least_one!
|
157
|
+
opts = @assigns.keys
|
158
|
+
# When at least one is required of the options A and B,
|
159
|
+
# if the both options were not given, none? would be true.
|
160
|
+
found = @at_least_ones.find{ |one_reqs| one_reqs.none?{ |o| opts.include? o} }
|
161
|
+
if found
|
162
|
+
names = names_to_switch_names(found).map{|n| "'#{n}'"}
|
163
|
+
class_name = self.class.name.split("::").last.downcase
|
164
|
+
fail AtLeastOneRequiredArgumentError, "Not found at least one of required #{class_name} #{names.join(", ")}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
141
168
|
def check_unknown!
|
142
169
|
to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
|
143
170
|
|
@@ -148,6 +175,17 @@ class Bundler::Thor
|
|
148
175
|
|
149
176
|
protected
|
150
177
|
|
178
|
+
# Option names changes to swith name or human name
|
179
|
+
def names_to_switch_names(names = [])
|
180
|
+
@switches.map do |_, o|
|
181
|
+
if names.include? o.name
|
182
|
+
o.respond_to?(:switch_name) ? o.switch_name : o.human_name
|
183
|
+
else
|
184
|
+
nil
|
185
|
+
end
|
186
|
+
end.compact
|
187
|
+
end
|
188
|
+
|
151
189
|
def assign_result!(option, result)
|
152
190
|
if option.repeatable && option.type == :hash
|
153
191
|
(@assigns[option.human_name] ||= {}).merge!(result)
|
@@ -194,7 +232,7 @@ class Bundler::Thor
|
|
194
232
|
end
|
195
233
|
|
196
234
|
def switch_option(arg)
|
197
|
-
if match = no_or_skip?(arg) # rubocop:disable AssignmentInCondition
|
235
|
+
if match = no_or_skip?(arg) # rubocop:disable Lint/AssignmentInCondition
|
198
236
|
@switches[arg] || @switches["--#{match}"]
|
199
237
|
else
|
200
238
|
@switches[arg]
|
@@ -41,7 +41,7 @@ instance_eval do
|
|
41
41
|
def task(*)
|
42
42
|
task = super
|
43
43
|
|
44
|
-
if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
|
44
|
+
if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable Lint/AssignmentInCondition
|
45
45
|
non_namespaced_name = task.name.split(":").last
|
46
46
|
|
47
47
|
description = non_namespaced_name
|
@@ -59,7 +59,7 @@ instance_eval do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def namespace(name)
|
62
|
-
if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable AssignmentInCondition
|
62
|
+
if klass = Bundler::Thor::RakeCompat.rake_classes.last # rubocop:disable Lint/AssignmentInCondition
|
63
63
|
const_name = Bundler::Thor::Util.camel_case(name.to_s).to_sym
|
64
64
|
klass.const_set(const_name, Class.new(Bundler::Thor))
|
65
65
|
new_klass = klass.const_get(const_name)
|
@@ -2,12 +2,10 @@ require_relative "../thor"
|
|
2
2
|
require_relative "group"
|
3
3
|
|
4
4
|
require "yaml"
|
5
|
-
require "digest/
|
5
|
+
require "digest/sha2"
|
6
6
|
require "pathname"
|
7
7
|
|
8
|
-
class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
9
|
-
autoload :OpenURI, "open-uri"
|
10
|
-
|
8
|
+
class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
11
9
|
map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version
|
12
10
|
|
13
11
|
def self.banner(command, all = false, subcommand = false)
|
@@ -25,7 +23,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
25
23
|
initialize_thorfiles(meth)
|
26
24
|
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
|
27
25
|
self.class.handle_no_command_error(command, false) if klass.nil?
|
28
|
-
klass.start(["-h", command].compact, :
|
26
|
+
klass.start(["-h", command].compact, shell: shell)
|
29
27
|
else
|
30
28
|
super
|
31
29
|
end
|
@@ -40,30 +38,42 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
40
38
|
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
|
41
39
|
self.class.handle_no_command_error(command, false) if klass.nil?
|
42
40
|
args.unshift(command) if command
|
43
|
-
klass.start(args, :
|
41
|
+
klass.start(args, shell: shell)
|
44
42
|
end
|
45
43
|
|
46
44
|
desc "install NAME", "Install an optionally named Bundler::Thor file into your system commands"
|
47
|
-
method_options :
|
48
|
-
def install(name) # rubocop:disable MethodLength
|
45
|
+
method_options as: :string, relative: :boolean, force: :boolean
|
46
|
+
def install(name) # rubocop:disable Metrics/MethodLength
|
49
47
|
initialize_thorfiles
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
49
|
+
is_uri = name =~ %r{^https?\://}
|
50
|
+
|
51
|
+
if is_uri
|
52
|
+
base = name
|
53
|
+
package = :file
|
54
|
+
require "open-uri"
|
55
|
+
begin
|
56
|
+
contents = URI.open(name, &:read)
|
57
|
+
rescue OpenURI::HTTPError
|
58
|
+
raise Error, "Error opening URI '#{name}'"
|
59
|
+
end
|
60
|
+
else
|
61
|
+
# If a directory name is provided as the argument, look for a 'main.thor'
|
62
|
+
# command in said directory.
|
63
|
+
begin
|
64
|
+
if File.directory?(File.expand_path(name))
|
65
|
+
base = File.join(name, "main.thor")
|
66
|
+
package = :directory
|
67
|
+
contents = File.open(base, &:read)
|
68
|
+
else
|
69
|
+
base = name
|
70
|
+
package = :file
|
71
|
+
require "open-uri"
|
72
|
+
contents = URI.open(name, &:read)
|
73
|
+
end
|
74
|
+
rescue Errno::ENOENT
|
75
|
+
raise Error, "Error opening file '#{name}'"
|
62
76
|
end
|
63
|
-
rescue OpenURI::HTTPError
|
64
|
-
raise Error, "Error opening URI '#{name}'"
|
65
|
-
rescue Errno::ENOENT
|
66
|
-
raise Error, "Error opening file '#{name}'"
|
67
77
|
end
|
68
78
|
|
69
79
|
say "Your Thorfile contains:"
|
@@ -84,16 +94,16 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
84
94
|
as = basename if as.empty?
|
85
95
|
end
|
86
96
|
|
87
|
-
location = if options[:relative] ||
|
97
|
+
location = if options[:relative] || is_uri
|
88
98
|
name
|
89
99
|
else
|
90
100
|
File.expand_path(name)
|
91
101
|
end
|
92
102
|
|
93
103
|
thor_yaml[as] = {
|
94
|
-
:
|
95
|
-
:
|
96
|
-
:
|
104
|
+
filename: Digest::SHA256.hexdigest(name + as),
|
105
|
+
location: location,
|
106
|
+
namespaces: Bundler::Thor::Util.namespaces_in_content(contents, base)
|
97
107
|
}
|
98
108
|
|
99
109
|
save_yaml(thor_yaml)
|
@@ -154,14 +164,14 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng
|
|
154
164
|
end
|
155
165
|
|
156
166
|
desc "installed", "List the installed Bundler::Thor modules and commands"
|
157
|
-
method_options :
|
167
|
+
method_options internal: :boolean
|
158
168
|
def installed
|
159
169
|
initialize_thorfiles(nil, true)
|
160
170
|
display_klasses(true, options["internal"])
|
161
171
|
end
|
162
172
|
|
163
173
|
desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)"
|
164
|
-
method_options :
|
174
|
+
method_options substring: :boolean, group: :string, all: :boolean, debug: :boolean
|
165
175
|
def list(search = "")
|
166
176
|
initialize_thorfiles
|
167
177
|
|
@@ -303,7 +313,7 @@ private
|
|
303
313
|
say shell.set_color(namespace, :blue, true)
|
304
314
|
say "-" * namespace.size
|
305
315
|
|
306
|
-
print_table(list, :
|
316
|
+
print_table(list, truncate: true)
|
307
317
|
say
|
308
318
|
end
|
309
319
|
alias_method :display_tasks, :display_commands
|
@@ -1,8 +1,10 @@
|
|
1
|
+
require_relative "column_printer"
|
2
|
+
require_relative "table_printer"
|
3
|
+
require_relative "wrapped_printer"
|
4
|
+
|
1
5
|
class Bundler::Thor
|
2
6
|
module Shell
|
3
7
|
class Basic
|
4
|
-
DEFAULT_TERMINAL_WIDTH = 80
|
5
|
-
|
6
8
|
attr_accessor :base
|
7
9
|
attr_reader :padding
|
8
10
|
|
@@ -145,14 +147,14 @@ class Bundler::Thor
|
|
145
147
|
# "yes".
|
146
148
|
#
|
147
149
|
def yes?(statement, color = nil)
|
148
|
-
!!(ask(statement, color, :
|
150
|
+
!!(ask(statement, color, add_to_history: false) =~ is?(:yes))
|
149
151
|
end
|
150
152
|
|
151
153
|
# Make a question the to user and returns true if the user replies "n" or
|
152
154
|
# "no".
|
153
155
|
#
|
154
156
|
def no?(statement, color = nil)
|
155
|
-
!!(ask(statement, color, :
|
157
|
+
!!(ask(statement, color, add_to_history: false) =~ is?(:no))
|
156
158
|
end
|
157
159
|
|
158
160
|
# Prints values in columns
|
@@ -161,16 +163,8 @@ class Bundler::Thor
|
|
161
163
|
# Array[String, String, ...]
|
162
164
|
#
|
163
165
|
def print_in_columns(array)
|
164
|
-
|
165
|
-
|
166
|
-
array.each_with_index do |value, index|
|
167
|
-
# Don't output trailing spaces when printing the last column
|
168
|
-
if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
|
169
|
-
stdout.puts value
|
170
|
-
else
|
171
|
-
stdout.printf("%-#{colwidth}s", value)
|
172
|
-
end
|
173
|
-
end
|
166
|
+
printer = ColumnPrinter.new(stdout)
|
167
|
+
printer.print(array)
|
174
168
|
end
|
175
169
|
|
176
170
|
# Prints a table.
|
@@ -181,58 +175,11 @@ class Bundler::Thor
|
|
181
175
|
# ==== Options
|
182
176
|
# indent<Integer>:: Indent the first column by indent value.
|
183
177
|
# colwidth<Integer>:: Force the first column to colwidth spaces wide.
|
178
|
+
# borders<Boolean>:: Adds ascii borders.
|
184
179
|
#
|
185
|
-
def print_table(array, options = {}) # rubocop:disable MethodLength
|
186
|
-
|
187
|
-
|
188
|
-
formats = []
|
189
|
-
indent = options[:indent].to_i
|
190
|
-
colwidth = options[:colwidth]
|
191
|
-
options[:truncate] = terminal_width if options[:truncate] == true
|
192
|
-
|
193
|
-
formats << "%-#{colwidth + 2}s".dup if colwidth
|
194
|
-
start = colwidth ? 1 : 0
|
195
|
-
|
196
|
-
colcount = array.max { |a, b| a.size <=> b.size }.size
|
197
|
-
|
198
|
-
maximas = []
|
199
|
-
|
200
|
-
start.upto(colcount - 1) do |index|
|
201
|
-
maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
|
202
|
-
maximas << maxima
|
203
|
-
formats << if index == colcount - 1
|
204
|
-
# Don't output 2 trailing spaces when printing the last column
|
205
|
-
"%-s".dup
|
206
|
-
else
|
207
|
-
"%-#{maxima + 2}s".dup
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
formats[0] = formats[0].insert(0, " " * indent)
|
212
|
-
formats << "%s"
|
213
|
-
|
214
|
-
array.each do |row|
|
215
|
-
sentence = "".dup
|
216
|
-
|
217
|
-
row.each_with_index do |column, index|
|
218
|
-
maxima = maximas[index]
|
219
|
-
|
220
|
-
f = if column.is_a?(Numeric)
|
221
|
-
if index == row.size - 1
|
222
|
-
# Don't output 2 trailing spaces when printing the last column
|
223
|
-
"%#{maxima}s"
|
224
|
-
else
|
225
|
-
"%#{maxima}s "
|
226
|
-
end
|
227
|
-
else
|
228
|
-
formats[index]
|
229
|
-
end
|
230
|
-
sentence << f % column.to_s
|
231
|
-
end
|
232
|
-
|
233
|
-
sentence = truncate(sentence, options[:truncate]) if options[:truncate]
|
234
|
-
stdout.puts sentence
|
235
|
-
end
|
180
|
+
def print_table(array, options = {}) # rubocop:disable Metrics/MethodLength
|
181
|
+
printer = TablePrinter.new(stdout, options)
|
182
|
+
printer.print(array)
|
236
183
|
end
|
237
184
|
|
238
185
|
# Prints a long string, word-wrapping the text to the current width of the
|
@@ -245,33 +192,8 @@ class Bundler::Thor
|
|
245
192
|
# indent<Integer>:: Indent each line of the printed paragraph by indent value.
|
246
193
|
#
|
247
194
|
def print_wrapped(message, options = {})
|
248
|
-
|
249
|
-
|
250
|
-
paras = message.split("\n\n")
|
251
|
-
|
252
|
-
paras.map! do |unwrapped|
|
253
|
-
words = unwrapped.split(" ")
|
254
|
-
counter = words.first.length
|
255
|
-
words.inject do |memo, word|
|
256
|
-
word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
|
257
|
-
counter = 0 if word.include? "\n"
|
258
|
-
if (counter + word.length + 1) < width
|
259
|
-
memo = "#{memo} #{word}"
|
260
|
-
counter += (word.length + 1)
|
261
|
-
else
|
262
|
-
memo = "#{memo}\n#{word}"
|
263
|
-
counter = word.length
|
264
|
-
end
|
265
|
-
memo
|
266
|
-
end
|
267
|
-
end.compact!
|
268
|
-
|
269
|
-
paras.each do |para|
|
270
|
-
para.split("\n").each do |line|
|
271
|
-
stdout.puts line.insert(0, " " * indent)
|
272
|
-
end
|
273
|
-
stdout.puts unless para == paras.last
|
274
|
-
end
|
195
|
+
printer = WrappedPrinter.new(stdout, options)
|
196
|
+
printer.print(message)
|
275
197
|
end
|
276
198
|
|
277
199
|
# Deals with file collision and returns true if the file should be
|
@@ -289,7 +211,7 @@ class Bundler::Thor
|
|
289
211
|
loop do
|
290
212
|
answer = ask(
|
291
213
|
%[Overwrite #{destination}? (enter "h" for help) #{options}],
|
292
|
-
:
|
214
|
+
add_to_history: false
|
293
215
|
)
|
294
216
|
|
295
217
|
case answer
|
@@ -316,24 +238,11 @@ class Bundler::Thor
|
|
316
238
|
|
317
239
|
say "Please specify merge tool to `THOR_MERGE` env."
|
318
240
|
else
|
319
|
-
say file_collision_help
|
241
|
+
say file_collision_help(block_given?)
|
320
242
|
end
|
321
243
|
end
|
322
244
|
end
|
323
245
|
|
324
|
-
# This code was copied from Rake, available under MIT-LICENSE
|
325
|
-
# Copyright (c) 2003, 2004 Jim Weirich
|
326
|
-
def terminal_width
|
327
|
-
result = if ENV["THOR_COLUMNS"]
|
328
|
-
ENV["THOR_COLUMNS"].to_i
|
329
|
-
else
|
330
|
-
unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
|
331
|
-
end
|
332
|
-
result < 10 ? DEFAULT_TERMINAL_WIDTH : result
|
333
|
-
rescue
|
334
|
-
DEFAULT_TERMINAL_WIDTH
|
335
|
-
end
|
336
|
-
|
337
246
|
# Called if something goes wrong during the execution. This is used by Bundler::Thor
|
338
247
|
# internally and should not be used inside your scripts. If something went
|
339
248
|
# wrong, you can always raise an exception. If you raise a Bundler::Thor::Error, it
|
@@ -384,16 +293,21 @@ class Bundler::Thor
|
|
384
293
|
end
|
385
294
|
end
|
386
295
|
|
387
|
-
def file_collision_help #:nodoc:
|
388
|
-
<<-HELP
|
296
|
+
def file_collision_help(block_given) #:nodoc:
|
297
|
+
help = <<-HELP
|
389
298
|
Y - yes, overwrite
|
390
299
|
n - no, do not overwrite
|
391
300
|
a - all, overwrite this and all others
|
392
301
|
q - quit, abort
|
393
|
-
d - diff, show the differences between the old and the new
|
394
302
|
h - help, show this help
|
395
|
-
m - merge, run merge tool
|
396
303
|
HELP
|
304
|
+
if block_given
|
305
|
+
help << <<-HELP
|
306
|
+
d - diff, show the differences between the old and the new
|
307
|
+
m - merge, run merge tool
|
308
|
+
HELP
|
309
|
+
end
|
310
|
+
help
|
397
311
|
end
|
398
312
|
|
399
313
|
def show_diff(destination, content) #:nodoc:
|
@@ -411,46 +325,8 @@ class Bundler::Thor
|
|
411
325
|
mute? || (base && base.options[:quiet])
|
412
326
|
end
|
413
327
|
|
414
|
-
# Calculate the dynamic width of the terminal
|
415
|
-
def dynamic_width
|
416
|
-
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
|
417
|
-
end
|
418
|
-
|
419
|
-
def dynamic_width_stty
|
420
|
-
`stty size 2>/dev/null`.split[1].to_i
|
421
|
-
end
|
422
|
-
|
423
|
-
def dynamic_width_tput
|
424
|
-
`tput cols 2>/dev/null`.to_i
|
425
|
-
end
|
426
|
-
|
427
328
|
def unix?
|
428
|
-
|
429
|
-
end
|
430
|
-
|
431
|
-
def truncate(string, width)
|
432
|
-
as_unicode do
|
433
|
-
chars = string.chars.to_a
|
434
|
-
if chars.length <= width
|
435
|
-
chars.join
|
436
|
-
else
|
437
|
-
chars[0, width - 3].join + "..."
|
438
|
-
end
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
if "".respond_to?(:encode)
|
443
|
-
def as_unicode
|
444
|
-
yield
|
445
|
-
end
|
446
|
-
else
|
447
|
-
def as_unicode
|
448
|
-
old = $KCODE
|
449
|
-
$KCODE = "U"
|
450
|
-
yield
|
451
|
-
ensure
|
452
|
-
$KCODE = old
|
453
|
-
end
|
329
|
+
Terminal.unix?
|
454
330
|
end
|
455
331
|
|
456
332
|
def ask_simply(statement, color, options)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "basic"
|
2
|
+
require_relative "lcs_diff"
|
2
3
|
|
3
4
|
class Bundler::Thor
|
4
5
|
module Shell
|
@@ -6,6 +7,8 @@ class Bundler::Thor
|
|
6
7
|
# Bundler::Thor::Shell::Basic to see all available methods.
|
7
8
|
#
|
8
9
|
class Color < Basic
|
10
|
+
include LCSDiff
|
11
|
+
|
9
12
|
# Embed in a String to clear all previous ANSI sequences.
|
10
13
|
CLEAR = "\e[0m"
|
11
14
|
# The start of an ANSI bold sequence.
|
@@ -105,52 +108,7 @@ class Bundler::Thor
|
|
105
108
|
end
|
106
109
|
|
107
110
|
def are_colors_disabled?
|
108
|
-
!ENV[
|
109
|
-
end
|
110
|
-
|
111
|
-
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
112
|
-
# available.
|
113
|
-
#
|
114
|
-
def show_diff(destination, content) #:nodoc:
|
115
|
-
if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
|
116
|
-
actual = File.binread(destination).to_s.split("\n")
|
117
|
-
content = content.to_s.split("\n")
|
118
|
-
|
119
|
-
Diff::LCS.sdiff(actual, content).each do |diff|
|
120
|
-
output_diff_line(diff)
|
121
|
-
end
|
122
|
-
else
|
123
|
-
super
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def output_diff_line(diff) #:nodoc:
|
128
|
-
case diff.action
|
129
|
-
when "-"
|
130
|
-
say "- #{diff.old_element.chomp}", :red, true
|
131
|
-
when "+"
|
132
|
-
say "+ #{diff.new_element.chomp}", :green, true
|
133
|
-
when "!"
|
134
|
-
say "- #{diff.old_element.chomp}", :red, true
|
135
|
-
say "+ #{diff.new_element.chomp}", :green, true
|
136
|
-
else
|
137
|
-
say " #{diff.old_element.chomp}", nil, true
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
142
|
-
# for diff.
|
143
|
-
#
|
144
|
-
def diff_lcs_loaded? #:nodoc:
|
145
|
-
return true if defined?(Diff::LCS)
|
146
|
-
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
147
|
-
|
148
|
-
@diff_lcs_loaded = begin
|
149
|
-
require "diff/lcs"
|
150
|
-
true
|
151
|
-
rescue LoadError
|
152
|
-
false
|
153
|
-
end
|
111
|
+
!ENV["NO_COLOR"].nil? && !ENV["NO_COLOR"].empty?
|
154
112
|
end
|
155
113
|
end
|
156
114
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_relative "terminal"
|
2
|
+
|
3
|
+
class Bundler::Thor
|
4
|
+
module Shell
|
5
|
+
class ColumnPrinter
|
6
|
+
attr_reader :stdout, :options
|
7
|
+
|
8
|
+
def initialize(stdout, options = {})
|
9
|
+
@stdout = stdout
|
10
|
+
@options = options
|
11
|
+
@indent = options[:indent].to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def print(array)
|
15
|
+
return if array.empty?
|
16
|
+
colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
|
17
|
+
array.each_with_index do |value, index|
|
18
|
+
# Don't output trailing spaces when printing the last column
|
19
|
+
if ((((index + 1) % (Terminal.terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
|
20
|
+
stdout.puts value
|
21
|
+
else
|
22
|
+
stdout.printf("%-#{colwidth}s", value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "basic"
|
2
|
+
require_relative "lcs_diff"
|
2
3
|
|
3
4
|
class Bundler::Thor
|
4
5
|
module Shell
|
@@ -6,6 +7,8 @@ class Bundler::Thor
|
|
6
7
|
# Bundler::Thor::Shell::Basic to see all available methods.
|
7
8
|
#
|
8
9
|
class HTML < Basic
|
10
|
+
include LCSDiff
|
11
|
+
|
9
12
|
# The start of an HTML bold sequence.
|
10
13
|
BOLD = "font-weight: bold"
|
11
14
|
|
@@ -76,51 +79,6 @@ class Bundler::Thor
|
|
76
79
|
def can_display_colors?
|
77
80
|
true
|
78
81
|
end
|
79
|
-
|
80
|
-
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
81
|
-
# available.
|
82
|
-
#
|
83
|
-
def show_diff(destination, content) #:nodoc:
|
84
|
-
if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
|
85
|
-
actual = File.binread(destination).to_s.split("\n")
|
86
|
-
content = content.to_s.split("\n")
|
87
|
-
|
88
|
-
Diff::LCS.sdiff(actual, content).each do |diff|
|
89
|
-
output_diff_line(diff)
|
90
|
-
end
|
91
|
-
else
|
92
|
-
super
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def output_diff_line(diff) #:nodoc:
|
97
|
-
case diff.action
|
98
|
-
when "-"
|
99
|
-
say "- #{diff.old_element.chomp}", :red, true
|
100
|
-
when "+"
|
101
|
-
say "+ #{diff.new_element.chomp}", :green, true
|
102
|
-
when "!"
|
103
|
-
say "- #{diff.old_element.chomp}", :red, true
|
104
|
-
say "+ #{diff.new_element.chomp}", :green, true
|
105
|
-
else
|
106
|
-
say " #{diff.old_element.chomp}", nil, true
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
111
|
-
# for diff.
|
112
|
-
#
|
113
|
-
def diff_lcs_loaded? #:nodoc:
|
114
|
-
return true if defined?(Diff::LCS)
|
115
|
-
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
116
|
-
|
117
|
-
@diff_lcs_loaded = begin
|
118
|
-
require "diff/lcs"
|
119
|
-
true
|
120
|
-
rescue LoadError
|
121
|
-
false
|
122
|
-
end
|
123
|
-
end
|
124
82
|
end
|
125
83
|
end
|
126
84
|
end
|