rubygems-update 3.4.21 → 3.4.22
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 +4 -4
- data/CHANGELOG.md +33 -0
- data/Manifest.txt +5 -0
- data/bundler/CHANGELOG.md +21 -0
- data/bundler/README.md +1 -2
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/gem.rb +3 -0
- data/bundler/lib/bundler/definition.rb +1 -1
- data/bundler/lib/bundler/endpoint_specification.rb +1 -1
- data/bundler/lib/bundler/errors.rb +15 -0
- data/bundler/lib/bundler/gem_helpers.rb +7 -0
- data/bundler/lib/bundler/installer/gem_installer.rb +5 -5
- data/bundler/lib/bundler/lazy_specification.rb +4 -0
- data/bundler/lib/bundler/plugin/index.rb +8 -0
- data/bundler/lib/bundler/plugin.rb +9 -2
- data/bundler/lib/bundler/rubygems_ext.rb +3 -4
- data/bundler/lib/bundler/rubygems_gem_installer.rb +23 -8
- data/bundler/lib/bundler/source/git/git_proxy.rb +9 -1
- data/bundler/lib/bundler/source/metadata.rb +1 -1
- data/bundler/lib/bundler/spec_set.rb +5 -2
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +1 -1
- data/bundler/lib/bundler/ui/shell.rb +1 -1
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +1 -0
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +21 -9
- data/bundler/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +3 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +8 -10
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +15 -4
- data/bundler/lib/bundler/vendor/thor/lib/thor/actions.rb +15 -15
- data/bundler/lib/bundler/vendor/thor/lib/thor/base.rb +140 -14
- data/bundler/lib/bundler/vendor/thor/lib/thor/command.rb +13 -4
- data/bundler/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +4 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/error.rb +16 -25
- data/bundler/lib/bundler/vendor/thor/lib/thor/group.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/invocation.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/nested_context.rb +2 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +20 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +33 -17
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/option.rb +27 -8
- data/bundler/lib/bundler/vendor/thor/lib/thor/parser/options.rb +44 -6
- data/bundler/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +2 -2
- data/bundler/lib/bundler/vendor/thor/lib/thor/runner.rb +40 -30
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +26 -150
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/color.rb +4 -46
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb +29 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/html.rb +3 -45
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb +49 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +134 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/terminal.rb +42 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb +38 -0
- data/bundler/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor/util.rb +8 -7
- data/bundler/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/bundler/lib/bundler/vendor/thor/lib/thor.rb +155 -8
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler/yaml_serializer.rb +6 -1
- data/bundler/lib/bundler.rb +0 -8
- data/lib/rubygems/command.rb +3 -3
- data/lib/rubygems/commands/cert_command.rb +1 -1
- data/lib/rubygems/commands/contents_command.rb +1 -1
- data/lib/rubygems/commands/environment_command.rb +2 -2
- data/lib/rubygems/commands/help_command.rb +1 -1
- data/lib/rubygems/commands/setup_command.rb +2 -2
- data/lib/rubygems/commands/uninstall_command.rb +4 -4
- data/lib/rubygems/commands/unpack_command.rb +3 -3
- data/lib/rubygems/commands/update_command.rb +1 -1
- data/lib/rubygems/config_file.rb +3 -3
- data/lib/rubygems/core_ext/kernel_require.rb +1 -1
- data/lib/rubygems/dependency_installer.rb +4 -4
- data/lib/rubygems/doctor.rb +1 -1
- data/lib/rubygems/ext/ext_conf_builder.rb +1 -1
- data/lib/rubygems/ext/rake_builder.rb +1 -1
- data/lib/rubygems/installer.rb +7 -12
- data/lib/rubygems/local_remote_options.rb +1 -1
- data/lib/rubygems/package/digest_io.rb +1 -1
- data/lib/rubygems/package/tar_header.rb +2 -2
- data/lib/rubygems/package/tar_reader.rb +9 -2
- data/lib/rubygems/package/tar_writer.rb +1 -1
- data/lib/rubygems/package.rb +1 -1
- data/lib/rubygems/path_support.rb +1 -1
- data/lib/rubygems/platform.rb +6 -4
- data/lib/rubygems/remote_fetcher.rb +2 -2
- data/lib/rubygems/request.rb +1 -1
- data/lib/rubygems/request_set/gem_dependency_api.rb +1 -1
- data/lib/rubygems/resolver.rb +3 -3
- data/lib/rubygems/security/trust_dir.rb +1 -1
- data/lib/rubygems/source/local.rb +2 -1
- data/lib/rubygems/source_list.rb +1 -1
- data/lib/rubygems/spec_fetcher.rb +2 -2
- data/lib/rubygems/specification.rb +21 -13
- data/lib/rubygems/specification_policy.rb +6 -6
- data/lib/rubygems/uninstaller.rb +2 -2
- data/lib/rubygems/user_interaction.rb +2 -2
- data/lib/rubygems/util/licenses.rb +48 -0
- data/lib/rubygems/validator.rb +1 -1
- data/lib/rubygems/version.rb +3 -3
- data/lib/rubygems/yaml_serializer.rb +6 -1
- data/lib/rubygems.rb +6 -6
- data/rubygems-update.gemspec +1 -1
- data/test/rubygems/helper.rb +6 -6
- data/test/rubygems/test_gem_command_manager.rb +6 -6
- data/test/rubygems/test_gem_commands_cert_command.rb +1 -1
- data/test/rubygems/test_gem_commands_install_command.rb +2 -2
- data/test/rubygems/test_gem_commands_uninstall_command.rb +20 -0
- data/test/rubygems/test_gem_ext_builder.rb +1 -1
- data/test/rubygems/test_gem_installer.rb +1 -1
- data/test/rubygems/test_gem_package_tar_reader.rb +15 -0
- data/test/rubygems/test_gem_security_policy.rb +2 -2
- data/test/rubygems/test_gem_stream_ui.rb +1 -1
- data/test/rubygems/utilities.rb +2 -2
- 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
|