diff options
author | The Bundler Bot <bot@bundler.io> | 2017-08-16 18:18:58 +0000 |
---|---|---|
committer | The Bundler Bot <bot@bundler.io> | 2017-08-16 18:18:58 +0000 |
commit | 1f4e890304a5dae7c83d40305e2d878ca7c0362e (patch) | |
tree | e4d9d4bc2076f17b0a3b83ac40ee4a7bdde7e0ea | |
parent | 246ab43690f517130772bd7d6219539ee60c9703 (diff) | |
parent | 5b930d792be4ad26557bb546239eae8a7cf6bed2 (diff) | |
download | bundler-1f4e890304a5dae7c83d40305e2d878ca7c0362e.tar.gz |
Auto merge of #5849 - rafaelfranca:thor-0.20, r=segiddins
Upgrade thor to 0.20.0
Thor 0.20.0 was released so I'm upgrading bundler to the newest version.
21 files changed, 184 insertions, 70 deletions
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index df5bad7321..70d210b9e9 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -103,9 +103,6 @@ module Bundler end end - # Ensure `bundle help --no-color` is valid - all_commands["help"].disable_class_options = false - def self.handle_no_command_error(command, has_namespace = $thor_runner) if Bundler.feature_flag.plugins? && Bundler::Plugin.command?(command) return Bundler::Plugin.exec_command(command, ARGV[1..-1]) diff --git a/lib/bundler/cli/gem.rb b/lib/bundler/cli/gem.rb index 5ebaf189e9..a18d929791 100644 --- a/lib/bundler/cli/gem.rb +++ b/lib/bundler/cli/gem.rb @@ -142,9 +142,10 @@ module Bundler end executables.each do |file| - path = target.join(file) - executable = (path.stat.mode | 0o111) - path.chmod(executable) + SharedHelpers.filesystem_access(target.join(file)) do |path| + executable = (path.stat.mode | 0o111) + path.chmod(executable) + end end if Bundler.git_present? diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb index 563e361bd3..999e8b7e61 100644 --- a/lib/bundler/vendor/thor/lib/thor.rb +++ b/lib/bundler/vendor/thor/lib/thor.rb @@ -158,10 +158,6 @@ class Bundler::Thor end alias_method :option, :method_option - def disable_class_options - @disable_class_options = true - end - # Prints help information for the given command. # # ==== Parameters @@ -241,6 +237,9 @@ class Bundler::Thor invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h") invoke subcommand_class, *invoke_args end + subcommand_class.commands.each do |_meth, command| + command.ancestor_name = subcommand + end end alias_method :subtask, :subcommand @@ -326,12 +325,31 @@ class Bundler::Thor command && stop_on_unknown_option.include?(command.name.to_sym) end + # Disable the check for required options for the given commands. + # This is useful if you have a command that does not need the required options + # to work, like help. + # + # ==== Parameters + # Symbol ...:: A list of commands that should be affected. + def disable_required_check!(*command_names) + disable_required_check.merge(command_names) + end + + def disable_required_check?(command) #:nodoc: + command && disable_required_check.include?(command.name.to_sym) + end + protected def stop_on_unknown_option #:nodoc: @stop_on_unknown_option ||= Set.new end + # help command has the required check disabled by default. + def disable_required_check #:nodoc: + @disable_required_check ||= Set.new([:help]) + end + # The method responsible for dispatching given the args. def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength meth ||= retrieve_command_name(given_args) @@ -390,12 +408,12 @@ class Bundler::Thor @usage ||= nil @desc ||= nil @long_desc ||= nil - @disable_class_options ||= 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, @disable_class_options) - @usage, @desc, @long_desc, @method_options, @hide, @disable_class_options = nil + commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options) + @usage, @desc, @long_desc, @method_options, @hide = nil true elsif all_commands[meth] || meth == "method_missing" true @@ -477,7 +495,6 @@ class Bundler::Thor map HELP_MAPPINGS => :help desc "help [COMMAND]", "Describe available commands or one specific command" - disable_class_options def help(command = nil, subcommand = false) if command if self.class.subcommands.include? command diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb index 9f1c9f23e8..e6698572a9 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions.rb @@ -1,4 +1,3 @@ -require "fileutils" require "uri" require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read" require "bundler/vendor/thor/lib/thor/actions/create_file" @@ -141,7 +140,7 @@ class Bundler::Thor end end - message = "Could not find #{file.inspect} in any of your source paths. " + message = "Could not find #{file.inspect} in any of your source paths. ".dup unless self.class.source_root message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. " @@ -175,6 +174,7 @@ class Bundler::Thor # If the directory doesnt exist and we're not pretending if !File.exist?(destination_root) && !pretend + require "fileutils" FileUtils.mkdir_p(destination_root) end @@ -182,6 +182,7 @@ class Bundler::Thor # In pretend mode, just yield down to the block block.arity == 1 ? yield(destination_root) : yield else + require "fileutils" FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } end @@ -251,7 +252,9 @@ class Bundler::Thor say_status :run, desc, config.fetch(:verbose, true) - !options[:pretend] && config[:capture] ? `#{command}` : system(command.to_s) + unless options[:pretend] + config[:capture] ? `#{command}` : system(command.to_s) + end end # Executes a ruby script (taking into account WIN32 platform quirks). diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb index ade3f85bde..97d22d9bbd 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/create_file.rb @@ -58,6 +58,7 @@ class Bundler::Thor def invoke! invoke_with_conflict_check do + require "fileutils" FileUtils.mkdir_p(File.dirname(destination)) File.open(destination, "wb") { |f| f.write render } end diff --git a/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb b/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb index 7577d12533..3a664401b4 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/create_link.rb @@ -38,6 +38,7 @@ class Bundler::Thor def invoke! invoke_with_conflict_check do + require "fileutils" FileUtils.mkdir_p(File.dirname(destination)) # Create a symlink by default config[:symbolic] = true if config[:symbolic].nil? diff --git a/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb index 309cb31d9d..284d92c19a 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb @@ -48,12 +48,14 @@ class Bundler::Thor def invoke! invoke_with_conflict_check do + require "fileutils" ::FileUtils.mkdir_p(destination) end end def revoke! say_status :remove, :red + require "fileutils" ::FileUtils.rm_rf(destination) if !pretend? && exists? given_destination end @@ -112,11 +114,17 @@ class Bundler::Thor if exists? on_conflict_behavior(&block) else - say_status :create, :green yield unless pretend? + say_status :create, :green end destination + rescue Errno::EISDIR, Errno::EEXIST + on_file_clash_behavior + end + + def on_file_clash_behavior + say_status :file_clash, :red end # What to do when the destination file already exists. diff --git a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb index 54272fc0c6..4c83bebc86 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb @@ -1,5 +1,4 @@ require "erb" -require "open-uri" class Bundler::Thor module Actions @@ -78,7 +77,12 @@ class Bundler::Thor config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first - source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ %r{^https?\://} + if source =~ %r{^https?\://} + require "open-uri" + else + source = File.expand_path(find_in_source_paths(source.to_s)) + end + render = open(source) { |input| input.binmode.read } destination ||= if block_given? @@ -113,7 +117,9 @@ class Bundler::Thor context = config.delete(:context) || instance_eval("binding") create_file destination, nil, config do - content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").result(context) + content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb| + erb.filename = source + end.result(context) content = yield(content) if block content end @@ -134,7 +140,10 @@ class Bundler::Thor return unless behavior == :invoke path = File.expand_path(path, destination_root) say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) - FileUtils.chmod_R(mode, path) unless options[:pretend] + unless options[:pretend] + require "fileutils" + FileUtils.chmod_R(mode, path) + end end # Prepend text to a file. Since it depends on insert_into_file, it's reversible. @@ -204,6 +213,29 @@ class Bundler::Thor insert_into_file(path, *(args << config), &block) end + # Injects text right after the module definition. Since it depends on + # insert_into_file, it's reversible. + # + # ==== Parameters + # path<String>:: path of the file to be changed + # module_name<String|Class>:: the module to be manipulated + # data<String>:: the data to append to the class, can be also given as a block. + # config<Hash>:: give :verbose => false to not log the status. + # + # ==== Examples + # + # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper, " def help; 'help'; end\n" + # + # inject_into_module "app/helpers/application_helper.rb", ApplicationHelper do + # " def help; 'help'; end\n" + # end + # + def inject_into_module(path, module_name, *args, &block) + config = args.last.is_a?(Hash) ? args.pop : {} + config[:after] = /module #{module_name}\n|module #{module_name} .*\n/ + insert_into_file(path, *(args << config), &block) + end + # Run a regular expression replacement on a file. # # ==== Parameters @@ -288,7 +320,10 @@ class Bundler::Thor path = File.expand_path(path, destination_root) say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) - ::FileUtils.rm_rf(path) if !options[:pretend] && File.exist?(path) + if !options[:pretend] && File.exist?(path) + require "fileutils" + ::FileUtils.rm_rf(path) + end end alias_method :remove_dir, :remove_file @@ -305,8 +340,10 @@ class Bundler::Thor with_output_buffer { yield(*args) } end - def with_output_buffer(buf = "") #:nodoc: - self.output_buffer, old_buffer = buf, output_buffer + def with_output_buffer(buf = "".dup) #:nodoc: + raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen? + old_buffer = output_buffer + self.output_buffer = buf yield output_buffer ensure @@ -319,7 +356,7 @@ class Bundler::Thor def set_eoutvar(compiler, eoutvar = "_erbout") compiler.put_cmd = "#{eoutvar}.concat" compiler.insert_cmd = "#{eoutvar}.concat" - compiler.pre_cmd = ["#{eoutvar} = ''"] + compiler.pre_cmd = ["#{eoutvar} = ''.dup"] compiler.post_cmd = [eoutvar] end end diff --git a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb index 781ee63140..349b26ff65 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb @@ -53,7 +53,13 @@ class Bundler::Thor replacement + '\0' end - replace!(/#{flag}/, content, config[:force]) + if exists? + replace!(/#{flag}/, content, config[:force]) + else + unless pretend? + raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist" + end + end end def revoke! @@ -91,8 +97,8 @@ class Bundler::Thor # Adds the content to the file. # def replace!(regexp, string, force) - return if base.options[:pretend] - content = File.binread(destination) + return if pretend? + content = File.read(destination) if force || !content.include?(replacement) content.gsub!(regexp, string) File.open(destination, "wb") { |file| file.write(content) } diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb index bbd2250de0..9bd1077170 100644 --- a/lib/bundler/vendor/thor/lib/thor/base.rb +++ b/lib/bundler/vendor/thor/lib/thor/base.rb @@ -42,7 +42,7 @@ class Bundler::Thor # config<Hash>:: Configuration for this Bundler::Thor class. # def initialize(args = [], local_options = {}, config = {}) - parse_options = config[:current_command] && config[:current_command].disable_class_options ? {} : self.class.class_options + parse_options = self.class.class_options # The start method splits inbound arguments at the first argument # that looks like an option (starts with - or --). It then calls @@ -65,7 +65,8 @@ class Bundler::Thor # 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] - opts = Bundler::Thor::Options.new(parse_options, hash_options, stop_on_unknown) + 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) self.options = opts.parse(array_options) self.options = config[:class_options].merge(options) if config[:class_options] @@ -112,7 +113,7 @@ class Bundler::Thor end # Whenever a class inherits from Bundler::Thor or Bundler::Thor::Group, we should track the - # class and the file on Bundler::Thor::Base. This is the method responsible for it. + # class and the file on Bundler::Thor::Base. This is the method responsable for it. # def register_klass_file(klass) #:nodoc: file = caller[1].match(/(.*):\d+/)[1] @@ -150,6 +151,21 @@ class Bundler::Thor !!check_unknown_options end + # If you want to raise an error when the default value of an option does not match + # the type call check_default_type! + # This is disabled by default for compatibility. + def check_default_type! + @check_default_type = true + end + + def check_default_type #:nodoc: + @check_default_type ||= from_superclass(:check_default_type, false) + end + + def check_default_type? #:nodoc: + !!check_default_type + end + # If true, option parsing is suspended as soon as an unknown option or a # regular argument is encountered. All remaining arguments are passed to # the command as regular arguments. @@ -157,6 +173,12 @@ class Bundler::Thor false end + # If true, option set will not suspend the execution of the command when + # a required option is not provided. + def disable_required_check?(command_name) #:nodoc: + false + end + # If you want only strict string args (useful when cascading thor classes), # call strict_args_position! This is disabled by default to allow dynamic # invocations. @@ -477,7 +499,8 @@ class Bundler::Thor alias_method :handle_no_task_error, :handle_no_command_error def handle_argument_error(command, error, args, arity) #:nodoc: - msg = "ERROR: \"#{basename} #{command.name}\" was called with " + name = [command.ancestor_name, command.name].compact.join(" ") + msg = "ERROR: \"#{basename} #{name}\" was called with ".dup msg << "no arguments" if args.empty? msg << "arguments " << args.inspect unless args.empty? msg << "\nUsage: #{banner(command).inspect}" @@ -541,7 +564,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, options) + scope[name] = Bundler::Thor::Option.new(name, options.merge(:check_default_type => check_default_type?)) end # Receives a hash of options, parse them and add to the scope. This is a diff --git a/lib/bundler/vendor/thor/lib/thor/command.rb b/lib/bundler/vendor/thor/lib/thor/command.rb index aacf2ef719..c636948e5d 100644 --- a/lib/bundler/vendor/thor/lib/thor/command.rb +++ b/lib/bundler/vendor/thor/lib/thor/command.rb @@ -1,9 +1,9 @@ class Bundler::Thor - class Command < Struct.new(:name, :description, :long_description, :usage, :options, :disable_class_options) + class Command < Struct.new(:name, :description, :long_description, :usage, :options, :ancestor_name) FILE_REGEXP = /^#{Regexp.escape(File.dirname(__FILE__))}/ - def initialize(name, description, long_description, usage, options = nil, disable_class_options = false) - super(name.to_s, description, long_description, usage, options || {}, disable_class_options) + def initialize(name, description, long_description, usage, options = nil) + super(name.to_s, description, long_description, usage, options || {}) end def initialize_copy(other) #:nodoc: @@ -39,13 +39,15 @@ class Bundler::Thor # Returns the formatted usage by injecting given required arguments # and required options into the given usage. def formatted_usage(klass, namespace = true, subcommand = false) - if namespace + if ancestor_name + formatted = "#{ancestor_name} ".dup # add space + elsif namespace namespace = klass.namespace - formatted = "#{namespace.gsub(/^(default)/, '')}:" + formatted = "#{namespace.gsub(/^(default)/, '')}:".dup end - formatted = "#{klass.namespace.split(':').last} " if subcommand + formatted ||= "#{klass.namespace.split(':').last} ".dup if subcommand - formatted ||= "" + formatted ||= "".dup # Add usage with required arguments formatted << if klass && !klass.arguments.empty? diff --git a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb index de8c4713b4..c167aa33b8 100644 --- a/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +++ b/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb @@ -51,6 +51,18 @@ class Bundler::Thor self end + def reverse_merge(other) + self.class.new(other).merge(self) + end + + def reverse_merge!(other_hash) + replace(reverse_merge(other_hash)) + end + + def replace(other_hash) + super(other_hash) + end + # Convert to a Hash with String keys. def to_hash Hash.new(default).merge!(self) diff --git a/lib/bundler/vendor/thor/lib/thor/group.rb b/lib/bundler/vendor/thor/lib/thor/group.rb index c95b708caa..05ddc10cd3 100644 --- a/lib/bundler/vendor/thor/lib/thor/group.rb +++ b/lib/bundler/vendor/thor/lib/thor/group.rb @@ -205,7 +205,7 @@ class Bundler::Thor::Group alias_method :printable_tasks, :printable_commands def handle_argument_error(command, error, _args, arity) #:nodoc: - msg = "#{basename} #{command.name} takes #{arity} argument" + msg = "#{basename} #{command.name} takes #{arity} argument".dup msg << "s" if arity > 1 msg << ", but it should not." raise error, msg diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb b/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb index b121e95575..0adb2b3137 100644 --- a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +++ b/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb @@ -23,6 +23,8 @@ class Bundler::Thor if echo? $stdin.gets else + # Lazy-load io/console since it is gem-ified as of 2.3 + require "io/console" if RUBY_VERSION > "1.9.2" $stdin.noecho(&:gets) end end diff --git a/lib/bundler/vendor/thor/lib/thor/parser/option.rb b/lib/bundler/vendor/thor/lib/thor/parser/option.rb index 032493075d..85169b56c8 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/option.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/option.rb @@ -5,6 +5,7 @@ class Bundler::Thor VALID_TYPES = [:boolean, :numeric, :hash, :array, :string] def initialize(name, options = {}) + @check_default_type = options[:check_default_type] options[:required] = false unless options.key?(:required) super @lazy_default = options[:lazy_default] @@ -80,12 +81,12 @@ class Bundler::Thor def usage(padding = 0) sample = if banner && !banner.to_s.empty? - "#{switch_name}=#{banner}" + "#{switch_name}=#{banner}".dup else switch_name end - sample = "[#{sample}]" unless required? + sample = "[#{sample}]".dup unless required? if boolean? sample << ", [#{dasherize('no-' + human_name)}]" unless (name == "force") || name.start_with?("no-") @@ -110,7 +111,7 @@ class Bundler::Thor def validate! raise ArgumentError, "An option cannot be boolean and required." if boolean? && required? - validate_default_type! + validate_default_type! if @check_default_type end def validate_default_type! @@ -127,8 +128,7 @@ class Bundler::Thor @default.class.name.downcase.to_sym end - # TODO: This should raise an ArgumentError in a future version of Bundler::Thor - warn "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type + raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type end def dasherized? diff --git a/lib/bundler/vendor/thor/lib/thor/parser/options.rb b/lib/bundler/vendor/thor/lib/thor/parser/options.rb index 3ce8f55f94..70f6366842 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb @@ -18,19 +18,20 @@ class Bundler::Thor when Hash "--#{key} #{value.map { |k, v| "#{k}:#{v}" }.join(' ')}" when nil, false - "" + nil else "--#{key} #{value.inspect}" end - end.join(" ") + end.compact.join(" ") end # Takes a hash of Bundler::Thor::Option and a hash with defaults. # # 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) + def initialize(hash_options = {}, defaults = {}, stop_on_unknown = false, disable_required_check = false) @stop_on_unknown = stop_on_unknown + @disable_required_check = disable_required_check options = hash_options.values super(options) @@ -111,7 +112,7 @@ class Bundler::Thor end end - check_requirement! + check_requirement! unless @disable_required_check assigns = Bundler::Thor::CoreExt::HashWithIndifferentAccess.new(@assigns) assigns.freeze @@ -188,7 +189,7 @@ class Bundler::Thor shift false else - true + !no_or_skip?(switch) end else @switches.key?(switch) || !no_or_skip?(switch) diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb index 4e96f7730a..65ae422d7f 100644 --- a/lib/bundler/vendor/thor/lib/thor/runner.rb +++ b/lib/bundler/vendor/thor/lib/thor/runner.rb @@ -2,8 +2,6 @@ require "bundler/vendor/thor/lib/thor" require "bundler/vendor/thor/lib/thor/group" require "bundler/vendor/thor/lib/thor/core_ext/io_binary_read" -require "fileutils" -require "open-uri" require "yaml" require "digest/md5" require "pathname" @@ -104,6 +102,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng if package == :file File.open(destination, "w") { |f| f.puts contents } else + require "fileutils" FileUtils.cp_r(name, destination) end @@ -120,6 +119,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng def uninstall(name) raise Error, "Can't find module '#{name}'" unless thor_yaml[name] say "Uninstalling #{name}." + require "fileutils" FileUtils.rm_rf(File.join(thor_root, (thor_yaml[name][:filename]).to_s)) thor_yaml.delete(name) @@ -138,6 +138,7 @@ class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLeng self.options = options.merge("as" => name) if File.directory? File.expand_path(name) + require "fileutils" FileUtils.rm_rf(File.join(thor_root, old_filename)) thor_yaml.delete(old_filename) @@ -194,6 +195,7 @@ private yaml_file = File.join(thor_root, "thor.yml") unless File.exist?(yaml_file) + require "fileutils" FileUtils.mkdir_p(thor_root) yaml_file = File.join(thor_root, "thor.yml") FileUtils.touch(yaml_file) diff --git a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb index 52b6dfd225..5162390efd 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell/basic.rb @@ -1,6 +1,3 @@ -require "tempfile" -require "io/console" if RUBY_VERSION > "1.9.2" - class Bundler::Thor module Shell class Basic @@ -110,7 +107,7 @@ class Bundler::Thor status = set_color status, color, true if color buffer = "#{status}#{spaces}#{message}" - buffer << "\n" unless buffer.end_with?("\n") + buffer = "#{buffer}\n" unless buffer.end_with?("\n") stdout.print(buffer) stdout.flush @@ -165,7 +162,7 @@ class Bundler::Thor colwidth = options[:colwidth] options[:truncate] = terminal_width if options[:truncate] == true - formats << "%-#{colwidth + 2}s" if colwidth + formats << "%-#{colwidth + 2}s".dup if colwidth start = colwidth ? 1 : 0 colcount = array.max { |a, b| a.size <=> b.size }.size @@ -177,9 +174,9 @@ class Bundler::Thor maximas << maxima formats << if index == colcount - 1 # Don't output 2 trailing spaces when printing the last column - "%-s" + "%-s".dup else - "%-#{maxima + 2}s" + "%-#{maxima + 2}s".dup end end @@ -187,7 +184,7 @@ class Bundler::Thor formats << "%s" array.each do |row| - sentence = "" + sentence = "".dup row.each_with_index do |column, index| maxima = maximas[index] @@ -255,6 +252,9 @@ class Bundler::Thor ) case answer + when nil + say "" + return true when is?(:yes), is?(:force), "" return true when is?(:no), is?(:skip) @@ -350,6 +350,7 @@ class Bundler::Thor def show_diff(destination, content) #:nodoc: diff_cmd = ENV["THOR_DIFF"] || ENV["RAILS_DIFF"] || "diff -u" + require "tempfile" Tempfile.open(File.basename(destination), File.dirname(destination)) do |temp| temp.write content temp.rewind @@ -411,7 +412,7 @@ class Bundler::Thor return unless result - result.strip! + result = result.strip if default && result == "" default diff --git a/lib/bundler/vendor/thor/lib/thor/util.rb b/lib/bundler/vendor/thor/lib/thor/util.rb index 0fe7d4d859..5d03177a28 100644 --- a/lib/bundler/vendor/thor/lib/thor/util.rb +++ b/lib/bundler/vendor/thor/lib/thor/util.rb @@ -27,7 +27,7 @@ class Bundler::Thor end # Receives a constant and converts it to a Bundler::Thor namespace. Since Bundler::Thor - # commands can be added to a sandbox, this method is also responsible for + # commands can be added to a sandbox, this method is also responsable for # removing the sandbox namespace. # # This method should not be used in general because it's used to deal with diff --git a/lib/bundler/vendor/thor/lib/thor/version.rb b/lib/bundler/vendor/thor/lib/thor/version.rb index a6d838b103..df8f18821a 100644 --- a/lib/bundler/vendor/thor/lib/thor/version.rb +++ b/lib/bundler/vendor/thor/lib/thor/version.rb @@ -1,3 +1,3 @@ class Bundler::Thor - VERSION = "0.19.4" + VERSION = "0.20.0" end diff --git a/spec/commands/newgem_spec.rb b/spec/commands/newgem_spec.rb index 8543989ca2..8d851f28a4 100644 --- a/spec/commands/newgem_spec.rb +++ b/spec/commands/newgem_spec.rb @@ -888,19 +888,19 @@ Usage: "bundle gem GEM [OPTIONS]" FileUtils.touch("conflict-foobar") end bundle "gem conflict-foobar" - expect(last_command.bundler_err).to include("Errno::EEXIST") + expect(last_command.bundler_err).to include("Errno::ENOTDIR") expect(exitstatus).to eql(32) if exitstatus end end context "on conflicts with a previously created directory" do - it "should fail gracefully" do + it "should succeed" do in_app_root do FileUtils.mkdir_p("conflict-foobar/Gemfile") end - bundle "gem conflict-foobar" - expect(last_command.bundler_err).to include("Errno::EISDIR") - expect(exitstatus).to eql(32) if exitstatus + bundle! "gem conflict-foobar" + expect(last_command.stdout).to include("file_clash conflict-foobar/Gemfile"). + and include "Initializing git repo in #{bundled_app("conflict-foobar")}" end end end |