[rubygems/rubygems] Update vendored thor to v1.3.0
See https://github.com/rails/thor/releases/tag/v1.3.0 https://github.com/rubygems/rubygems/commit/3c7165474b
This commit is contained in:
parent
3e65115cef
commit
af222d4db2
@ -147,7 +147,7 @@ module Bundler
|
||||
spaces ? text.gsub(/#{spaces}/, "") : text
|
||||
end
|
||||
|
||||
def word_wrap(text, line_width = @shell.terminal_width)
|
||||
def word_wrap(text, line_width = Thor::Terminal.terminal_width)
|
||||
strip_leading_spaces(text).split("\n").collect do |line|
|
||||
line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
|
||||
end * "\n"
|
||||
|
161
lib/bundler/vendor/thor/lib/thor.rb
vendored
161
lib/bundler/vendor/thor/lib/thor.rb
vendored
@ -65,8 +65,15 @@ class Bundler::Thor
|
||||
|
||||
# Defines the long description of the next command.
|
||||
#
|
||||
# Long description is by default indented, line-wrapped and repeated whitespace merged.
|
||||
# In order to print long description verbatim, with indentation and spacing exactly
|
||||
# as found in the code, use the +wrap+ option
|
||||
#
|
||||
# long_desc 'your very long description', wrap: false
|
||||
#
|
||||
# ==== Parameters
|
||||
# long description<String>
|
||||
# options<Hash>
|
||||
#
|
||||
def long_desc(long_description, options = {})
|
||||
if options[:for]
|
||||
@ -74,6 +81,7 @@ class Bundler::Thor
|
||||
command.long_description = long_description if long_description
|
||||
else
|
||||
@long_desc = long_description
|
||||
@long_desc_wrap = options[:wrap] != false
|
||||
end
|
||||
end
|
||||
|
||||
@ -133,7 +141,7 @@ class Bundler::Thor
|
||||
# # magic
|
||||
# end
|
||||
#
|
||||
# method_option :foo => :bar, :for => :previous_command
|
||||
# method_option :foo, :for => :previous_command
|
||||
#
|
||||
# def next_command
|
||||
# # magic
|
||||
@ -153,6 +161,9 @@ class Bundler::Thor
|
||||
# :hide - If you want to hide this option from the help.
|
||||
#
|
||||
def method_option(name, options = {})
|
||||
unless [ Symbol, String ].any? { |klass| name.is_a?(klass) }
|
||||
raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}"
|
||||
end
|
||||
scope = if options[:for]
|
||||
find_and_refresh_command(options[:for]).options
|
||||
else
|
||||
@ -163,6 +174,81 @@ class Bundler::Thor
|
||||
end
|
||||
alias_method :option, :method_option
|
||||
|
||||
# Adds and declares option group for exclusive options in the
|
||||
# block and arguments. You can declare options as the outside of the block.
|
||||
#
|
||||
# If :for is given as option, it allows you to change the options from
|
||||
# a previous defined command.
|
||||
#
|
||||
# ==== Parameters
|
||||
# Array[Bundler::Thor::Option.name]
|
||||
# options<Hash>:: :for is applied for previous defined command.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# exclusive do
|
||||
# option :one
|
||||
# option :two
|
||||
# end
|
||||
#
|
||||
# Or
|
||||
#
|
||||
# option :one
|
||||
# option :two
|
||||
# exclusive :one, :two
|
||||
#
|
||||
# If you give "--one" and "--two" at the same time ExclusiveArgumentsError
|
||||
# will be raised.
|
||||
#
|
||||
def method_exclusive(*args, &block)
|
||||
register_options_relation_for(:method_options,
|
||||
:method_exclusive_option_names, *args, &block)
|
||||
end
|
||||
alias_method :exclusive, :method_exclusive
|
||||
|
||||
# Adds and declares option group for required at least one of options in the
|
||||
# block of arguments. You can declare options as the outside of the block.
|
||||
#
|
||||
# If :for is given as option, it allows you to change the options from
|
||||
# a previous defined command.
|
||||
#
|
||||
# ==== Parameters
|
||||
# Array[Bundler::Thor::Option.name]
|
||||
# options<Hash>:: :for is applied for previous defined command.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# at_least_one do
|
||||
# option :one
|
||||
# option :two
|
||||
# end
|
||||
#
|
||||
# Or
|
||||
#
|
||||
# option :one
|
||||
# option :two
|
||||
# at_least_one :one, :two
|
||||
#
|
||||
# If you do not give "--one" and "--two" AtLeastOneRequiredArgumentError
|
||||
# will be raised.
|
||||
#
|
||||
# You can use at_least_one and exclusive at the same time.
|
||||
#
|
||||
# exclusive do
|
||||
# at_least_one do
|
||||
# option :one
|
||||
# option :two
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Then it is required either only one of "--one" or "--two".
|
||||
#
|
||||
def method_at_least_one(*args, &block)
|
||||
register_options_relation_for(:method_options,
|
||||
:method_at_least_one_option_names, *args, &block)
|
||||
end
|
||||
alias_method :at_least_one, :method_at_least_one
|
||||
|
||||
# Prints help information for the given command.
|
||||
#
|
||||
# ==== Parameters
|
||||
@ -178,9 +264,16 @@ class Bundler::Thor
|
||||
shell.say " #{banner(command).split("\n").join("\n ")}"
|
||||
shell.say
|
||||
class_options_help(shell, nil => command.options.values)
|
||||
print_exclusive_options(shell, command)
|
||||
print_at_least_one_required_options(shell, command)
|
||||
|
||||
if command.long_description
|
||||
shell.say "Description:"
|
||||
shell.print_wrapped(command.long_description, :indent => 2)
|
||||
if command.wrap_long_description
|
||||
shell.print_wrapped(command.long_description, indent: 2)
|
||||
else
|
||||
shell.say command.long_description
|
||||
end
|
||||
else
|
||||
shell.say command.description
|
||||
end
|
||||
@ -197,7 +290,7 @@ class Bundler::Thor
|
||||
Bundler::Thor::Util.thor_classes_in(self).each do |klass|
|
||||
list += klass.printable_commands(false)
|
||||
end
|
||||
list.sort! { |a, b| a[0] <=> b[0] }
|
||||
sort_commands!(list)
|
||||
|
||||
if defined?(@package_name) && @package_name
|
||||
shell.say "#{@package_name} commands:"
|
||||
@ -205,9 +298,11 @@ class Bundler::Thor
|
||||
shell.say "Commands:"
|
||||
end
|
||||
|
||||
shell.print_table(list, :indent => 2, :truncate => true)
|
||||
shell.print_table(list, indent: 2, truncate: true)
|
||||
shell.say
|
||||
class_options_help(shell)
|
||||
print_exclusive_options(shell)
|
||||
print_at_least_one_required_options(shell)
|
||||
end
|
||||
|
||||
# Returns commands ready to be printed.
|
||||
@ -238,7 +333,7 @@ class Bundler::Thor
|
||||
|
||||
define_method(subcommand) do |*args|
|
||||
args, opts = Bundler::Thor::Arguments.split(args)
|
||||
invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}]
|
||||
invoke_args = [args, opts, {invoked_via_subcommand: true, class_options: options}]
|
||||
invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
|
||||
invoke subcommand_class, *invoke_args
|
||||
end
|
||||
@ -346,6 +441,24 @@ class Bundler::Thor
|
||||
|
||||
protected
|
||||
|
||||
# Returns this class exclusive options array set.
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[Array[Bundler::Thor::Option.name]]
|
||||
#
|
||||
def method_exclusive_option_names #:nodoc:
|
||||
@method_exclusive_option_names ||= []
|
||||
end
|
||||
|
||||
# Returns this class at least one of required options array set.
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[Array[Bundler::Thor::Option.name]]
|
||||
#
|
||||
def method_at_least_one_option_names #:nodoc:
|
||||
@method_at_least_one_option_names ||= []
|
||||
end
|
||||
|
||||
def stop_on_unknown_option #:nodoc:
|
||||
@stop_on_unknown_option ||= []
|
||||
end
|
||||
@ -355,6 +468,28 @@ class Bundler::Thor
|
||||
@disable_required_check ||= [:help]
|
||||
end
|
||||
|
||||
def print_exclusive_options(shell, command = nil) # :nodoc:
|
||||
opts = []
|
||||
opts = command.method_exclusive_option_names unless command.nil?
|
||||
opts += class_exclusive_option_names
|
||||
unless opts.empty?
|
||||
shell.say "Exclusive Options:"
|
||||
shell.print_table(opts.map{ |ex| ex.map{ |e| "--#{e}"}}, indent: 2 )
|
||||
shell.say
|
||||
end
|
||||
end
|
||||
|
||||
def print_at_least_one_required_options(shell, command = nil) # :nodoc:
|
||||
opts = []
|
||||
opts = command.method_at_least_one_option_names unless command.nil?
|
||||
opts += class_at_least_one_option_names
|
||||
unless opts.empty?
|
||||
shell.say "Required At Least One:"
|
||||
shell.print_table(opts.map{ |ex| ex.map{ |e| "--#{e}"}}, indent: 2 )
|
||||
shell.say
|
||||
end
|
||||
end
|
||||
|
||||
# The method responsible for dispatching given the args.
|
||||
def dispatch(meth, given_args, given_opts, config) #:nodoc:
|
||||
meth ||= retrieve_command_name(given_args)
|
||||
@ -415,12 +550,16 @@ class Bundler::Thor
|
||||
@usage ||= nil
|
||||
@desc ||= nil
|
||||
@long_desc ||= nil
|
||||
@long_desc_wrap ||= nil
|
||||
@hide ||= nil
|
||||
|
||||
if @usage && @desc
|
||||
base_class = @hide ? Bundler::Thor::HiddenCommand : Bundler::Thor::Command
|
||||
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
|
||||
@usage, @desc, @long_desc, @method_options, @hide = nil
|
||||
relations = {exclusive_option_names: method_exclusive_option_names,
|
||||
at_least_one_option_names: method_at_least_one_option_names}
|
||||
commands[meth] = base_class.new(meth, @desc, @long_desc, @long_desc_wrap, @usage, method_options, relations)
|
||||
@usage, @desc, @long_desc, @long_desc_wrap, @method_options, @hide = nil
|
||||
@method_exclusive_option_names, @method_at_least_one_option_names = nil
|
||||
true
|
||||
elsif all_commands[meth] || meth == "method_missing"
|
||||
true
|
||||
@ -495,6 +634,14 @@ class Bundler::Thor
|
||||
"
|
||||
end
|
||||
alias_method :subtask_help, :subcommand_help
|
||||
|
||||
# Sort the commands, lexicographically by default.
|
||||
#
|
||||
# Can be overridden in the subclass to change the display order of the
|
||||
# commands.
|
||||
def sort_commands!(list)
|
||||
list.sort! { |a, b| a[0] <=> b[0] }
|
||||
end
|
||||
end
|
||||
|
||||
include Bundler::Thor::Base
|
||||
|
29
lib/bundler/vendor/thor/lib/thor/actions.rb
vendored
29
lib/bundler/vendor/thor/lib/thor/actions.rb
vendored
@ -46,17 +46,17 @@ class Bundler::Thor
|
||||
# Add runtime options that help actions execution.
|
||||
#
|
||||
def add_runtime_options!
|
||||
class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
|
||||
:desc => "Overwrite files that already exist"
|
||||
class_option :force, type: :boolean, aliases: "-f", group: :runtime,
|
||||
desc: "Overwrite files that already exist"
|
||||
|
||||
class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
|
||||
:desc => "Run but do not make any changes"
|
||||
class_option :pretend, type: :boolean, aliases: "-p", group: :runtime,
|
||||
desc: "Run but do not make any changes"
|
||||
|
||||
class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
|
||||
:desc => "Suppress status output"
|
||||
class_option :quiet, type: :boolean, aliases: "-q", group: :runtime,
|
||||
desc: "Suppress status output"
|
||||
|
||||
class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
|
||||
:desc => "Skip files that already exist"
|
||||
class_option :skip, type: :boolean, aliases: "-s", group: :runtime,
|
||||
desc: "Skip files that already exist"
|
||||
end
|
||||
end
|
||||
|
||||
@ -113,9 +113,9 @@ class Bundler::Thor
|
||||
#
|
||||
def relative_to_original_destination_root(path, remove_dot = true)
|
||||
root = @destination_stack[0]
|
||||
if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
|
||||
if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ""].include?(path[root.size..root.size])
|
||||
path = path.dup
|
||||
path[0...root.size] = '.'
|
||||
path[0...root.size] = "."
|
||||
remove_dot ? (path[2..-1] || "") : path
|
||||
else
|
||||
path
|
||||
@ -223,8 +223,7 @@ class Bundler::Thor
|
||||
|
||||
contents = if is_uri
|
||||
require "open-uri"
|
||||
# for ruby 2.1-2.4
|
||||
URI.send(:open, path, "Accept" => "application/x-thor-template", &:read)
|
||||
URI.open(path, "Accept" => "application/x-thor-template", &:read)
|
||||
else
|
||||
File.open(path, &:read)
|
||||
end
|
||||
@ -285,7 +284,7 @@ class Bundler::Thor
|
||||
#
|
||||
def run_ruby_script(command, config = {})
|
||||
return unless behavior == :invoke
|
||||
run command, config.merge(:with => Bundler::Thor::Util.ruby_command)
|
||||
run command, config.merge(with: Bundler::Thor::Util.ruby_command)
|
||||
end
|
||||
|
||||
# Run a thor command. A hash of options can be given and it's converted to
|
||||
@ -316,7 +315,7 @@ class Bundler::Thor
|
||||
args.push Bundler::Thor::Options.to_switches(config)
|
||||
command = args.join(" ").strip
|
||||
|
||||
run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
|
||||
run command, with: :thor, verbose: verbose, pretend: pretend, capture: capture
|
||||
end
|
||||
|
||||
protected
|
||||
@ -324,7 +323,7 @@ class Bundler::Thor
|
||||
# Allow current root to be shared between invocations.
|
||||
#
|
||||
def _shared_configuration #:nodoc:
|
||||
super.merge!(:destination_root => destination_root)
|
||||
super.merge!(destination_root: destination_root)
|
||||
end
|
||||
|
||||
def _cleanup_options_and_set(options, key) #:nodoc:
|
||||
|
@ -43,7 +43,8 @@ class Bundler::Thor
|
||||
# Boolean:: true if it is identical, false otherwise.
|
||||
#
|
||||
def identical?
|
||||
exists? && File.binread(destination) == render
|
||||
# binread uses ASCII-8BIT, so to avoid false negatives, the string must use the same
|
||||
exists? && File.binread(destination) == String.new(render).force_encoding("ASCII-8BIT")
|
||||
end
|
||||
|
||||
# Holds the content to be added to the file.
|
||||
|
@ -58,7 +58,7 @@ class Bundler::Thor
|
||||
def initialize(base, source, destination = nil, config = {}, &block)
|
||||
@source = File.expand_path(Dir[Util.escape_globs(base.find_in_source_paths(source.to_s))].first)
|
||||
@block = block
|
||||
super(base, destination, {:recursive => true}.merge(config))
|
||||
super(base, destination, {recursive: true}.merge(config))
|
||||
end
|
||||
|
||||
def invoke!
|
||||
|
@ -33,7 +33,7 @@ class Bundler::Thor
|
||||
#
|
||||
def initialize(base, destination, config = {})
|
||||
@base = base
|
||||
@config = {:verbose => true}.merge(config)
|
||||
@config = {verbose: true}.merge(config)
|
||||
self.destination = destination
|
||||
end
|
||||
|
||||
|
@ -66,12 +66,15 @@ class Bundler::Thor
|
||||
# ==== Parameters
|
||||
# source<String>:: the address of the given content.
|
||||
# destination<String>:: the relative path to the destination root.
|
||||
# config<Hash>:: give :verbose => false to not log the status.
|
||||
# config<Hash>:: give :verbose => false to not log the status, and
|
||||
# :http_headers => <Hash> to add headers to an http request.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# get "http://gist.github.com/103208", "doc/README"
|
||||
#
|
||||
# get "http://gist.github.com/103208", "doc/README", :http_headers => {"Content-Type" => "application/json"}
|
||||
#
|
||||
# get "http://gist.github.com/103208" do |content|
|
||||
# content.split("\n").first
|
||||
# end
|
||||
@ -82,7 +85,7 @@ class Bundler::Thor
|
||||
|
||||
render = if source =~ %r{^https?\://}
|
||||
require "open-uri"
|
||||
URI.send(:open, source) { |input| input.binmode.read }
|
||||
URI.send(:open, source, config.fetch(:http_headers, {})) { |input| input.binmode.read }
|
||||
else
|
||||
source = File.expand_path(find_in_source_paths(source.to_s))
|
||||
File.open(source) { |input| input.binmode.read }
|
||||
@ -120,12 +123,7 @@ class Bundler::Thor
|
||||
context = config.delete(:context) || instance_eval("binding")
|
||||
|
||||
create_file destination, nil, config do
|
||||
match = ERB.version.match(/(\d+\.\d+\.\d+)/)
|
||||
capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
|
||||
CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
|
||||
else
|
||||
CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
|
||||
end
|
||||
capturable_erb = CapturableERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer")
|
||||
content = capturable_erb.tap do |erb|
|
||||
erb.filename = source
|
||||
end.result(context)
|
||||
|
@ -21,7 +21,7 @@ class Bundler::Thor
|
||||
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
|
||||
# end
|
||||
#
|
||||
WARNINGS = { unchanged_no_flag: 'File unchanged! Either the supplied flag value not found or the content has already been inserted!' }
|
||||
WARNINGS = {unchanged_no_flag: "File unchanged! Either the supplied flag value not found or the content has already been inserted!"}
|
||||
|
||||
def insert_into_file(destination, *args, &block)
|
||||
data = block_given? ? block : args.shift
|
||||
@ -37,7 +37,7 @@ class Bundler::Thor
|
||||
attr_reader :replacement, :flag, :behavior
|
||||
|
||||
def initialize(base, destination, data, config)
|
||||
super(base, destination, {:verbose => true}.merge(config))
|
||||
super(base, destination, {verbose: true}.merge(config))
|
||||
|
||||
@behavior, @flag = if @config.key?(:after)
|
||||
[:after, @config.delete(:after)]
|
||||
@ -59,6 +59,8 @@ class Bundler::Thor
|
||||
if exists?
|
||||
if replace!(/#{flag}/, content, config[:force])
|
||||
say_status(:invoke)
|
||||
elsif replacement_present?
|
||||
say_status(:unchanged, color: :blue)
|
||||
else
|
||||
say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red)
|
||||
end
|
||||
@ -96,6 +98,8 @@ class Bundler::Thor
|
||||
end
|
||||
elsif warning
|
||||
warning
|
||||
elsif behavior == :unchanged
|
||||
:unchanged
|
||||
else
|
||||
:subtract
|
||||
end
|
||||
@ -103,11 +107,18 @@ class Bundler::Thor
|
||||
super(status, (color || config[:verbose]))
|
||||
end
|
||||
|
||||
def content
|
||||
@content ||= File.read(destination)
|
||||
end
|
||||
|
||||
def replacement_present?
|
||||
content.include?(replacement)
|
||||
end
|
||||
|
||||
# Adds the content to the file.
|
||||
#
|
||||
def replace!(regexp, string, force)
|
||||
content = File.read(destination)
|
||||
if force || !content.include?(replacement)
|
||||
if force || !replacement_present?
|
||||
success = content.gsub!(regexp, string)
|
||||
|
||||
File.open(destination, "wb") { |file| file.write(content) } unless pretend?
|
||||
|
145
lib/bundler/vendor/thor/lib/thor/base.rb
vendored
145
lib/bundler/vendor/thor/lib/thor/base.rb
vendored
@ -24,9 +24,9 @@ class Bundler::Thor
|
||||
|
||||
class << self
|
||||
def deprecation_warning(message) #:nodoc:
|
||||
unless ENV['THOR_SILENCE_DEPRECATION']
|
||||
unless ENV["THOR_SILENCE_DEPRECATION"]
|
||||
warn "Deprecation warning: #{message}\n" +
|
||||
'You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION.'
|
||||
"You can silence deprecations warning by setting the environment variable THOR_SILENCE_DEPRECATION."
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -60,6 +60,7 @@ class Bundler::Thor
|
||||
|
||||
command_options = config.delete(:command_options) # hook for start
|
||||
parse_options = parse_options.merge(command_options) if command_options
|
||||
|
||||
if local_options.is_a?(Array)
|
||||
array_options = local_options
|
||||
hash_options = {}
|
||||
@ -73,9 +74,24 @@ class Bundler::Thor
|
||||
# Let Bundler::Thor::Options parse the options first, so it can remove
|
||||
# declared options from the array. This will leave us with
|
||||
# a list of arguments that weren't declared.
|
||||
stop_on_unknown = self.class.stop_on_unknown_option? config[:current_command]
|
||||
disable_required_check = self.class.disable_required_check? config[:current_command]
|
||||
opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check)
|
||||
current_command = config[:current_command]
|
||||
stop_on_unknown = self.class.stop_on_unknown_option? current_command
|
||||
|
||||
# Give a relation of options.
|
||||
# After parsing, Bundler::Thor::Options check whether right relations are kept
|
||||
relations = if current_command.nil?
|
||||
{exclusive_option_names: [], at_least_one_option_names: []}
|
||||
else
|
||||
current_command.options_relation
|
||||
end
|
||||
|
||||
self.class.class_exclusive_option_names.map { |n| relations[:exclusive_option_names] << n }
|
||||
self.class.class_at_least_one_option_names.map { |n| relations[:at_least_one_option_names] << n }
|
||||
|
||||
disable_required_check = self.class.disable_required_check? current_command
|
||||
|
||||
opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown, disable_required_check, relations)
|
||||
|
||||
self.options = opts.parse(array_options)
|
||||
self.options = config[:class_options].merge(options) if config[:class_options]
|
||||
|
||||
@ -310,9 +326,92 @@ class Bundler::Thor
|
||||
# :hide:: -- If you want to hide this option from the help.
|
||||
#
|
||||
def class_option(name, options = {})
|
||||
unless [ Symbol, String ].any? { |klass| name.is_a?(klass) }
|
||||
raise ArgumentError, "Expected a Symbol or String, got #{name.inspect}"
|
||||
end
|
||||
build_option(name, options, class_options)
|
||||
end
|
||||
|
||||
# Adds and declares option group for exclusive options in the
|
||||
# block and arguments. You can declare options as the outside of the block.
|
||||
#
|
||||
# ==== Parameters
|
||||
# Array[Bundler::Thor::Option.name]
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# class_exclusive do
|
||||
# class_option :one
|
||||
# class_option :two
|
||||
# end
|
||||
#
|
||||
# Or
|
||||
#
|
||||
# class_option :one
|
||||
# class_option :two
|
||||
# class_exclusive :one, :two
|
||||
#
|
||||
# If you give "--one" and "--two" at the same time ExclusiveArgumentsError
|
||||
# will be raised.
|
||||
#
|
||||
def class_exclusive(*args, &block)
|
||||
register_options_relation_for(:class_options,
|
||||
:class_exclusive_option_names, *args, &block)
|
||||
end
|
||||
|
||||
# Adds and declares option group for required at least one of options in the
|
||||
# block and arguments. You can declare options as the outside of the block.
|
||||
#
|
||||
# ==== Examples
|
||||
#
|
||||
# class_at_least_one do
|
||||
# class_option :one
|
||||
# class_option :two
|
||||
# end
|
||||
#
|
||||
# Or
|
||||
#
|
||||
# class_option :one
|
||||
# class_option :two
|
||||
# class_at_least_one :one, :two
|
||||
#
|
||||
# If you do not give "--one" and "--two" AtLeastOneRequiredArgumentError
|
||||
# will be raised.
|
||||
#
|
||||
# You can use class_at_least_one and class_exclusive at the same time.
|
||||
#
|
||||
# class_exclusive do
|
||||
# class_at_least_one do
|
||||
# class_option :one
|
||||
# class_option :two
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Then it is required either only one of "--one" or "--two".
|
||||
#
|
||||
def class_at_least_one(*args, &block)
|
||||
register_options_relation_for(:class_options,
|
||||
:class_at_least_one_option_names, *args, &block)
|
||||
end
|
||||
|
||||
# Returns this class exclusive options array set, looking up in the ancestors chain.
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[Array[Bundler::Thor::Option.name]]
|
||||
#
|
||||
def class_exclusive_option_names
|
||||
@class_exclusive_option_names ||= from_superclass(:class_exclusive_option_names, [])
|
||||
end
|
||||
|
||||
# Returns this class at least one of required options array set, looking up in the ancestors chain.
|
||||
#
|
||||
# ==== Returns
|
||||
# Array[Array[Bundler::Thor::Option.name]]
|
||||
#
|
||||
def class_at_least_one_option_names
|
||||
@class_at_least_one_option_names ||= from_superclass(:class_at_least_one_option_names, [])
|
||||
end
|
||||
|
||||
# Removes a previous defined argument. If :undefine is given, undefine
|
||||
# accessors as well.
|
||||
#
|
||||
@ -565,12 +664,12 @@ class Bundler::Thor
|
||||
item.push(option.description ? "# #{option.description}" : "")
|
||||
|
||||
list << item
|
||||
list << ["", "# Default: #{option.default}"] if option.show_default?
|
||||
list << ["", "# Possible values: #{option.enum.join(', ')}"] if option.enum
|
||||
list << ["", "# Default: #{option.print_default}"] if option.show_default?
|
||||
list << ["", "# Possible values: #{option.enum_to_s}"] if option.enum
|
||||
end
|
||||
|
||||
shell.say(group_name ? "#{group_name} options:" : "Options:")
|
||||
shell.print_table(list, :indent => 2)
|
||||
shell.print_table(list, indent: 2)
|
||||
shell.say ""
|
||||
end
|
||||
|
||||
@ -587,7 +686,7 @@ class Bundler::Thor
|
||||
# options<Hash>:: Described in both class_option and method_option.
|
||||
# scope<Hash>:: Options hash that is being built up
|
||||
def build_option(name, options, scope) #:nodoc:
|
||||
scope[name] = Bundler::Thor::Option.new(name, {:check_default_type => check_default_type}.merge!(options))
|
||||
scope[name] = Bundler::Thor::Option.new(name, {check_default_type: check_default_type}.merge!(options))
|
||||
end
|
||||
|
||||
# Receives a hash of options, parse them and add to the scope. This is a
|
||||
@ -693,6 +792,34 @@ class Bundler::Thor
|
||||
def dispatch(command, given_args, given_opts, config) #:nodoc:
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Register a relation of options for target(method_option/class_option)
|
||||
# by args and block.
|
||||
def register_options_relation_for(target, relation, *args, &block) # :nodoc:
|
||||
opt = args.pop if args.last.is_a? Hash
|
||||
opt ||= {}
|
||||
names = args.map{ |arg| arg.to_s }
|
||||
names += built_option_names(target, opt, &block) if block_given?
|
||||
command_scope_member(relation, opt) << names
|
||||
end
|
||||
|
||||
# Get target(method_options or class_options) options
|
||||
# of before and after by block evaluation.
|
||||
def built_option_names(target, opt = {}, &block) # :nodoc:
|
||||
before = command_scope_member(target, opt).map{ |k,v| v.name }
|
||||
instance_eval(&block)
|
||||
after = command_scope_member(target, opt).map{ |k,v| v.name }
|
||||
after - before
|
||||
end
|
||||
|
||||
# Get command scope member by name.
|
||||
def command_scope_member(name, options = {}) # :nodoc:
|
||||
if options[:for]
|
||||
find_and_refresh_command(options[:for]).send(name)
|
||||
else
|
||||
send(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
17
lib/bundler/vendor/thor/lib/thor/command.rb
vendored
17
lib/bundler/vendor/thor/lib/thor/command.rb
vendored
@ -1,14 +1,15 @@
|
||||
class Bundler::Thor
|
||||
class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name)
|
||||
class Command < Struct.new(:name, :description, :long_description, :wrap_long_description, :usage, :options, :options_relation, :ancestor_name)
|
||||
FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/
|
||||
|
||||
def initialize(name, description, long_description, usage, options = nil)
|
||||
super(name.to_s, description, long_description, usage, options || {})
|
||||
def initialize(name, description, long_description, wrap_long_description, usage, options = nil, options_relation = nil)
|
||||
super(name.to_s, description, long_description, wrap_long_description, usage, options || {}, options_relation || {})
|
||||
end
|
||||
|
||||
def initialize_copy(other) #:nodoc:
|
||||
super(other)
|
||||
self.options = other.options.dup if other.options
|
||||
self.options_relation = other.options_relation.dup if other.options_relation
|
||||
end
|
||||
|
||||
def hidden?
|
||||
@ -62,6 +63,14 @@ class Bundler::Thor
|
||||
end.join("\n")
|
||||
end
|
||||
|
||||
def method_exclusive_option_names #:nodoc:
|
||||
self.options_relation[:exclusive_option_names] || []
|
||||
end
|
||||
|
||||
def method_at_least_one_option_names #:nodoc:
|
||||
self.options_relation[:at_least_one_option_names] || []
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Add usage with required arguments
|
||||
@ -127,7 +136,7 @@ class Bundler::Thor
|
||||
# A dynamic command that handles method missing scenarios.
|
||||
class DynamicCommand < Command
|
||||
def initialize(name, options = nil)
|
||||
super(name.to_s, "A dynamically-generated command", name.to_s, name.to_s, options)
|
||||
super(name.to_s, "A dynamically-generated command", name.to_s, nil, name.to_s, options)
|
||||
end
|
||||
|
||||
def run(instance, args = [])
|
||||
|
@ -38,6 +38,10 @@ class Bundler::Thor
|
||||
super(convert_key(key), *args)
|
||||
end
|
||||
|
||||
def slice(*keys)
|
||||
super(*keys.map{ |key| convert_key(key) })
|
||||
end
|
||||
|
||||
def key?(key)
|
||||
super(convert_key(key))
|
||||
end
|
||||
|
39
lib/bundler/vendor/thor/lib/thor/error.rb
vendored
39
lib/bundler/vendor/thor/lib/thor/error.rb
vendored
@ -1,26 +1,15 @@
|
||||
class Bundler::Thor
|
||||
Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
|
||||
# In order to support versions of Ruby that don't have keyword
|
||||
# arguments, we need our own spell checker class that doesn't take key
|
||||
# words. Even though this code wouldn't be hit because of the check
|
||||
# above, it's still necessary because the interpreter would otherwise be
|
||||
# unable to parse the file.
|
||||
class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
|
||||
def initialize(dictionary)
|
||||
@dictionary = dictionary
|
||||
end
|
||||
end
|
||||
Module.new do
|
||||
def to_s
|
||||
super + DidYouMean.formatter.message_for(corrections)
|
||||
end
|
||||
|
||||
Module.new do
|
||||
def to_s
|
||||
super + DidYouMean.formatter.message_for(corrections)
|
||||
end
|
||||
|
||||
def corrections
|
||||
@corrections ||= self.class.const_get(:SpellChecker).new(self).corrections
|
||||
end
|
||||
end
|
||||
end
|
||||
def corrections
|
||||
@corrections ||= self.class.const_get(:SpellChecker).new(self).corrections
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
|
||||
# errors have their backtrace suppressed and are nicely shown to the user.
|
||||
@ -45,7 +34,7 @@ class Bundler::Thor
|
||||
end
|
||||
|
||||
def spell_checker
|
||||
NoKwargSpellChecker.new(error.all_commands)
|
||||
DidYouMean::SpellChecker.new(dictionary: error.all_commands)
|
||||
end
|
||||
end
|
||||
|
||||
@ -87,7 +76,7 @@ class Bundler::Thor
|
||||
end
|
||||
|
||||
def spell_checker
|
||||
@spell_checker ||= NoKwargSpellChecker.new(error.switches)
|
||||
@spell_checker ||= DidYouMean::SpellChecker.new(dictionary: error.switches)
|
||||
end
|
||||
end
|
||||
|
||||
@ -108,4 +97,10 @@ class Bundler::Thor
|
||||
|
||||
class MalformattedArgumentError < InvocationError
|
||||
end
|
||||
|
||||
class ExclusiveArgumentError < InvocationError
|
||||
end
|
||||
|
||||
class AtLeastOneRequiredArgumentError < InvocationError
|
||||
end
|
||||
end
|
||||
|
@ -143,7 +143,7 @@ class Bundler::Thor
|
||||
|
||||
# Configuration values that are shared between invocations.
|
||||
def _shared_configuration #:nodoc:
|
||||
{:invocations => @_invocations}
|
||||
{invocations: @_invocations}
|
||||
end
|
||||
|
||||
# This method simply retrieves the class and command to be invoked.
|
||||
|
@ -13,10 +13,10 @@ class Bundler::Thor
|
||||
end
|
||||
|
||||
def entered?
|
||||
@depth > 0
|
||||
@depth.positive?
|
||||
end
|
||||
|
||||
private
|
||||
private
|
||||
|
||||
def push
|
||||
@depth += 1
|
||||
|
@ -24,6 +24,17 @@ class Bundler::Thor
|
||||
validate! # Trigger specific validations
|
||||
end
|
||||
|
||||
def print_default
|
||||
if @type == :array and @default.is_a?(Array)
|
||||
@default.map { |x|
|
||||
p = x.gsub('"','\\"')
|
||||
"\"#{p}\""
|
||||
}.join(" ")
|
||||
else
|
||||
@default
|
||||
end
|
||||
end
|
||||
|
||||
def usage
|
||||
required? ? banner : "[#{banner}]"
|
||||
end
|
||||
@ -41,11 +52,19 @@ class Bundler::Thor
|
||||
end
|
||||
end
|
||||
|
||||
def enum_to_s
|
||||
if enum.respond_to? :join
|
||||
enum.join(", ")
|
||||
else
|
||||
"#{enum.first}..#{enum.last}"
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def validate!
|
||||
raise ArgumentError, "An argument cannot be required and have default value." if required? && !default.nil?
|
||||
raise ArgumentError, "An argument cannot have an enum other than an array." if @enum && !@enum.is_a?(Array)
|
||||
raise ArgumentError, "An argument cannot have an enum other than an enumerable." if @enum && !@enum.is_a?(Enumerable)
|
||||
end
|
||||
|
||||
def valid_type?(type)
|
||||
|
@ -30,11 +30,7 @@ class Bundler::Thor
|
||||
|
||||
arguments.each do |argument|
|
||||
if !argument.default.nil?
|
||||
begin
|
||||
@assigns[argument.human_name] = argument.default.dup
|
||||
rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
|
||||
@assigns[argument.human_name] = argument.default
|
||||
end
|
||||
@assigns[argument.human_name] = argument.default.dup
|
||||
elsif argument.required?
|
||||
@non_assigned_required << argument
|
||||
end
|
||||
@ -121,8 +117,18 @@ class Bundler::Thor
|
||||
#
|
||||
def parse_array(name)
|
||||
return shift if peek.is_a?(Array)
|
||||
|
||||
array = []
|
||||
array << shift while current_is_value?
|
||||
|
||||
while current_is_value?
|
||||
value = shift
|
||||
|
||||
if !value.empty?
|
||||
validate_enum_value!(name, value, "Expected all values of '%s' to be one of %s; got %s")
|
||||
end
|
||||
|
||||
array << value
|
||||
end
|
||||
array
|
||||
end
|
||||
|
||||
@ -138,11 +144,9 @@ class Bundler::Thor
|
||||
end
|
||||
|
||||
value = $&.index(".") ? shift.to_f : shift.to_i
|
||||
if @switches.is_a?(Hash) && switch = @switches[name]
|
||||
if switch.enum && !switch.enum.include?(value)
|
||||
raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
|
||||
end
|
||||
end
|
||||
|
||||
validate_enum_value!(name, value, "Expected '%s' to be one of %s; got %s")
|
||||
|
||||
value
|
||||
end
|
||||
|
||||
@ -156,15 +160,27 @@ class Bundler::Thor
|
||||
nil
|
||||
else
|
||||
value = shift
|
||||
if @switches.is_a?(Hash) && switch = @switches[name]
|
||||
if switch.enum && !switch.enum.include?(value)
|
||||
raise MalformattedArgumentError, "Expected '#{name}' to be one of #{switch.enum.join(', ')}; got #{value}"
|
||||
end
|
||||
end
|
||||
|
||||
validate_enum_value!(name, value, "Expected '%s' to be one of %s; got %s")
|
||||
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
# Raises an error if the switch is an enum and the values aren't included on it.
|
||||
#
|
||||
def validate_enum_value!(name, value, message)
|
||||
return unless @switches.is_a?(Hash)
|
||||
|
||||
switch = @switches[name]
|
||||
|
||||
return unless switch
|
||||
|
||||
if switch.enum && !switch.enum.include?(value)
|
||||
raise MalformattedArgumentError, message % [name, switch.enum_to_s, value]
|
||||
end
|
||||
end
|
||||
|
||||
# Raises an error if @non_assigned_required array is not empty.
|
||||
#
|
||||
def check_requirement!
|
||||
|
@ -11,7 +11,7 @@ class Bundler::Thor
|
||||
super
|
||||
@lazy_default = options[:lazy_default]
|
||||
@group = options[:group].to_s.capitalize if options[:group]
|
||||
@aliases = Array(options[:aliases])
|
||||
@aliases = normalize_aliases(options[:aliases])
|
||||
@hide = options[:hide]
|
||||
end
|
||||
|
||||
@ -69,7 +69,7 @@ class Bundler::Thor
|
||||
value.class.name.downcase.to_sym
|
||||
end
|
||||
|
||||
new(name.to_s, :required => required, :type => type, :default => default, :aliases => aliases)
|
||||
new(name.to_s, required: required, type: type, default: default, aliases: aliases)
|
||||
end
|
||||
|
||||
def switch_name
|
||||
@ -90,7 +90,7 @@ class Bundler::Thor
|
||||
sample = "[#{sample}]".dup unless required?
|
||||
|
||||
if boolean?
|
||||
sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-")
|
||||
sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.match(/\Ano[\-_]/)
|
||||
end
|
||||
|
||||
aliases_for_usage.ljust(padding) + sample
|
||||
@ -104,6 +104,15 @@ class Bundler::Thor
|
||||
end
|
||||
end
|
||||
|
||||
def show_default?
|
||||
case default
|
||||
when TrueClass, FalseClass
|
||||
true
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
VALID_TYPES.each do |type|
|
||||
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def #{type}?
|
||||
@ -142,8 +151,8 @@ class Bundler::Thor
|
||||
raise ArgumentError, err
|
||||
elsif @check_default_type == nil
|
||||
Bundler::Thor.deprecation_warning "#{err}.\n" +
|
||||
'This will be rejected in the future unless you explicitly pass the options `check_default_type: false`' +
|
||||
' or call `allow_incompatible_default_type!` in your code'
|
||||
"This will be rejected in the future unless you explicitly pass the options `check_default_type: false`" +
|
||||
" or call `allow_incompatible_default_type!` in your code"
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -159,5 +168,11 @@ class Bundler::Thor
|
||||
def dasherize(str)
|
||||
(str.length > 1 ? "--" : "-") + str.tr("_", "-")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def normalize_aliases(aliases)
|
||||
Array(aliases).map { |short| short.to_s.sub(/^(?!\-)/, "-") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -29,8 +29,10 @@ class Bundler::Thor
|
||||
#
|
||||
# If +stop_on_unknown+ is true, #parse will stop as soon as it encounters
|
||||
# an unknown option or a regular argument.
|
||||
def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false)
|
||||
def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false, relations = {})
|
||||
@stop_on_unknown = stop_on_unknown
|
||||
@exclusives = (relations[:exclusive_option_names] || []).select{|array| !array.empty?}
|
||||
@at_least_ones = (relations[:at_least_one_option_names] || []).select{|array| !array.empty?}
|
||||
@disable_required_check = disable_required_check
|
||||
options = hash_options.values
|
||||
super(options)
|
||||
@ -50,8 +52,7 @@ class Bundler::Thor
|
||||
options.each do |option|
|
||||
@switches[option.switch_name] = option
|
||||
|
||||
option.aliases.each do |short|
|
||||
name = short.to_s.sub(/^(?!\-)/, "-")
|
||||
option.aliases.each do |name|
|
||||
@shorts[name] ||= option.switch_name
|
||||
end
|
||||
end
|
||||
@ -101,7 +102,7 @@ class Bundler::Thor
|
||||
unshift($1.split("").map { |f| "-#{f}" })
|
||||
next
|
||||
when EQ_RE
|
||||
unshift($2, :is_value => true)
|
||||
unshift($2, is_value: true)
|
||||
switch = $1
|
||||
when SHORT_NUM
|
||||
unshift($2)
|
||||
@ -132,12 +133,38 @@ class Bundler::Thor
|
||||
end
|
||||
|
||||
check_requirement! unless @disable_required_check
|
||||
check_exclusive!
|
||||
check_at_least_one!
|
||||
|
||||
assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns)
|
||||
assigns.freeze
|
||||
assigns
|
||||
end
|
||||
|
||||
def check_exclusive!
|
||||
opts = @assigns.keys
|
||||
# When option A and B are exclusive, if A and B are given at the same time,
|
||||
# the diffrence of argument array size will decrease.
|
||||
found = @exclusives.find{ |ex| (ex - opts).size < ex.size - 1 }
|
||||
if found
|
||||
names = names_to_switch_names(found & opts).map{|n| "'#{n}'"}
|
||||
class_name = self.class.name.split("::").last.downcase
|
||||
fail ExclusiveArgumentError, "Found exclusive #{class_name} #{names.join(", ")}"
|
||||
end
|
||||
end
|
||||
|
||||
def check_at_least_one!
|
||||
opts = @assigns.keys
|
||||
# When at least one is required of the options A and B,
|
||||
# if the both options were not given, none? would be true.
|
||||
found = @at_least_ones.find{ |one_reqs| one_reqs.none?{ |o| opts.include? o} }
|
||||
if found
|
||||
names = names_to_switch_names(found).map{|n| "'#{n}'"}
|
||||
class_name = self.class.name.split("::").last.downcase
|
||||
fail AtLeastOneRequiredArgumentError, "Not found at least one of required #{class_name} #{names.join(", ")}"
|
||||
end
|
||||
end
|
||||
|
||||
def check_unknown!
|
||||
to_check = @stopped_parsing_after_extra_index ? @extra[0...@stopped_parsing_after_extra_index] : @extra
|
||||
|
||||
@ -148,6 +175,17 @@ class Bundler::Thor
|
||||
|
||||
protected
|
||||
|
||||
# Option names changes to swith name or human name
|
||||
def names_to_switch_names(names = [])
|
||||
@switches.map do |_, o|
|
||||
if names.include? o.name
|
||||
o.respond_to?(:switch_name) ? o.switch_name : o.human_name
|
||||
else
|
||||
nil
|
||||
end
|
||||
end.compact
|
||||
end
|
||||
|
||||
def assign_result!(option, result)
|
||||
if option.repeatable && option.type == :hash
|
||||
(@assigns[option.human_name] ||= {}).merge!(result)
|
||||
|
22
lib/bundler/vendor/thor/lib/thor/runner.rb
vendored
22
lib/bundler/vendor/thor/lib/thor/runner.rb
vendored
@ -23,7 +23,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
||||
initialize_thorfiles(meth)
|
||||
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
|
||||
self.class.handle_no_command_error(command, false) if klass.nil?
|
||||
klass.start(["-h", command].compact, :shell => shell)
|
||||
klass.start(["-h", command].compact, shell: shell)
|
||||
else
|
||||
super
|
||||
end
|
||||
@ -38,11 +38,11 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
||||
klass, command = Bundler::Thor::Util.find_class_and_command_by_namespace(meth)
|
||||
self.class.handle_no_command_error(command, false) if klass.nil?
|
||||
args.unshift(command) if command
|
||||
klass.start(args, :shell => shell)
|
||||
klass.start(args, shell: shell)
|
||||
end
|
||||
|
||||
desc "install NAME", "Install an optionally named Bundler::Thor file into your system commands"
|
||||
method_options :as => :string, :relative => :boolean, :force => :boolean
|
||||
method_options as: :string, relative: :boolean, force: :boolean
|
||||
def install(name) # rubocop:disable Metrics/MethodLength
|
||||
initialize_thorfiles
|
||||
|
||||
@ -53,7 +53,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
||||
package = :file
|
||||
require "open-uri"
|
||||
begin
|
||||
contents = URI.send(:open, name, &:read) # Using `send` for Ruby 2.4- support
|
||||
contents = URI.open(name, &:read)
|
||||
rescue OpenURI::HTTPError
|
||||
raise Error, "Error opening URI '#{name}'"
|
||||
end
|
||||
@ -69,7 +69,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
||||
base = name
|
||||
package = :file
|
||||
require "open-uri"
|
||||
contents = URI.send(:open, name, &:read) # for ruby 2.1-2.4
|
||||
contents = URI.open(name, &:read)
|
||||
end
|
||||
rescue Errno::ENOENT
|
||||
raise Error, "Error opening file '#{name}'"
|
||||
@ -101,9 +101,9 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
||||
end
|
||||
|
||||
thor_yaml[as] = {
|
||||
:filename => Digest::SHA256.hexdigest(name + as),
|
||||
:location => location,
|
||||
:namespaces => Bundler::Thor::Util.namespaces_in_content(contents, base)
|
||||
filename: Digest::SHA256.hexdigest(name + as),
|
||||
location: location,
|
||||
namespaces: Bundler::Thor::Util.namespaces_in_content(contents, base)
|
||||
}
|
||||
|
||||
save_yaml(thor_yaml)
|
||||
@ -164,14 +164,14 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc:
|
||||
end
|
||||
|
||||
desc "installed", "List the installed Bundler::Thor modules and commands"
|
||||
method_options :internal => :boolean
|
||||
method_options internal: :boolean
|
||||
def installed
|
||||
initialize_thorfiles(nil, true)
|
||||
display_klasses(true, options["internal"])
|
||||
end
|
||||
|
||||
desc "list [SEARCH]", "List the available thor commands (--substring means .*SEARCH)"
|
||||
method_options :substring => :boolean, :group => :string, :all => :boolean, :debug => :boolean
|
||||
method_options substring: :boolean, group: :string, all: :boolean, debug: :boolean
|
||||
def list(search = "")
|
||||
initialize_thorfiles
|
||||
|
||||
@ -313,7 +313,7 @@ private
|
||||
say shell.set_color(namespace, :blue, true)
|
||||
say "-" * namespace.size
|
||||
|
||||
print_table(list, :truncate => true)
|
||||
print_table(list, truncate: true)
|
||||
say
|
||||
end
|
||||
alias_method :display_tasks, :display_commands
|
||||
|
2
lib/bundler/vendor/thor/lib/thor/shell.rb
vendored
2
lib/bundler/vendor/thor/lib/thor/shell.rb
vendored
@ -75,7 +75,7 @@ class Bundler::Thor
|
||||
# Allow shell to be shared between invocations.
|
||||
#
|
||||
def _shared_configuration #:nodoc:
|
||||
super.merge!(:shell => shell)
|
||||
super.merge!(shell: shell)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
174
lib/bundler/vendor/thor/lib/thor/shell/basic.rb
vendored
174
lib/bundler/vendor/thor/lib/thor/shell/basic.rb
vendored
@ -1,8 +1,10 @@
|
||||
require_relative "column_printer"
|
||||
require_relative "table_printer"
|
||||
require_relative "wrapped_printer"
|
||||
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
class Basic
|
||||
DEFAULT_TERMINAL_WIDTH = 80
|
||||
|
||||
attr_accessor :base
|
||||
attr_reader :padding
|
||||
|
||||
@ -145,14 +147,14 @@ class Bundler::Thor
|
||||
# "yes".
|
||||
#
|
||||
def yes?(statement, color = nil)
|
||||
!!(ask(statement, color, :add_to_history => false) =~ is?(:yes))
|
||||
!!(ask(statement, color, add_to_history: false) =~ is?(:yes))
|
||||
end
|
||||
|
||||
# Make a question the to user and returns true if the user replies "n" or
|
||||
# "no".
|
||||
#
|
||||
def no?(statement, color = nil)
|
||||
!!(ask(statement, color, :add_to_history => false) =~ is?(:no))
|
||||
!!(ask(statement, color, add_to_history: false) =~ is?(:no))
|
||||
end
|
||||
|
||||
# Prints values in columns
|
||||
@ -161,16 +163,8 @@ class Bundler::Thor
|
||||
# Array[String, String, ...]
|
||||
#
|
||||
def print_in_columns(array)
|
||||
return if array.empty?
|
||||
colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
|
||||
array.each_with_index do |value, index|
|
||||
# Don't output trailing spaces when printing the last column
|
||||
if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
|
||||
stdout.puts value
|
||||
else
|
||||
stdout.printf("%-#{colwidth}s", value)
|
||||
end
|
||||
end
|
||||
printer = ColumnPrinter.new(stdout)
|
||||
printer.print(array)
|
||||
end
|
||||
|
||||
# Prints a table.
|
||||
@ -181,58 +175,11 @@ class Bundler::Thor
|
||||
# ==== Options
|
||||
# indent<Integer>:: Indent the first column by indent value.
|
||||
# colwidth<Integer>:: Force the first column to colwidth spaces wide.
|
||||
# borders<Boolean>:: Adds ascii borders.
|
||||
#
|
||||
def print_table(array, options = {}) # rubocop:disable Metrics/MethodLength
|
||||
return if array.empty?
|
||||
|
||||
formats = []
|
||||
indent = options[:indent].to_i
|
||||
colwidth = options[:colwidth]
|
||||
options[:truncate] = terminal_width if options[:truncate] == true
|
||||
|
||||
formats << "%-#{colwidth + 2}s".dup if colwidth
|
||||
start = colwidth ? 1 : 0
|
||||
|
||||
colcount = array.max { |a, b| a.size <=> b.size }.size
|
||||
|
||||
maximas = []
|
||||
|
||||
start.upto(colcount - 1) do |index|
|
||||
maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
|
||||
maximas << maxima
|
||||
formats << if index == colcount - 1
|
||||
# Don't output 2 trailing spaces when printing the last column
|
||||
"%-s".dup
|
||||
else
|
||||
"%-#{maxima + 2}s".dup
|
||||
end
|
||||
end
|
||||
|
||||
formats[0] = formats[0].insert(0, " " * indent)
|
||||
formats << "%s"
|
||||
|
||||
array.each do |row|
|
||||
sentence = "".dup
|
||||
|
||||
row.each_with_index do |column, index|
|
||||
maxima = maximas[index]
|
||||
|
||||
f = if column.is_a?(Numeric)
|
||||
if index == row.size - 1
|
||||
# Don't output 2 trailing spaces when printing the last column
|
||||
"%#{maxima}s"
|
||||
else
|
||||
"%#{maxima}s "
|
||||
end
|
||||
else
|
||||
formats[index]
|
||||
end
|
||||
sentence << f % column.to_s
|
||||
end
|
||||
|
||||
sentence = truncate(sentence, options[:truncate]) if options[:truncate]
|
||||
stdout.puts sentence
|
||||
end
|
||||
printer = TablePrinter.new(stdout, options)
|
||||
printer.print(array)
|
||||
end
|
||||
|
||||
# Prints a long string, word-wrapping the text to the current width of the
|
||||
@ -245,33 +192,8 @@ class Bundler::Thor
|
||||
# indent<Integer>:: Indent each line of the printed paragraph by indent value.
|
||||
#
|
||||
def print_wrapped(message, options = {})
|
||||
indent = options[:indent] || 0
|
||||
width = terminal_width - indent
|
||||
paras = message.split("\n\n")
|
||||
|
||||
paras.map! do |unwrapped|
|
||||
words = unwrapped.split(" ")
|
||||
counter = words.first.length
|
||||
words.inject do |memo, word|
|
||||
word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
|
||||
counter = 0 if word.include? "\n"
|
||||
if (counter + word.length + 1) < width
|
||||
memo = "#{memo} #{word}"
|
||||
counter += (word.length + 1)
|
||||
else
|
||||
memo = "#{memo}\n#{word}"
|
||||
counter = word.length
|
||||
end
|
||||
memo
|
||||
end
|
||||
end.compact!
|
||||
|
||||
paras.each do |para|
|
||||
para.split("\n").each do |line|
|
||||
stdout.puts line.insert(0, " " * indent)
|
||||
end
|
||||
stdout.puts unless para == paras.last
|
||||
end
|
||||
printer = WrappedPrinter.new(stdout, options)
|
||||
printer.print(message)
|
||||
end
|
||||
|
||||
# Deals with file collision and returns true if the file should be
|
||||
@ -289,7 +211,7 @@ class Bundler::Thor
|
||||
loop do
|
||||
answer = ask(
|
||||
%[Overwrite #{destination}? (enter "h" for help) #{options}],
|
||||
:add_to_history => false
|
||||
add_to_history: false
|
||||
)
|
||||
|
||||
case answer
|
||||
@ -316,24 +238,11 @@ class Bundler::Thor
|
||||
|
||||
say "Please specify merge tool to `THOR_MERGE` env."
|
||||
else
|
||||
say file_collision_help
|
||||
say file_collision_help(block_given?)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# This code was copied from Rake, available under MIT-LICENSE
|
||||
# Copyright (c) 2003, 2004 Jim Weirich
|
||||
def terminal_width
|
||||
result = if ENV["THOR_COLUMNS"]
|
||||
ENV["THOR_COLUMNS"].to_i
|
||||
else
|
||||
unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
|
||||
end
|
||||
result < 10 ? DEFAULT_TERMINAL_WIDTH : result
|
||||
rescue
|
||||
DEFAULT_TERMINAL_WIDTH
|
||||
end
|
||||
|
||||
# Called if something goes wrong during the execution. This is used by Bundler::Thor
|
||||
# internally and should not be used inside your scripts. If something went
|
||||
# wrong, you can always raise an exception. If you raise a Bundler::Thor::Error, it
|
||||
@ -384,16 +293,21 @@ class Bundler::Thor
|
||||
end
|
||||
end
|
||||
|
||||
def file_collision_help #:nodoc:
|
||||
<<-HELP
|
||||
def file_collision_help(block_given) #:nodoc:
|
||||
help = <<-HELP
|
||||
Y - yes, overwrite
|
||||
n - no, do not overwrite
|
||||
a - all, overwrite this and all others
|
||||
q - quit, abort
|
||||
d - diff, show the differences between the old and the new
|
||||
h - help, show this help
|
||||
m - merge, run merge tool
|
||||
HELP
|
||||
if block_given
|
||||
help << <<-HELP
|
||||
d - diff, show the differences between the old and the new
|
||||
m - merge, run merge tool
|
||||
HELP
|
||||
end
|
||||
help
|
||||
end
|
||||
|
||||
def show_diff(destination, content) #:nodoc:
|
||||
@ -411,46 +325,8 @@ class Bundler::Thor
|
||||
mute? || (base && base.options[:quiet])
|
||||
end
|
||||
|
||||
# Calculate the dynamic width of the terminal
|
||||
def dynamic_width
|
||||
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
|
||||
end
|
||||
|
||||
def dynamic_width_stty
|
||||
`stty size 2>/dev/null`.split[1].to_i
|
||||
end
|
||||
|
||||
def dynamic_width_tput
|
||||
`tput cols 2>/dev/null`.to_i
|
||||
end
|
||||
|
||||
def unix?
|
||||
RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris)/i
|
||||
end
|
||||
|
||||
def truncate(string, width)
|
||||
as_unicode do
|
||||
chars = string.chars.to_a
|
||||
if chars.length <= width
|
||||
chars.join
|
||||
else
|
||||
chars[0, width - 3].join + "..."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if "".respond_to?(:encode)
|
||||
def as_unicode
|
||||
yield
|
||||
end
|
||||
else
|
||||
def as_unicode
|
||||
old = $KCODE
|
||||
$KCODE = "U"
|
||||
yield
|
||||
ensure
|
||||
$KCODE = old
|
||||
end
|
||||
Terminal.unix?
|
||||
end
|
||||
|
||||
def ask_simply(statement, color, options)
|
||||
|
50
lib/bundler/vendor/thor/lib/thor/shell/color.rb
vendored
50
lib/bundler/vendor/thor/lib/thor/shell/color.rb
vendored
@ -1,4 +1,5 @@
|
||||
require_relative "basic"
|
||||
require_relative "lcs_diff"
|
||||
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
@ -6,6 +7,8 @@ class Bundler::Thor
|
||||
# Bundler::Thor::Shell::Basic to see all available methods.
|
||||
#
|
||||
class Color < Basic
|
||||
include LCSDiff
|
||||
|
||||
# Embed in a String to clear all previous ANSI sequences.
|
||||
CLEAR = "\e[0m"
|
||||
# The start of an ANSI bold sequence.
|
||||
@ -105,52 +108,7 @@ class Bundler::Thor
|
||||
end
|
||||
|
||||
def are_colors_disabled?
|
||||
!ENV['NO_COLOR'].nil? && !ENV['NO_COLOR'].empty?
|
||||
end
|
||||
|
||||
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
||||
# available.
|
||||
#
|
||||
def show_diff(destination, content) #:nodoc:
|
||||
if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
|
||||
actual = File.binread(destination).to_s.split("\n")
|
||||
content = content.to_s.split("\n")
|
||||
|
||||
Diff::LCS.sdiff(actual, content).each do |diff|
|
||||
output_diff_line(diff)
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def output_diff_line(diff) #:nodoc:
|
||||
case diff.action
|
||||
when "-"
|
||||
say "- #{diff.old_element.chomp}", :red, true
|
||||
when "+"
|
||||
say "+ #{diff.new_element.chomp}", :green, true
|
||||
when "!"
|
||||
say "- #{diff.old_element.chomp}", :red, true
|
||||
say "+ #{diff.new_element.chomp}", :green, true
|
||||
else
|
||||
say " #{diff.old_element.chomp}", nil, true
|
||||
end
|
||||
end
|
||||
|
||||
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
||||
# for diff.
|
||||
#
|
||||
def diff_lcs_loaded? #:nodoc:
|
||||
return true if defined?(Diff::LCS)
|
||||
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
||||
|
||||
@diff_lcs_loaded = begin
|
||||
require "diff/lcs"
|
||||
true
|
||||
rescue LoadError
|
||||
false
|
||||
end
|
||||
!ENV["NO_COLOR"].nil? && !ENV["NO_COLOR"].empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
29
lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb
vendored
Normal file
29
lib/bundler/vendor/thor/lib/thor/shell/column_printer.rb
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
require_relative "terminal"
|
||||
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
class ColumnPrinter
|
||||
attr_reader :stdout, :options
|
||||
|
||||
def initialize(stdout, options = {})
|
||||
@stdout = stdout
|
||||
@options = options
|
||||
@indent = options[:indent].to_i
|
||||
end
|
||||
|
||||
def print(array)
|
||||
return if array.empty?
|
||||
colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
|
||||
array.each_with_index do |value, index|
|
||||
# Don't output trailing spaces when printing the last column
|
||||
if ((((index + 1) % (Terminal.terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
|
||||
stdout.puts value
|
||||
else
|
||||
stdout.printf("%-#{colwidth}s", value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
48
lib/bundler/vendor/thor/lib/thor/shell/html.rb
vendored
48
lib/bundler/vendor/thor/lib/thor/shell/html.rb
vendored
@ -1,4 +1,5 @@
|
||||
require_relative "basic"
|
||||
require_relative "lcs_diff"
|
||||
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
@ -6,6 +7,8 @@ class Bundler::Thor
|
||||
# Bundler::Thor::Shell::Basic to see all available methods.
|
||||
#
|
||||
class HTML < Basic
|
||||
include LCSDiff
|
||||
|
||||
# The start of an HTML bold sequence.
|
||||
BOLD = "font-weight: bold"
|
||||
|
||||
@ -76,51 +79,6 @@ class Bundler::Thor
|
||||
def can_display_colors?
|
||||
true
|
||||
end
|
||||
|
||||
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
||||
# available.
|
||||
#
|
||||
def show_diff(destination, content) #:nodoc:
|
||||
if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
|
||||
actual = File.binread(destination).to_s.split("\n")
|
||||
content = content.to_s.split("\n")
|
||||
|
||||
Diff::LCS.sdiff(actual, content).each do |diff|
|
||||
output_diff_line(diff)
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def output_diff_line(diff) #:nodoc:
|
||||
case diff.action
|
||||
when "-"
|
||||
say "- #{diff.old_element.chomp}", :red, true
|
||||
when "+"
|
||||
say "+ #{diff.new_element.chomp}", :green, true
|
||||
when "!"
|
||||
say "- #{diff.old_element.chomp}", :red, true
|
||||
say "+ #{diff.new_element.chomp}", :green, true
|
||||
else
|
||||
say " #{diff.old_element.chomp}", nil, true
|
||||
end
|
||||
end
|
||||
|
||||
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
||||
# for diff.
|
||||
#
|
||||
def diff_lcs_loaded? #:nodoc:
|
||||
return true if defined?(Diff::LCS)
|
||||
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
||||
|
||||
@diff_lcs_loaded = begin
|
||||
require "diff/lcs"
|
||||
true
|
||||
rescue LoadError
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
49
lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb
vendored
Normal file
49
lib/bundler/vendor/thor/lib/thor/shell/lcs_diff.rb
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
module LCSDiff
|
||||
protected
|
||||
|
||||
# Overwrite show_diff to show diff with colors if Diff::LCS is
|
||||
# available.
|
||||
def show_diff(destination, content) #:nodoc:
|
||||
if diff_lcs_loaded? && ENV["THOR_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
|
||||
actual = File.binread(destination).to_s.split("\n")
|
||||
content = content.to_s.split("\n")
|
||||
|
||||
Diff::LCS.sdiff(actual, content).each do |diff|
|
||||
output_diff_line(diff)
|
||||
end
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def output_diff_line(diff) #:nodoc:
|
||||
case diff.action
|
||||
when "-"
|
||||
say "- #{diff.old_element.chomp}", :red, true
|
||||
when "+"
|
||||
say "+ #{diff.new_element.chomp}", :green, true
|
||||
when "!"
|
||||
say "- #{diff.old_element.chomp}", :red, true
|
||||
say "+ #{diff.new_element.chomp}", :green, true
|
||||
else
|
||||
say " #{diff.old_element.chomp}", nil, true
|
||||
end
|
||||
end
|
||||
|
||||
# Check if Diff::LCS is loaded. If it is, use it to create pretty output
|
||||
# for diff.
|
||||
def diff_lcs_loaded? #:nodoc:
|
||||
return true if defined?(Diff::LCS)
|
||||
return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
|
||||
|
||||
@diff_lcs_loaded = begin
|
||||
require "diff/lcs"
|
||||
true
|
||||
rescue LoadError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
134
lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb
vendored
Normal file
134
lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
require_relative "column_printer"
|
||||
require_relative "terminal"
|
||||
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
class TablePrinter < ColumnPrinter
|
||||
BORDER_SEPARATOR = :separator
|
||||
|
||||
def initialize(stdout, options = {})
|
||||
super
|
||||
@formats = []
|
||||
@maximas = []
|
||||
@colwidth = options[:colwidth]
|
||||
@truncate = options[:truncate] == true ? Terminal.terminal_width : options[:truncate]
|
||||
@padding = 1
|
||||
end
|
||||
|
||||
def print(array)
|
||||
return if array.empty?
|
||||
|
||||
prepare(array)
|
||||
|
||||
print_border_separator if options[:borders]
|
||||
|
||||
array.each do |row|
|
||||
if options[:borders] && row == BORDER_SEPARATOR
|
||||
print_border_separator
|
||||
next
|
||||
end
|
||||
|
||||
sentence = "".dup
|
||||
|
||||
row.each_with_index do |column, index|
|
||||
sentence << format_cell(column, row.size, index)
|
||||
end
|
||||
|
||||
sentence = truncate(sentence)
|
||||
sentence << "|" if options[:borders]
|
||||
stdout.puts indentation + sentence
|
||||
|
||||
end
|
||||
print_border_separator if options[:borders]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def prepare(array)
|
||||
array = array.reject{|row| row == BORDER_SEPARATOR }
|
||||
|
||||
@formats << "%-#{@colwidth + 2}s".dup if @colwidth
|
||||
start = @colwidth ? 1 : 0
|
||||
|
||||
colcount = array.max { |a, b| a.size <=> b.size }.size
|
||||
|
||||
start.upto(colcount - 1) do |index|
|
||||
maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
|
||||
|
||||
@maximas << maxima
|
||||
@formats << if options[:borders]
|
||||
"%-#{maxima}s".dup
|
||||
elsif index == colcount - 1
|
||||
# Don't output 2 trailing spaces when printing the last column
|
||||
"%-s".dup
|
||||
else
|
||||
"%-#{maxima + 2}s".dup
|
||||
end
|
||||
end
|
||||
|
||||
@formats << "%s"
|
||||
end
|
||||
|
||||
def format_cell(column, row_size, index)
|
||||
maxima = @maximas[index]
|
||||
|
||||
f = if column.is_a?(Numeric)
|
||||
if options[:borders]
|
||||
# With borders we handle padding separately
|
||||
"%#{maxima}s"
|
||||
elsif index == row_size - 1
|
||||
# Don't output 2 trailing spaces when printing the last column
|
||||
"%#{maxima}s"
|
||||
else
|
||||
"%#{maxima}s "
|
||||
end
|
||||
else
|
||||
@formats[index]
|
||||
end
|
||||
|
||||
cell = "".dup
|
||||
cell << "|" + " " * @padding if options[:borders]
|
||||
cell << f % column.to_s
|
||||
cell << " " * @padding if options[:borders]
|
||||
cell
|
||||
end
|
||||
|
||||
def print_border_separator
|
||||
separator = @maximas.map do |maxima|
|
||||
"+" + "-" * (maxima + 2 * @padding)
|
||||
end
|
||||
stdout.puts indentation + separator.join + "+"
|
||||
end
|
||||
|
||||
def truncate(string)
|
||||
return string unless @truncate
|
||||
as_unicode do
|
||||
chars = string.chars.to_a
|
||||
if chars.length <= @truncate
|
||||
chars.join
|
||||
else
|
||||
chars[0, @truncate - 3 - @indent].join + "..."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def indentation
|
||||
" " * @indent
|
||||
end
|
||||
|
||||
if "".respond_to?(:encode)
|
||||
def as_unicode
|
||||
yield
|
||||
end
|
||||
else
|
||||
def as_unicode
|
||||
old = $KCODE # rubocop:disable Style/GlobalVars
|
||||
$KCODE = "U" # rubocop:disable Style/GlobalVars
|
||||
yield
|
||||
ensure
|
||||
$KCODE = old # rubocop:disable Style/GlobalVars
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
42
lib/bundler/vendor/thor/lib/thor/shell/terminal.rb
vendored
Normal file
42
lib/bundler/vendor/thor/lib/thor/shell/terminal.rb
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
module Terminal
|
||||
DEFAULT_TERMINAL_WIDTH = 80
|
||||
|
||||
class << self
|
||||
# This code was copied from Rake, available under MIT-LICENSE
|
||||
# Copyright (c) 2003, 2004 Jim Weirich
|
||||
def terminal_width
|
||||
result = if ENV["THOR_COLUMNS"]
|
||||
ENV["THOR_COLUMNS"].to_i
|
||||
else
|
||||
unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
|
||||
end
|
||||
result < 10 ? DEFAULT_TERMINAL_WIDTH : result
|
||||
rescue
|
||||
DEFAULT_TERMINAL_WIDTH
|
||||
end
|
||||
|
||||
def unix?
|
||||
RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris)/i
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Calculate the dynamic width of the terminal
|
||||
def dynamic_width
|
||||
@dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
|
||||
end
|
||||
|
||||
def dynamic_width_stty
|
||||
`stty size 2>/dev/null`.split[1].to_i
|
||||
end
|
||||
|
||||
def dynamic_width_tput
|
||||
`tput cols 2>/dev/null`.to_i
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
38
lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb
vendored
Normal file
38
lib/bundler/vendor/thor/lib/thor/shell/wrapped_printer.rb
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
require_relative "column_printer"
|
||||
require_relative "terminal"
|
||||
|
||||
class Bundler::Thor
|
||||
module Shell
|
||||
class WrappedPrinter < ColumnPrinter
|
||||
def print(message)
|
||||
width = Terminal.terminal_width - @indent
|
||||
paras = message.split("\n\n")
|
||||
|
||||
paras.map! do |unwrapped|
|
||||
words = unwrapped.split(" ")
|
||||
counter = words.first.length
|
||||
words.inject do |memo, word|
|
||||
word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
|
||||
counter = 0 if word.include? "\n"
|
||||
if (counter + word.length + 1) < width
|
||||
memo = "#{memo} #{word}"
|
||||
counter += (word.length + 1)
|
||||
else
|
||||
memo = "#{memo}\n#{word}"
|
||||
counter = word.length
|
||||
end
|
||||
memo
|
||||
end
|
||||
end.compact!
|
||||
|
||||
paras.each do |para|
|
||||
para.split("\n").each do |line|
|
||||
stdout.puts line.insert(0, " " * @indent)
|
||||
end
|
||||
stdout.puts unless para == paras.last
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
7
lib/bundler/vendor/thor/lib/thor/util.rb
vendored
7
lib/bundler/vendor/thor/lib/thor/util.rb
vendored
@ -130,9 +130,10 @@ class Bundler::Thor
|
||||
#
|
||||
def find_class_and_command_by_namespace(namespace, fallback = true)
|
||||
if namespace.include?(":") # look for a namespaced command
|
||||
pieces = namespace.split(":")
|
||||
command = pieces.pop
|
||||
klass = Bundler::Thor::Util.find_by_namespace(pieces.join(":"))
|
||||
*pieces, command = namespace.split(":")
|
||||
namespace = pieces.join(":")
|
||||
namespace = "default" if namespace.empty?
|
||||
klass = Bundler::Thor::Base.subclasses.detect { |thor| thor.namespace == namespace && thor.commands.keys.include?(command) }
|
||||
end
|
||||
unless klass # look for a Bundler::Thor::Group with the right name
|
||||
klass = Bundler::Thor::Util.find_by_namespace(namespace)
|
||||
|
2
lib/bundler/vendor/thor/lib/thor/version.rb
vendored
2
lib/bundler/vendor/thor/lib/thor/version.rb
vendored
@ -1,3 +1,3 @@
|
||||
class Bundler::Thor
|
||||
VERSION = "1.2.2"
|
||||
VERSION = "1.3.0"
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user