diff options
author | Hiroshi SHIBATA <hsbt@ruby-lang.org> | 2019-11-13 07:57:02 +0900 |
---|---|---|
committer | SHIBATA Hiroshi <hsbt@ruby-lang.org> | 2019-11-13 10:19:51 +0900 |
commit | bb9ecd026a6cadd5d0f85ac061649216806ed935 (patch) | |
tree | 237975b9702a837fd0a8d24575f1edadb4d773d0 | |
parent | 00d56bdf66a3aeaadbc84196aacbd8d4e698cf79 (diff) |
Merge Bundler 2.1.0.pre3 released version
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2674
36 files changed, 192 insertions, 152 deletions
diff --git a/lib/bundler/gem_helper.rb b/lib/bundler/gem_helper.rb index 81872b9429..46a6643233 100644 --- a/lib/bundler/gem_helper.rb +++ b/lib/bundler/gem_helper.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require_relative "vendored_thor" unless defined?(Thor) require_relative "../bundler" require "shellwords" diff --git a/lib/bundler/vendor/thor/lib/thor.rb b/lib/bundler/vendor/thor/lib/thor.rb index 395fad28eb..f2a03388cc 100644 --- a/lib/bundler/vendor/thor/lib/thor.rb +++ b/lib/bundler/vendor/thor/lib/thor.rb @@ -175,7 +175,7 @@ class Bundler::Thor handle_no_command_error(meth) unless command shell.say "Usage:" - shell.say " #{banner(command)}" + shell.say " #{banner(command).split("\n").join("\n ")}" shell.say class_options_help(shell, nil => command.options.values) if command.long_description @@ -398,7 +398,10 @@ class Bundler::Thor # the namespace should be displayed as arguments. # def banner(command, namespace = nil, subcommand = false) - "#{basename} #{command.formatted_usage(self, $thor_runner, subcommand)}" + $thor_runner ||= false + command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage| + "#{basename} #{formatted_usage}" + end.join("\n") end def baseclass #:nodoc: diff --git a/lib/bundler/vendor/thor/lib/thor/actions.rb b/lib/bundler/vendor/thor/lib/thor/actions.rb index 5681d5a7c6..39ce67e142 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions.rb @@ -12,6 +12,7 @@ class Bundler::Thor attr_accessor :behavior def self.included(base) #:nodoc: + super(base) base.extend ClassMethods end diff --git a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb index 03c97bf630..d37327a139 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/directory.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/directory.rb @@ -56,7 +56,7 @@ class Bundler::Thor attr_reader :source def initialize(base, source, destination = nil, config = {}, &block) - @source = File.expand_path(base.find_in_source_paths(source.to_s)) + @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)) end @@ -96,22 +96,12 @@ class Bundler::Thor end end - if RUBY_VERSION < "2.0" - def file_level_lookup(previous_lookup) - File.join(previous_lookup, "{*,.[a-z]*}") - end - - def files(lookup) - Dir[lookup] - end - else - def file_level_lookup(previous_lookup) - File.join(previous_lookup, "*") - end + def file_level_lookup(previous_lookup) + File.join(previous_lookup, "*") + end - def files(lookup) - Dir.glob(lookup, File::FNM_DOTMATCH) - end + def files(lookup) + Dir.glob(lookup, File::FNM_DOTMATCH) end end end 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 cc29db05a8..afdbd53dd0 100644 --- a/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +++ b/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb @@ -23,14 +23,14 @@ class Bundler::Thor destination = args.first || source source = File.expand_path(find_in_source_paths(source.to_s)) - create_file destination, nil, config do + resulting_destination = create_file destination, nil, config do content = File.binread(source) content = yield(content) if block content end if config[:mode] == :preserve mode = File.stat(source).mode - chmod(destination, mode, config) + chmod(resulting_destination, mode, config) end end @@ -80,14 +80,14 @@ class Bundler::Thor config = args.last.is_a?(Hash) ? args.pop : {} destination = args.first - if source =~ %r{^https?\://} + render = if source =~ %r{^https?\://} require "open-uri" + URI.send(:open, source) { |input| input.binmode.read } else source = File.expand_path(find_in_source_paths(source.to_s)) + open(source) { |input| input.binmode.read } end - render = open(source) { |input| input.binmode.read } - destination ||= if block_given? block.arity == 1 ? yield(render) : yield else 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 cf651a4e78..09ce0864f0 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 @@ -21,9 +21,14 @@ class Bundler::Thor # gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n") # end # + WARNINGS = { unchanged_no_flag: 'File unchanged! The supplied flag value not found!' } + def insert_into_file(destination, *args, &block) data = block_given? ? block : args.shift - config = args.shift + + config = args.shift || {} + config[:after] = /\z/ unless config.key?(:before) || config.key?(:after) + action InjectIntoFile.new(self, destination, data, config) end alias_method :inject_into_file, :insert_into_file @@ -45,8 +50,6 @@ class Bundler::Thor end def invoke! - say_status :invoke - content = if @behavior == :after '\0' + replacement else @@ -54,7 +57,11 @@ class Bundler::Thor end if exists? - replace!(/#{flag}/, content, config[:force]) + if replace!(/#{flag}/, content, config[:force]) + say_status(:invoke) + else + say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red) + end else unless pretend? raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist" @@ -78,7 +85,7 @@ class Bundler::Thor protected - def say_status(behavior) + def say_status(behavior, warning: nil, color: nil) status = if behavior == :invoke if flag == /\A/ :prepend @@ -87,11 +94,13 @@ class Bundler::Thor else :insert end + elsif warning + warning else :subtract end - super(status, config[:verbose]) + super(status, (color || config[:verbose])) end # Adds the content to the file. @@ -100,8 +109,10 @@ class Bundler::Thor return if pretend? content = File.read(destination) if force || !content.include?(replacement) - content.gsub!(regexp, string) + success = content.gsub!(regexp, string) + File.open(destination, "wb") { |file| file.write(content) } + success end end end diff --git a/lib/bundler/vendor/thor/lib/thor/base.rb b/lib/bundler/vendor/thor/lib/thor/base.rb index 7d7cd3b5fe..6089fd3dc4 100644 --- a/lib/bundler/vendor/thor/lib/thor/base.rb +++ b/lib/bundler/vendor/thor/lib/thor/base.rb @@ -1,6 +1,5 @@ require_relative "command" require_relative "core_ext/hash_with_indifferent_access" -require_relative "core_ext/ordered_hash" require_relative "error" require_relative "invocation" require_relative "parser" @@ -89,6 +88,7 @@ class Bundler::Thor class << self def included(base) #:nodoc: + super(base) base.extend ClassMethods base.send :include, Invocation base.send :include, Shell @@ -353,22 +353,22 @@ class Bundler::Thor # Returns the commands for this Bundler::Thor class. # # ==== Returns - # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command - # objects as values. + # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command + # objects as values. # def commands - @commands ||= Bundler::Thor::CoreExt::OrderedHash.new + @commands ||= Hash.new end alias_method :tasks, :commands # Returns the commands for this Bundler::Thor class and all subclasses. # # ==== Returns - # OrderedHash:: An ordered hash with commands names as keys and Bundler::Thor::Command - # objects as values. + # Hash:: An ordered hash with commands names as keys and Bundler::Thor::Command + # objects as values. # def all_commands - @all_commands ||= from_superclass(:all_commands, Bundler::Thor::CoreExt::OrderedHash.new) + @all_commands ||= from_superclass(:all_commands, Hash.new) @all_commands.merge!(commands) end alias_method :all_tasks, :all_commands @@ -502,7 +502,7 @@ class Bundler::Thor 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}" + msg << "\nUsage: \"#{banner(command).split("\n").join("\"\n \"")}\"" raise InvocationError, msg end @@ -596,6 +596,7 @@ class Bundler::Thor # Everytime someone inherits from a Bundler::Thor class, register the klass # and file into baseclass. def inherited(klass) + super(klass) Bundler::Thor::Base.register_klass_file(klass) klass.instance_variable_set(:@no_commands, false) end @@ -603,6 +604,7 @@ class Bundler::Thor # Fire this callback whenever a method is added. Added methods are # tracked as commands by invoking the create_command method. def method_added(meth) + super(meth) meth = meth.to_s if meth == "initialize" diff --git a/lib/bundler/vendor/thor/lib/thor/command.rb b/lib/bundler/vendor/thor/lib/thor/command.rb index c636948e5d..040c971c0c 100644 --- a/lib/bundler/vendor/thor/lib/thor/command.rb +++ b/lib/bundler/vendor/thor/lib/thor/command.rb @@ -49,24 +49,32 @@ class Bundler::Thor formatted ||= "".dup - # Add usage with required arguments - formatted << if klass && !klass.arguments.empty? - usage.to_s.gsub(/^#{name}/) do |match| - match << " " << klass.arguments.map(&:usage).compact.join(" ") - end - else - usage.to_s - end + Array(usage).map do |specific_usage| + formatted_specific_usage = formatted - # Add required options - formatted << " #{required_options}" + formatted_specific_usage += required_arguments_for(klass, specific_usage) - # Strip and go! - formatted.strip + # Add required options + formatted_specific_usage += " #{required_options}" + + # Strip and go! + formatted_specific_usage.strip + end.join("\n") end protected + # Add usage with required arguments + def required_arguments_for(klass, usage) + if klass && !klass.arguments.empty? + usage.to_s.gsub(/^#{name}/) do |match| + match << " " << klass.arguments.map(&:usage).compact.join(" ") + end + else + usage.to_s + end + end + def not_debugging?(instance) !(instance.class.respond_to?(:debugging) && instance.class.debugging) end @@ -97,8 +105,7 @@ class Bundler::Thor def handle_argument_error?(instance, error, caller) not_debugging?(instance) && (error.message =~ /wrong number of arguments/ || error.message =~ /given \d*, expected \d*/) && begin saned = sans_backtrace(error.backtrace, caller) - # Ruby 1.9 always include the called method in the backtrace - saned.empty? || (saned.size == 1 && RUBY_VERSION >= "1.9") + saned.empty? || saned.size == 1 end end diff --git a/lib/bundler/vendor/thor/lib/thor/error.rb b/lib/bundler/vendor/thor/lib/thor/error.rb index 16c68294e4..1553afd201 100644 --- a/lib/bundler/vendor/thor/lib/thor/error.rb +++ b/lib/bundler/vendor/thor/lib/thor/error.rb @@ -1,22 +1,18 @@ class Bundler::Thor - Correctable = - begin - require 'did_you_mean' - - # 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 - - DidYouMean::Correctable - rescue LoadError, NameError - end + Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) + # 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 + + DidYouMean::Correctable + 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. diff --git a/lib/bundler/vendor/thor/lib/thor/invocation.rb b/lib/bundler/vendor/thor/lib/thor/invocation.rb index 866d2212a7..248a466f8e 100644 --- a/lib/bundler/vendor/thor/lib/thor/invocation.rb +++ b/lib/bundler/vendor/thor/lib/thor/invocation.rb @@ -1,6 +1,7 @@ class Bundler::Thor module Invocation def self.included(base) #:nodoc: + super(base) base.extend ClassMethods end 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 0adb2b3137..fe3d7c998f 100644 --- a/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb +++ b/lib/bundler/vendor/thor/lib/thor/line_editor/basic.rb @@ -24,7 +24,7 @@ class Bundler::Thor $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" + require "io/console" $stdin.noecho(&:gets) end end diff --git a/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb b/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb index dd39cff35d..120eadd06a 100644 --- a/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb +++ b/lib/bundler/vendor/thor/lib/thor/line_editor/readline.rb @@ -1,19 +1,19 @@ -begin - require "readline" -rescue LoadError -end - class Bundler::Thor module LineEditor class Readline < Basic def self.available? + begin + require "readline" + rescue LoadError + end + Object.const_defined?(:Readline) end def readline if echo? ::Readline.completion_append_character = nil - # Ruby 1.8.7 does not allow Readline.completion_proc= to receive nil. + # rb-readline does not allow Readline.completion_proc= to receive nil. if complete = completion_proc ::Readline.completion_proc = complete end diff --git a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb index 1fd790f4b7..a17a3fcf22 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/arguments.rb @@ -9,7 +9,7 @@ class Bundler::Thor arguments = [] args.each do |item| - break if item =~ /^-/ + break if item.is_a?(String) && item =~ /^-/ arguments << item end diff --git a/lib/bundler/vendor/thor/lib/thor/parser/option.rb b/lib/bundler/vendor/thor/lib/thor/parser/option.rb index 85169b56c8..0ddd472b43 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/option.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/option.rb @@ -1,17 +1,18 @@ class Bundler::Thor class Option < Argument #:nodoc: - attr_reader :aliases, :group, :lazy_default, :hide + attr_reader :aliases, :group, :lazy_default, :hide, :repeatable 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) + @repeatable = options.fetch(:repeatable, false) super - @lazy_default = options[:lazy_default] - @group = options[:group].to_s.capitalize if options[:group] - @aliases = Array(options[:aliases]) - @hide = options[:hide] + @lazy_default = options[:lazy_default] + @group = options[:group].to_s.capitalize if options[:group] + @aliases = Array(options[:aliases]) + @hide = options[:hide] end # This parse quick options given as method_options. It makes several @@ -128,7 +129,8 @@ class Bundler::Thor @default.class.name.downcase.to_sym end - raise ArgumentError, "Expected #{@type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == @type + expected_type = (@repeatable && @type != :hash) ? :array : @type + raise ArgumentError, "Expected #{expected_type} default value for '#{switch_name}'; got #{@default.inspect} (#{default_type})" unless default_type == expected_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 179f4fa015..6d1342ee3c 100644 --- a/lib/bundler/vendor/thor/lib/thor/parser/options.rb +++ b/lib/bundler/vendor/thor/lib/thor/parser/options.rb @@ -97,7 +97,8 @@ class Bundler::Thor switch = normalize_switch(switch) option = switch_option(switch) - @assigns[option.human_name] = parse_peek(switch, option) + result = parse_peek(switch, option) + assign_result!(option, result) elsif @stop_on_unknown @parsing_options = false @extra << shifted @@ -132,6 +133,15 @@ class Bundler::Thor protected + def assign_result!(option, result) + if option.repeatable && option.type == :hash + (@assigns[option.human_name] ||= {}).merge!(result) + elsif option.repeatable + (@assigns[option.human_name] ||= []) << result + else + @assigns[option.human_name] = result + end + end # Check if the current value in peek is a registered switch. # # Two booleans are returned. The first is true if the current value @@ -161,7 +171,7 @@ class Bundler::Thor end def switch?(arg) - switch_option(normalize_switch(arg)) + !switch_option(normalize_switch(arg)).nil? end def switch_option(arg) @@ -194,7 +204,7 @@ class Bundler::Thor shift false else - !no_or_skip?(switch) + @switches.key?(switch) || !no_or_skip?(switch) end else @switches.key?(switch) || !no_or_skip?(switch) diff --git a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb index 60282e2991..f8f86372cc 100644 --- a/lib/bundler/vendor/thor/lib/thor/rake_compat.rb +++ b/lib/bundler/vendor/thor/lib/thor/rake_compat.rb @@ -25,6 +25,7 @@ class Bundler::Thor end def self.included(base) + super(base) # Hack. Make rakefile point to invoker, so rdoc task is generated properly. rakefile = File.basename(caller[0].match(/(.*):\d+/)[1]) Rake.application.instance_variable_set(:@rakefile, rakefile) diff --git a/lib/bundler/vendor/thor/lib/thor/runner.rb b/lib/bundler/vendor/thor/lib/thor/runner.rb index ed44853a00..48d33d7ac3 100644 --- a/lib/bundler/vendor/thor/lib/thor/runner.rb +++ b/lib/bundler/vendor/thor/lib/thor/runner.rb @@ -7,6 +7,8 @@ require "digest/md5" require "pathname" class Bundler::Thor::Runner < Bundler::Thor #:nodoc: # rubocop:disable ClassLength + autoload :OpenURI, "open-uri" + map "-T" => :list, "-i" => :install, "-u" => :update, "-v" => :version def self.banner(command, all = false, subcommand = false) diff --git a/lib/bundler/vendor/thor/lib/thor/shell/color.rb b/lib/bundler/vendor/thor/lib/thor/shell/color.rb index 6c821d4a09..29f280202d 100644 --- a/lib/bundler/vendor/thor/lib/thor/shell/color.rb +++ b/lib/bundler/vendor/thor/lib/thor/shell/color.rb @@ -97,7 +97,11 @@ class Bundler::Thor protected def can_display_colors? - stdout.tty? + stdout.tty? && !are_colors_disabled? + end + + def are_colors_disabled? + !ENV['NO_COLOR'].nil? end # Overwrite show_diff to show diff with colors if Diff::LCS is diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb index 81b4d99064..df10bd3498 100644 --- a/spec/bundler/commands/binstubs_spec.rb +++ b/spec/bundler/commands/binstubs_spec.rb @@ -141,38 +141,61 @@ RSpec.describe "bundle binstubs <gem>" do end context "when a lockfile exists with a locked bundler version" do - it "runs the correct version of bundler when the version is newer" do - lockfile lockfile.gsub(system_bundler_version, "999.999.999") - sys_exec "#{bundled_app("bin/bundle")} install" - expect(exitstatus).to eq(42) if exitstatus - expect(err).to include("Activating bundler (~> 999.999) failed:"). - and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`") + context "and the version is newer" do + before do + lockfile lockfile.gsub(system_bundler_version, "999.999") + end + + it "runs the correct version of bundler" do + sys_exec "#{bundled_app("bin/bundle")} install" + expect(exitstatus).to eq(42) if exitstatus + expect(err).to include("Activating bundler (~> 999.999) failed:"). + and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`") + end end - it "runs the correct version of bundler when the version is older and a different major" do - simulate_bundler_version "55" - lockfile lockfile.gsub(system_bundler_version, "44.0") - sys_exec "#{bundled_app("bin/bundle")} install" - expect(exitstatus).to eq(42) if exitstatus - expect(err).to include("Activating bundler (~> 44.0) failed:"). - and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`") + context "and the version is older and a different major" do + let(:system_bundler_version) { "55" } + + before do + lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 44.0") + end + + it "runs the correct version of bundler" do + sys_exec "#{bundled_app("bin/bundle")} install" + expect(exitstatus).to eq(42) if exitstatus + expect(err).to include("Activating bundler (~> 44.0) failed:"). + and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`") + end end - it "runs the available version of bundler when the version is older and the same major" do - simulate_bundler_version "55.1" - lockfile lockfile.gsub(system_bundler_version, "55.0") - sys_exec "#{bundled_app("bin/bundle")} install" - expect(exitstatus).not_to eq(42) if exitstatus - expect(err).not_to include("Activating bundler (~> 55.0) failed:") + context "and the version is older and the same major" do + let(:system_bundler_version) { "55.1" } + + before do + lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 55.0") + end + + it "runs the available version of bundler when the version is older and the same major" do + sys_exec "#{bundled_app("bin/bundle")} install" + expect(exitstatus).not_to eq(42) if exitstatus + expect(err).not_to include("Activating bundler (~> 55.0) failed:") + end end - it "runs the correct version of bundler when the version is a pre-release" do - simulate_bundler_version "55" - lockfile lockfile.gsub(system_bundler_version, "2.12.0.a") - sys_exec "#{bundled_app("bin/bundle")} install" - expect(exitstatus).to eq(42) if exitstatus - expect(err).to include("Activating bundler (~> 2.12.a) failed:"). - and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 2.12.a'`") + context "and the version is a pre-releaser" do + let(:system_bundler_version) { "55" } + + before do + lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.12.0.a") + end + + it "runs the correct version of bundler when the version is a pre-release" do + sys_exec "#{bundled_app("bin/bundle")} install" + expect(exitstatus).to eq(42) if exitstatus + expect(err).to include("Activating bundler (~> 2.12.a) failed:"). + and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 2.12.a'`") + end end end diff --git a/spec/bundler/install/binstubs_spec.rb b/spec/bundler/install/binstubs_spec.rb index e7aa577077..78ee893b81 100644 --- a/spec/bundler/install/binstubs_spec.rb +++ b/spec/bundler/install/binstubs_spec.rb @@ -7,7 +7,6 @@ RSpec.describe "bundle install" do it "overrides Gem.bindir" do expect(Pathname.new("/usr/bin")).not_to be_writable unless Process.euid == 0 gemfile <<-G - require 'rubygems' def Gem.bindir; "/usr/bin"; end source "#{file_uri_for(gem_repo1)}" gem "rack" diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index 08789820d8..00f8e96625 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -1056,7 +1056,6 @@ RSpec.describe "bundle install with git sources" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}" end @@ -1076,7 +1075,6 @@ RSpec.describe "bundle install with git sources" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require '#{spec_dir}/support/rubygems' Gem.post_install_hooks << lambda do |inst| STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}" end @@ -1096,7 +1094,6 @@ RSpec.describe "bundle install with git sources" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| false end diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index 5261e18bbe..786b767354 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -672,7 +672,6 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}" end @@ -692,7 +691,6 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require '#{spec_dir}/support/rubygems' Gem.post_install_hooks << lambda do |inst| STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}" end @@ -712,7 +710,6 @@ RSpec.describe "bundle install with explicit source paths" do File.open(lib_path("install_hooks.rb"), "w") do |h| h.write <<-H - require '#{spec_dir}/support/rubygems' Gem.pre_install_hooks << lambda do |inst| false end diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index e291fb7917..ddab4831a5 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -1418,7 +1418,6 @@ RSpec.describe "the lockfile format" do it "preserves Gemfile.lock \\n line endings" do expect do ruby <<-RUBY - require 'rubygems' require 'bundler' Bundler.setup RUBY @@ -1432,7 +1431,6 @@ RSpec.describe "the lockfile format" do expect do ruby <<-RUBY - require 'rubygems' require 'bundler' Bundler.setup RUBY diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb index 57b68fdb97..f743bccb92 100644 --- a/spec/bundler/other/major_deprecation_spec.rb +++ b/spec/bundler/other/major_deprecation_spec.rb @@ -356,9 +356,7 @@ RSpec.describe "major deprecations" do G ruby <<-RUBY - require 'rubygems' - require 'bundler' - require 'bundler/vendored_thor' + require '#{lib_dir}/bundler' Bundler.setup Bundler.setup diff --git a/spec/bundler/other/platform_spec.rb b/spec/bundler/other/platform_spec.rb index 4feec14d76..8b02505ad8 100644 --- a/spec/bundler/other/platform_spec.rb +++ b/spec/bundler/other/platform_spec.rb @@ -1086,7 +1086,6 @@ G FileUtils.rm(bundled_app("Gemfile.lock")) ruby <<-R - require 'rubygems' require 'bundler/setup' R @@ -1106,7 +1105,6 @@ G FileUtils.rm(bundled_app("Gemfile.lock")) ruby <<-R - require 'rubygems' require 'bundler/setup' R @@ -1127,7 +1125,6 @@ G FileUtils.rm(bundled_app("Gemfile.lock")) ruby <<-R - require 'rubygems' require 'bundler/setup' R @@ -1148,7 +1145,6 @@ G FileUtils.rm(bundled_app("Gemfile.lock")) ruby <<-R - require 'rubygems' require 'bundler/setup' R diff --git a/spec/bundler/rubygems/rubygems.rb b/spec/bundler/rubygems/rubygems.rb new file mode 100644 index 0000000000..6fa63013bf --- /dev/null +++ b/spec/bundler/rubygems/rubygems.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require_relative "../support/rubygems_version_manager" + +RubygemsVersionManager.new(ENV["RGV"]).switch + +$:.delete("#{Spec::Path.spec_dir}/rubygems") + +require "rubygems" diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index e5569fec94..06be2ef83d 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -115,7 +115,7 @@ RSpec.describe "bundler/inline#gemfile" do it "has an option for quiet installation" do script <<-RUBY, :artifice => "endpoint" - require 'bundler' + require '#{lib_dir}/bundler/inline' gemfile(true, :quiet => true) do source "https://notaserver.com" diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 72ad06a43a..4a754945b7 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -985,9 +985,7 @@ end build_git "bar", :gemspec => false do |s| s.write "lib/bar/version.rb", %(BAR_VERSION = '1.0') s.write "bar.gemspec", <<-G - lib = File.expand_path('../lib/', __FILE__) - $:.unshift lib unless $:.include?(lib) - require 'bar/version' + require_relative 'lib/bar/version' Gem::Specification.new do |s| s.name = 'bar' diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb index ba21d22fbd..9702ab71f5 100644 --- a/spec/bundler/spec_helper.rb +++ b/spec/bundler/spec_helper.rb @@ -82,7 +82,7 @@ RSpec.configure do |config| config.before :suite do require_relative "support/rubygems_ext" Spec::Rubygems.setup - ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -r#{Spec::Path.spec_dir}/support/hax.rb" + ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -I#{Spec::Path.spec_dir}/rubygems -r#{Spec::Path.spec_dir}/support/hax.rb" ENV["BUNDLE_SPEC_RUN"] = "true" ENV["BUNDLE_USER_CONFIG"] = ENV["BUNDLE_USER_CACHE"] = ENV["BUNDLE_USER_PLUGIN"] = nil ENV["GEMRC"] = nil diff --git a/spec/bundler/support/hax.rb b/spec/bundler/support/hax.rb index 3e1ece2f0a..c18470acd2 100644 --- a/spec/bundler/support/hax.rb +++ b/spec/bundler/support/hax.rb @@ -28,7 +28,8 @@ module Gem end if ENV["BUNDLER_SPEC_VERSION"] - require "bundler/version" + require_relative "path" + require "#{Spec::Path.lib_dir}/bundler/version" module Bundler remove_const(:VERSION) if const_defined?(:VERSION) @@ -37,7 +38,8 @@ if ENV["BUNDLER_SPEC_VERSION"] end if ENV["BUNDLER_SPEC_WINDOWS"] == "true" - require "bundler/constants" + require_relative "path" + require "#{Spec::Path.lib_dir}/bundler/constants" module Bundler remove_const :WINDOWS if defined?(WINDOWS) diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb index 8bf76bba89..911f734d8b 100644 --- a/spec/bundler/support/helpers.rb +++ b/spec/bundler/support/helpers.rb @@ -110,7 +110,6 @@ module Spec env["PATH"].gsub!("#{Path.root}/exe", "") if env["PATH"] && system_bundler requires = options.delete(:requires) || [] - requires << "support/rubygems" requires << "support/hax" artifice = options.delete(:artifice) do @@ -144,7 +143,7 @@ module Spec end end.join - cmd = "#{sudo} #{Gem.ruby} --disable-gems #{load_path_str} #{requires_str} #{bundle_bin} #{cmd}#{args}" + cmd = "#{sudo} #{Gem.ruby} #{load_path_str} #{requires_str} #{bundle_bin} #{cmd}#{args}" sys_exec(cmd, env) {|i, o, thr| yield i, o, thr if block_given? } end bang :bundle diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb index 69d3be4a3d..e1a08a30cc 100644 --- a/spec/bundler/support/matchers.rb +++ b/spec/bundler/support/matchers.rb @@ -128,9 +128,10 @@ module Spec groups << opts @errors = names.map do |name| name, version, platform = name.split(/\s+/) + require_path = name == "bundler" ? "#{lib_dir}/bundler" : name version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name) begin - run! "require '#{name}.rb'; puts #{version_const}", *groups + run! "require '#{require_path}.rb'; puts #{version_const}", *groups rescue StandardError => e next "#{name} is not installed:\n#{indent(e)}" end diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index b957e24abe..cc5aebb01b 100644 --- a/spec/bundler/support/path.rb +++ b/spec/bundler/support/path.rb @@ -22,7 +22,7 @@ module Spec end def gem_bin - @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "#{Gem.ruby} --disable-gems -r#{spec_dir}/support/rubygems -S gem --backtrace" + @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "#{Gem.ruby} -I#{spec_dir}/rubygems -S gem --backtrace" end def spec_dir diff --git a/spec/bundler/support/rubygems.rb b/spec/bundler/support/rubygems.rb deleted file mode 100644 index e60f9a928e..0000000000 --- a/spec/bundler/support/rubygems.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -require_relative "rubygems_version_manager" - -RubygemsVersionManager.new(ENV["RGV"]).switch - -require "rubygems" diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb index 1093362d81..d237897b67 100644 --- a/spec/bundler/support/rubygems_ext.rb +++ b/spec/bundler/support/rubygems_ext.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require_relative "path" -require "fileutils" module Spec module Rubygems @@ -40,7 +39,7 @@ module Spec end def gem_load(gem_name, bin_container) - require_relative "rubygems" + require_relative "../rubygems/rubygems" gem_load_and_activate(gem_name, bin_container) end @@ -50,6 +49,8 @@ module Spec end def setup + require "fileutils" + Gem.clear_paths ENV["BUNDLE_PATH"] = nil diff --git a/spec/bundler/support/rubygems_version_manager.rb b/spec/bundler/support/rubygems_version_manager.rb index 31f7cc4b08..356d391c08 100644 --- a/spec/bundler/support/rubygems_version_manager.rb +++ b/spec/bundler/support/rubygems_version_manager.rb @@ -56,7 +56,7 @@ private end def rubygems_unrequire_needed? - defined?(Gem) && Gem::VERSION != target_gem_version + defined?(Gem::VERSION) && Gem::VERSION != target_gem_version end def local_copy_switch_needed? |