Stop generating binstubs for Bundler itself
This commit is contained in:
parent
56e2ef2468
commit
451d848a76
@ -91,6 +91,11 @@ module Bundler
|
|||||||
end
|
end
|
||||||
|
|
||||||
def generate_bundler_executable_stubs(spec, options = {})
|
def generate_bundler_executable_stubs(spec, options = {})
|
||||||
|
if spec.name == "bundler"
|
||||||
|
Bundler.ui.warn "Bundler itself does not use binstubs because its version is selected by RubyGems"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if options[:binstubs_cmd] && spec.executables.empty?
|
if options[:binstubs_cmd] && spec.executables.empty?
|
||||||
options = {}
|
options = {}
|
||||||
spec.runtime_dependencies.each do |dep|
|
spec.runtime_dependencies.each do |dep|
|
||||||
@ -115,10 +120,6 @@ module Bundler
|
|||||||
ruby_command = Thor::Util.ruby_command
|
ruby_command = Thor::Util.ruby_command
|
||||||
ruby_command = ruby_command
|
ruby_command = ruby_command
|
||||||
template_path = File.expand_path("templates/Executable", __dir__)
|
template_path = File.expand_path("templates/Executable", __dir__)
|
||||||
if spec.name == "bundler"
|
|
||||||
template_path += ".bundler"
|
|
||||||
spec.executables = %(bundle)
|
|
||||||
end
|
|
||||||
template = File.read(template_path)
|
template = File.read(template_path)
|
||||||
|
|
||||||
exists = []
|
exists = []
|
||||||
|
@ -10,17 +10,6 @@
|
|||||||
|
|
||||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("<%= relative_gemfile_path %>", __dir__)
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("<%= relative_gemfile_path %>", __dir__)
|
||||||
|
|
||||||
bundle_binstub = File.expand_path("bundle", __dir__)
|
|
||||||
|
|
||||||
if File.file?(bundle_binstub)
|
|
||||||
if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
|
|
||||||
load(bundle_binstub)
|
|
||||||
else
|
|
||||||
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
|
||||||
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
require "rubygems"
|
require "rubygems"
|
||||||
require "bundler/setup"
|
require "bundler/setup"
|
||||||
|
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
#!/usr/bin/env <%= Bundler.settings[:shebang] || RbConfig::CONFIG["ruby_install_name"] %>
|
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
#
|
|
||||||
# This file was generated by Bundler.
|
|
||||||
#
|
|
||||||
# The application '<%= executable %>' is installed as part of a gem, and
|
|
||||||
# this file is here to facilitate running it.
|
|
||||||
#
|
|
||||||
|
|
||||||
require "rubygems"
|
|
||||||
|
|
||||||
m = Module.new do
|
|
||||||
module_function
|
|
||||||
|
|
||||||
def invoked_as_script?
|
|
||||||
File.expand_path($0) == File.expand_path(__FILE__)
|
|
||||||
end
|
|
||||||
|
|
||||||
def env_var_version
|
|
||||||
ENV["BUNDLER_VERSION"]
|
|
||||||
end
|
|
||||||
|
|
||||||
def cli_arg_version
|
|
||||||
return unless invoked_as_script? # don't want to hijack other binstubs
|
|
||||||
return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
|
|
||||||
bundler_version = nil
|
|
||||||
update_index = nil
|
|
||||||
ARGV.each_with_index do |a, i|
|
|
||||||
if update_index && update_index.succ == i && a.match?(Gem::Version::ANCHORED_VERSION_PATTERN)
|
|
||||||
bundler_version = a
|
|
||||||
end
|
|
||||||
next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
|
|
||||||
bundler_version = $1
|
|
||||||
update_index = i
|
|
||||||
end
|
|
||||||
bundler_version
|
|
||||||
end
|
|
||||||
|
|
||||||
def gemfile
|
|
||||||
gemfile = ENV["BUNDLE_GEMFILE"]
|
|
||||||
return gemfile if gemfile && !gemfile.empty?
|
|
||||||
|
|
||||||
File.expand_path("<%= relative_gemfile_path %>", __dir__)
|
|
||||||
end
|
|
||||||
|
|
||||||
def lockfile
|
|
||||||
lockfile =
|
|
||||||
case File.basename(gemfile)
|
|
||||||
when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
|
|
||||||
else "#{gemfile}.lock"
|
|
||||||
end
|
|
||||||
File.expand_path(lockfile)
|
|
||||||
end
|
|
||||||
|
|
||||||
def lockfile_version
|
|
||||||
return unless File.file?(lockfile)
|
|
||||||
lockfile_contents = File.read(lockfile)
|
|
||||||
return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
|
|
||||||
Regexp.last_match(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
def bundler_requirement
|
|
||||||
@bundler_requirement ||=
|
|
||||||
env_var_version ||
|
|
||||||
cli_arg_version ||
|
|
||||||
bundler_requirement_for(lockfile_version)
|
|
||||||
end
|
|
||||||
|
|
||||||
def bundler_requirement_for(version)
|
|
||||||
return "#{Gem::Requirement.default}.a" unless version
|
|
||||||
|
|
||||||
bundler_gem_version = Gem::Version.new(version)
|
|
||||||
|
|
||||||
bundler_gem_version.approximate_recommendation
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_bundler!
|
|
||||||
ENV["BUNDLE_GEMFILE"] ||= gemfile
|
|
||||||
|
|
||||||
activate_bundler
|
|
||||||
end
|
|
||||||
|
|
||||||
def activate_bundler
|
|
||||||
gem_error = activation_error_handling do
|
|
||||||
gem "bundler", bundler_requirement
|
|
||||||
end
|
|
||||||
return if gem_error.nil?
|
|
||||||
require_error = activation_error_handling do
|
|
||||||
require "bundler/version"
|
|
||||||
end
|
|
||||||
return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
|
||||||
warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
|
|
||||||
exit 42
|
|
||||||
end
|
|
||||||
|
|
||||||
def activation_error_handling
|
|
||||||
yield
|
|
||||||
nil
|
|
||||||
rescue StandardError, LoadError => e
|
|
||||||
e
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
m.load_bundler!
|
|
||||||
|
|
||||||
if m.invoked_as_script?
|
|
||||||
load Gem.bin_path("<%= spec.name %>", "<%= executable %>")
|
|
||||||
end
|
|
@ -85,220 +85,6 @@ RSpec.describe "bundle binstubs <gem>" do
|
|||||||
expect(err).to include("Cannot specify --all with specific gems")
|
expect(err).to include("Cannot specify --all with specific gems")
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when generating bundle binstub outside bundler" do
|
|
||||||
it "should abort" do
|
|
||||||
install_gemfile <<-G
|
|
||||||
source "https://gem.repo1"
|
|
||||||
gem "myrack"
|
|
||||||
G
|
|
||||||
|
|
||||||
bundle "binstubs myrack"
|
|
||||||
|
|
||||||
File.open(bundled_app("bin/bundle"), "wb") do |file|
|
|
||||||
file.print "OMG"
|
|
||||||
end
|
|
||||||
|
|
||||||
sys_exec "bin/myrackup", raise_on_error: false
|
|
||||||
|
|
||||||
expect(err).to include("was not generated by Bundler")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "the bundle binstub" do
|
|
||||||
before do
|
|
||||||
pristine_system_gems "bundler-#{system_bundler_version}"
|
|
||||||
build_repo2 do
|
|
||||||
build_gem "myrack", "1.2" do |s|
|
|
||||||
s.executables = "myrackup"
|
|
||||||
end
|
|
||||||
|
|
||||||
build_gem "prints_loaded_gems", "1.0" do |s|
|
|
||||||
s.executables = "print_loaded_gems"
|
|
||||||
s.bindir = "exe"
|
|
||||||
s.write "exe/print_loaded_gems", <<~R
|
|
||||||
#!/usr/bin/env ruby
|
|
||||||
specs = Gem.loaded_specs.values.reject {|s| s.default_gem? }
|
|
||||||
puts specs.map(&:full_name).sort.inspect
|
|
||||||
R
|
|
||||||
end
|
|
||||||
|
|
||||||
build_bundler locked_bundler_version
|
|
||||||
end
|
|
||||||
install_gemfile <<-G
|
|
||||||
source "https://gem.repo2"
|
|
||||||
gem "myrack"
|
|
||||||
gem "prints_loaded_gems"
|
|
||||||
G
|
|
||||||
bundle "binstubs bundler myrack prints_loaded_gems"
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:system_bundler_version) { Bundler::VERSION }
|
|
||||||
let(:locked_bundler_version) { nil }
|
|
||||||
let(:lockfile_content) { lockfile.gsub(system_bundler_version, locked_bundler_version) }
|
|
||||||
|
|
||||||
it "runs bundler" do
|
|
||||||
bundle "install --verbose", bundle_bin: "bin/bundle"
|
|
||||||
expect(out).to include %(Using bundler #{system_bundler_version}\n)
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when BUNDLER_VERSION is set" do
|
|
||||||
it "runs the correct version of bundler" do
|
|
||||||
bundle "install", env: { "BUNDLER_VERSION" => "999.999.999" }, raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
expect(err).to include("Activating bundler (999.999.999) failed:").
|
|
||||||
and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "runs the correct version of bundler even if a higher version is installed" do
|
|
||||||
system_gems "bundler-999.999.998", "bundler-999.999.999"
|
|
||||||
|
|
||||||
bundle "install --verbose", env: { "BUNDLER_VERSION" => "999.999.998" }, raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(out).to include %(Using bundler 999.999.998\n)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when a lockfile exists with a locked bundler version" do
|
|
||||||
let(:locked_bundler_version) { "999.999" }
|
|
||||||
|
|
||||||
context "and the version is newer" do
|
|
||||||
before do
|
|
||||||
lockfile lockfile_content
|
|
||||||
end
|
|
||||||
|
|
||||||
it "runs the correct version of bundler" do
|
|
||||||
bundle "install", raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
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
|
|
||||||
|
|
||||||
context "and the version is newer when given `gems.rb` and `gems.locked`" do
|
|
||||||
before do
|
|
||||||
gemfile bundled_app("gems.rb"), gemfile
|
|
||||||
lockfile bundled_app("gems.locked"), lockfile_content
|
|
||||||
end
|
|
||||||
|
|
||||||
it "runs the correct version of bundler" do
|
|
||||||
bundle "install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
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
|
|
||||||
|
|
||||||
context "and the version is older and a different major" do
|
|
||||||
let(:system_bundler_version) { "55" }
|
|
||||||
let(:locked_bundler_version) { "44" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
lockfile lockfile_content
|
|
||||||
end
|
|
||||||
|
|
||||||
it "runs the correct version of bundler" do
|
|
||||||
bundle "install", raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
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
|
|
||||||
|
|
||||||
context "and the version is older and a different major when given `gems.rb` and `gems.locked`" do
|
|
||||||
let(:system_bundler_version) { "55" }
|
|
||||||
let(:locked_bundler_version) { "44" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
gemfile bundled_app("gems.rb"), gemfile
|
|
||||||
lockfile bundled_app("gems.locked"), lockfile_content
|
|
||||||
end
|
|
||||||
|
|
||||||
it "runs the correct version of bundler" do
|
|
||||||
bundle "install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
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
|
|
||||||
|
|
||||||
context "and the version is older and the same major" do
|
|
||||||
let(:system_bundler_version) { "2.999.999" }
|
|
||||||
let(:locked_bundler_version) { "2.3.0" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
lockfile lockfile_content
|
|
||||||
end
|
|
||||||
|
|
||||||
it "installs and runs the exact version of bundler" do
|
|
||||||
bundle "install --verbose", bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).not_to eq(42)
|
|
||||||
expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.")
|
|
||||||
expect(out).to include("Using bundler 2.3.0")
|
|
||||||
expect(err).not_to include("Activating bundler (~> 2.3.0) failed:")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "and the version is a pre-releaser" do
|
|
||||||
let(:system_bundler_version) { "55" }
|
|
||||||
let(:locked_bundler_version) { "2.12.0.a" }
|
|
||||||
|
|
||||||
before do
|
|
||||||
lockfile lockfile_content
|
|
||||||
end
|
|
||||||
|
|
||||||
it "runs the correct version of bundler when the version is a pre-release" do
|
|
||||||
bundle "install", raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
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
|
|
||||||
|
|
||||||
context "when update --bundler is called" do
|
|
||||||
it "calls through to the latest bundler version" do
|
|
||||||
bundle "update --bundler --verbose", bundle_bin: "bin/bundle"
|
|
||||||
using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out)
|
|
||||||
expect(using_bundler_line).to_not be_nil
|
|
||||||
latest_version = using_bundler_line[1]
|
|
||||||
expect(Gem::Version.new(latest_version)).to be >= Gem::Version.new(system_bundler_version)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "calls through to the explicit bundler version" do
|
|
||||||
bundle "update --bundler=999.999.999", raise_on_error: false, bundle_bin: "bin/bundle"
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
expect(err).to include("Activating bundler (999.999.999) failed:").
|
|
||||||
and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "without a lockfile" do
|
|
||||||
it "falls back to the latest installed bundler" do
|
|
||||||
FileUtils.rm bundled_app_lock
|
|
||||||
bundle "install --verbose", bundle_bin: "bin/bundle"
|
|
||||||
expect(out).to include "Using bundler #{system_bundler_version}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "using another binstub" do
|
|
||||||
it "loads all gems" do
|
|
||||||
sys_exec bundled_app("bin/print_loaded_gems").to_s
|
|
||||||
expect(out).to eq %(["bundler-#{Bundler::VERSION}", "myrack-1.2", "prints_loaded_gems-1.0"])
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when requesting a different bundler version" do
|
|
||||||
before { lockfile lockfile.gsub(Bundler::VERSION, "999.999.999") }
|
|
||||||
|
|
||||||
it "attempts to load that version" do
|
|
||||||
sys_exec bundled_app("bin/myrackup").to_s, raise_on_error: false
|
|
||||||
expect(exitstatus).to eq(42)
|
|
||||||
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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "installs binstubs from git gems" do
|
it "installs binstubs from git gems" do
|
||||||
FileUtils.mkdir_p(lib_path("foo/bin"))
|
FileUtils.mkdir_p(lib_path("foo/bin"))
|
||||||
FileUtils.touch(lib_path("foo/bin/foo"))
|
FileUtils.touch(lib_path("foo/bin/foo"))
|
||||||
|
@ -77,7 +77,7 @@ RSpec.describe "Running bin/* commands" do
|
|||||||
expect(out).to eq("1.0")
|
expect(out).to eq("1.0")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates a bundle binstub" do
|
it "does not create a bundle binstub" do
|
||||||
gemfile <<-G
|
gemfile <<-G
|
||||||
source "https://gem.repo1"
|
source "https://gem.repo1"
|
||||||
gem "bundler"
|
gem "bundler"
|
||||||
@ -85,7 +85,9 @@ RSpec.describe "Running bin/* commands" do
|
|||||||
|
|
||||||
bundle "binstubs bundler"
|
bundle "binstubs bundler"
|
||||||
|
|
||||||
expect(bundled_app("bin/bundle")).to exist
|
expect(bundled_app("bin/bundle")).not_to exist
|
||||||
|
|
||||||
|
expect(err).to include("Bundler itself does not use binstubs because its version is selected by RubyGems")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not generate bin stubs if the option was not specified" do
|
it "does not generate bin stubs if the option was not specified" do
|
||||||
|
Loading…
x
Reference in New Issue
Block a user