summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler/cli/add.rb10
-rw-r--r--lib/bundler/current_ruby.rb2
-rw-r--r--lib/bundler/definition.rb17
-rw-r--r--lib/bundler/rubygems_integration.rb2
-rw-r--r--lib/bundler/runtime.rb9
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/commands/rebuild_command.rb1
-rw-r--r--lib/rubygems/installer.rb7
-rw-r--r--spec/bundler/bundler/current_ruby_spec.rb11
-rw-r--r--spec/bundler/commands/add_spec.rb34
-rw-r--r--spec/bundler/commands/clean_spec.rb37
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb116
-rw-r--r--spec/bundler/realworld/fixtures/tapioca/Gemfile.lock2
-rw-r--r--spec/bundler/realworld/fixtures/warbler/Gemfile.lock2
-rw-r--r--tool/bundler/dev_gems.rb.lock2
-rw-r--r--tool/bundler/rubocop_gems.rb.lock2
-rw-r--r--tool/bundler/standard_gems.rb.lock2
-rw-r--r--tool/bundler/test_gems.rb.lock2
19 files changed, 246 insertions, 16 deletions
diff --git a/lib/bundler/cli/add.rb b/lib/bundler/cli/add.rb
index 12a681a816..9f17604096 100644
--- a/lib/bundler/cli/add.rb
+++ b/lib/bundler/cli/add.rb
@@ -36,6 +36,16 @@ module Bundler
end
def validate_options!
+ raise InvalidOption, "You cannot specify `--git` and `--github` at the same time." if options["git"] && options["github"]
+
+ unless options["git"] || options["github"]
+ raise InvalidOption, "You cannot specify `--branch` unless `--git` or `--github` is specified." if options["branch"]
+
+ raise InvalidOption, "You cannot specify `--ref` unless `--git` or `--github` is specified." if options["ref"]
+ end
+
+ raise InvalidOption, "You cannot specify `--branch` and `--ref` at the same time." if options["branch"] && options["ref"]
+
raise InvalidOption, "You cannot specify `--strict` and `--optimistic` at the same time." if options[:strict] && options[:optimistic]
# raise error when no gems are specified
diff --git a/lib/bundler/current_ruby.rb b/lib/bundler/current_ruby.rb
index ab6520a106..17c7655adb 100644
--- a/lib/bundler/current_ruby.rb
+++ b/lib/bundler/current_ruby.rb
@@ -11,7 +11,7 @@ module Bundler
end
class CurrentRuby
- ALL_RUBY_VERSIONS = [*18..27, *30..34, 40].freeze
+ ALL_RUBY_VERSIONS = [*18..27, *30..34, *40..41].freeze
KNOWN_MINOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.reverse.join(".") }.freeze
KNOWN_MAJOR_VERSIONS = ALL_RUBY_VERSIONS.map {|v| v.digits.last.to_s }.uniq.freeze
PLATFORM_MAP = {
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 2fa7d0d277..5ab577f504 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -1066,7 +1066,22 @@ module Bundler
deps << dep if !replacement_source || lockfile_source.include?(replacement_source) || new_deps.include?(dep)
else
- replacement_source = sources.get(lockfile_source)
+ parent_dep = @dependencies.find do |d|
+ next unless d.source && d.source != lockfile_source
+ next if d.source.is_a?(Source::Gemspec)
+
+ parent_locked_specs = @originally_locked_specs[d.name]
+
+ parent_locked_specs.any? do |parent_spec|
+ parent_spec.runtime_dependencies.any? {|rd| rd.name == s.name }
+ end
+ end
+
+ if parent_dep
+ replacement_source = parent_dep.source
+ else
+ replacement_source = sources.get(lockfile_source)
+ end
end
# Replace the locked dependency's source with the equivalent source from the Gemfile
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index d8f95cffb8..e04ef23259 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -432,7 +432,7 @@ module Bundler
end
def find_bundler(version)
- find_name("bundler").find {|s| s.version.to_s == version }
+ find_name("bundler").find {|s| s.version.to_s == version.to_s }
end
def find_name(name)
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index 5eb827dcb2..5280e72aa2 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -174,7 +174,14 @@ module Bundler
spec_cache_paths = []
spec_gemspec_paths = []
spec_extension_paths = []
- Bundler.rubygems.add_default_gems_to(specs).values.each do |spec|
+ specs_to_keep = Bundler.rubygems.add_default_gems_to(specs).values
+
+ current_bundler = Bundler.rubygems.find_bundler(Bundler.gem_version)
+ if current_bundler
+ specs_to_keep << current_bundler
+ end
+
+ specs_to_keep.each do |spec|
spec_gem_paths << spec.full_gem_path
# need to check here in case gems are nested like for the rails git repo
md = %r{(.+bundler/gems/.+-[a-f0-9]{7,12})}.match(spec.full_gem_path)
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 732b4a0563..8c039d16a0 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "4.0.3".freeze
+ VERSION = "4.0.4".freeze
def self.bundler_major_version
@bundler_major_version ||= gem_version.segments.first
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index e99176fec0..9e90e608a5 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -9,7 +9,7 @@
require "rbconfig"
module Gem
- VERSION = "4.0.3"
+ VERSION = "4.0.4"
end
require_relative "rubygems/defaults"
diff --git a/lib/rubygems/commands/rebuild_command.rb b/lib/rubygems/commands/rebuild_command.rb
index 77a474ef1d..23b9d7b3ba 100644
--- a/lib/rubygems/commands/rebuild_command.rb
+++ b/lib/rubygems/commands/rebuild_command.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
-require "date"
require "digest"
require "fileutils"
require "tmpdir"
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 90aa25dc07..914e413677 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -943,7 +943,12 @@ class Gem::Installer
end
def build_jobs
- @build_jobs ||= Etc.nprocessors + 1
+ @build_jobs ||= begin
+ require "etc"
+ Etc.nprocessors + 1
+ rescue LoadError
+ 1
+ end
end
def rb_config
diff --git a/spec/bundler/bundler/current_ruby_spec.rb b/spec/bundler/bundler/current_ruby_spec.rb
index aa19a41407..79eb802aa5 100644
--- a/spec/bundler/bundler/current_ruby_spec.rb
+++ b/spec/bundler/bundler/current_ruby_spec.rb
@@ -23,6 +23,7 @@ RSpec.describe Bundler::CurrentRuby do
ruby_33: Gem::Platform::RUBY,
ruby_34: Gem::Platform::RUBY,
ruby_40: Gem::Platform::RUBY,
+ ruby_41: Gem::Platform::RUBY,
mri: Gem::Platform::RUBY,
mri_18: Gem::Platform::RUBY,
mri_19: Gem::Platform::RUBY,
@@ -40,6 +41,7 @@ RSpec.describe Bundler::CurrentRuby do
mri_33: Gem::Platform::RUBY,
mri_34: Gem::Platform::RUBY,
mri_40: Gem::Platform::RUBY,
+ mri_41: Gem::Platform::RUBY,
rbx: Gem::Platform::RUBY,
truffleruby: Gem::Platform::RUBY,
jruby: Gem::Platform::JAVA,
@@ -61,7 +63,8 @@ RSpec.describe Bundler::CurrentRuby do
windows_32: Gem::Platform::WINDOWS,
windows_33: Gem::Platform::WINDOWS,
windows_34: Gem::Platform::WINDOWS,
- windows_40: Gem::Platform::WINDOWS }
+ windows_40: Gem::Platform::WINDOWS,
+ windows_41: Gem::Platform::WINDOWS }
end
let(:deprecated) do
@@ -82,6 +85,7 @@ RSpec.describe Bundler::CurrentRuby do
mswin_33: Gem::Platform::MSWIN,
mswin_34: Gem::Platform::MSWIN,
mswin_40: Gem::Platform::MSWIN,
+ mswin_41: Gem::Platform::MSWIN,
mswin64: Gem::Platform::MSWIN64,
mswin64_19: Gem::Platform::MSWIN64,
mswin64_20: Gem::Platform::MSWIN64,
@@ -98,6 +102,7 @@ RSpec.describe Bundler::CurrentRuby do
mswin64_33: Gem::Platform::MSWIN64,
mswin64_34: Gem::Platform::MSWIN64,
mswin64_40: Gem::Platform::MSWIN64,
+ mswin64_41: Gem::Platform::MSWIN64,
mingw: Gem::Platform::UNIVERSAL_MINGW,
mingw_18: Gem::Platform::UNIVERSAL_MINGW,
mingw_19: Gem::Platform::UNIVERSAL_MINGW,
@@ -115,6 +120,7 @@ RSpec.describe Bundler::CurrentRuby do
mingw_33: Gem::Platform::UNIVERSAL_MINGW,
mingw_34: Gem::Platform::UNIVERSAL_MINGW,
mingw_40: Gem::Platform::UNIVERSAL_MINGW,
+ mingw_41: Gem::Platform::UNIVERSAL_MINGW,
x64_mingw: Gem::Platform::UNIVERSAL_MINGW,
x64_mingw_20: Gem::Platform::UNIVERSAL_MINGW,
x64_mingw_21: Gem::Platform::UNIVERSAL_MINGW,
@@ -129,7 +135,8 @@ RSpec.describe Bundler::CurrentRuby do
x64_mingw_32: Gem::Platform::UNIVERSAL_MINGW,
x64_mingw_33: Gem::Platform::UNIVERSAL_MINGW,
x64_mingw_34: Gem::Platform::UNIVERSAL_MINGW,
- x64_mingw_40: Gem::Platform::UNIVERSAL_MINGW }
+ x64_mingw_40: Gem::Platform::UNIVERSAL_MINGW,
+ x64_mingw_41: Gem::Platform::UNIVERSAL_MINGW }
end
# rubocop:enable Naming/VariableNumber
diff --git a/spec/bundler/commands/add_spec.rb b/spec/bundler/commands/add_spec.rb
index 00aa6415e1..ed98a914f3 100644
--- a/spec/bundler/commands/add_spec.rb
+++ b/spec/bundler/commands/add_spec.rb
@@ -236,6 +236,40 @@ RSpec.describe "bundle add" do
end
end
+ describe "with mismatched pair in --git/--github, --branch/--ref" do
+ describe "with --git and --github" do
+ it "throws error" do
+ bundle "add 'foo' --git x --github y", raise_on_error: false
+
+ expect(err).to include("You cannot specify `--git` and `--github` at the same time.")
+ end
+ end
+
+ describe "with --branch and --ref with --git" do
+ it "throws error" do
+ bundle "add 'foo' --branch x --ref y --git file://git", raise_on_error: false
+
+ expect(err).to include("You cannot specify `--branch` and `--ref` at the same time.")
+ end
+ end
+
+ describe "with --branch but without --git or --github" do
+ it "throws error" do
+ bundle "add 'foo' --branch x", raise_on_error: false
+
+ expect(err).to include("You cannot specify `--branch` unless `--git` or `--github` is specified.")
+ end
+ end
+
+ describe "with --ref but without --git or --github" do
+ it "throws error" do
+ bundle "add 'foo' --ref y", raise_on_error: false
+
+ expect(err).to include("You cannot specify `--ref` unless `--git` or `--github` is specified.")
+ end
+ end
+ end
+
describe "with --skip-install" do
it "adds gem to Gemfile but is not installed" do
bundle "add foo --skip-install --version=2.0"
diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb
index 6b678d0aa5..793aacf5c2 100644
--- a/spec/bundler/commands/clean_spec.rb
+++ b/spec/bundler/commands/clean_spec.rb
@@ -898,4 +898,41 @@ RSpec.describe "bundle clean" do
expect(very_simple_binary_extensions_dir).to be_nil
end
+
+ it "does not remove the bundler version currently running" do
+ gemfile <<-G
+ source "https://gem.repo1"
+
+ gem "myrack"
+ G
+
+ bundle "config set path vendor/bundle"
+ bundle "install"
+
+ version = Bundler.gem_version.to_s
+ # Simulate that the locked bundler version is installed in the bundle path
+ # by creating the gem directory and gemspec (as would happen after bundle install with that version)
+ Pathname(vendored_gems("cache/bundler-#{version}.gem")).tap do |path|
+ path.basename.mkpath
+ FileUtils.touch(path)
+ end
+ FileUtils.touch(vendored_gems("gems/bundler-#{version}"))
+ Pathname(vendored_gems("specifications/bundler-#{version}.gemspec")).tap do |path|
+ path.basename.mkpath
+ path.write(<<~GEMSPEC)
+ Gem::Specification.new do |s|
+ s.name = "bundler"
+ s.version = "#{version}"
+ s.authors = ["bundler team"]
+ s.summary = "The best way to manage your application's dependencies"
+ end
+ GEMSPEC
+ end
+
+ should_have_gems "bundler-#{version}"
+
+ bundle :clean
+
+ should_have_gems "bundler-#{version}"
+ end
end
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index c0b4d98f1c..90f87ed0c5 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -1079,4 +1079,120 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(lockfile).to eq original_lockfile.gsub("bigdecimal (1.0.0)", "bigdecimal (3.3.1)")
end
end
+
+ context "when switching a gem with components from rubygems to git source" do
+ before do
+ build_repo2 do
+ build_gem "rails", "7.0.0" do |s|
+ s.add_dependency "actionpack", "7.0.0"
+ s.add_dependency "activerecord", "7.0.0"
+ end
+ build_gem "actionpack", "7.0.0"
+ build_gem "activerecord", "7.0.0"
+ # propshaft also depends on actionpack, creating the conflict
+ build_gem "propshaft", "1.0.0" do |s|
+ s.add_dependency "actionpack", ">= 7.0.0"
+ end
+ end
+
+ build_git "rails", "7.0.0", path: lib_path("rails") do |s|
+ s.add_dependency "actionpack", "7.0.0"
+ s.add_dependency "activerecord", "7.0.0"
+ end
+
+ build_git "actionpack", "7.0.0", path: lib_path("rails")
+ build_git "activerecord", "7.0.0", path: lib_path("rails")
+
+ install_gemfile <<-G
+ source "https://gem.repo2"
+ gem "rails", "7.0.0"
+ gem "propshaft"
+ G
+ end
+
+ it "moves component gems to the git source in the lockfile" do
+ expect(lockfile).to include("remote: https://gem.repo2")
+ expect(lockfile).to include("rails (7.0.0)")
+ expect(lockfile).to include("actionpack (7.0.0)")
+ expect(lockfile).to include("activerecord (7.0.0)")
+ expect(lockfile).to include("propshaft (1.0.0)")
+
+ gemfile <<-G
+ source "https://gem.repo2"
+ gem "rails", git: "#{lib_path("rails")}"
+ gem "propshaft"
+ G
+
+ bundle "install"
+
+ expect(lockfile).to include("remote: #{lib_path("rails")}")
+ expect(lockfile).to include("rails (7.0.0)")
+ expect(lockfile).to include("actionpack (7.0.0)")
+ expect(lockfile).to include("activerecord (7.0.0)")
+
+ # Component gems should NOT remain in the GEM section
+ # Extract just the GEM section by splitting on GIT first, then GEM
+ gem_section = lockfile.split("GEM\n").last.split(/\n(PLATFORMS|DEPENDENCIES)/)[0]
+ expect(gem_section).not_to include("actionpack (7.0.0)")
+ expect(gem_section).not_to include("activerecord (7.0.0)")
+ end
+ end
+
+ context "when switching a gem with components from rubygems to path source" do
+ before do
+ build_repo2 do
+ build_gem "rails", "7.0.0" do |s|
+ s.add_dependency "actionpack", "7.0.0"
+ s.add_dependency "activerecord", "7.0.0"
+ end
+ build_gem "actionpack", "7.0.0"
+ build_gem "activerecord", "7.0.0"
+ # propshaft also depends on actionpack, creating the conflict
+ build_gem "propshaft", "1.0.0" do |s|
+ s.add_dependency "actionpack", ">= 7.0.0"
+ end
+ end
+
+ build_lib "rails", "7.0.0", path: lib_path("rails") do |s|
+ s.add_dependency "actionpack", "7.0.0"
+ s.add_dependency "activerecord", "7.0.0"
+ end
+
+ build_lib "actionpack", "7.0.0", path: lib_path("rails")
+ build_lib "activerecord", "7.0.0", path: lib_path("rails")
+
+ install_gemfile <<-G
+ source "https://gem.repo2"
+ gem "rails", "7.0.0"
+ gem "propshaft"
+ G
+ end
+
+ it "moves component gems to the path source in the lockfile" do
+ expect(lockfile).to include("remote: https://gem.repo2")
+ expect(lockfile).to include("rails (7.0.0)")
+ expect(lockfile).to include("actionpack (7.0.0)")
+ expect(lockfile).to include("activerecord (7.0.0)")
+ expect(lockfile).to include("propshaft (1.0.0)")
+
+ gemfile <<-G
+ source "https://gem.repo2"
+ gem "rails", path: "#{lib_path("rails")}"
+ gem "propshaft"
+ G
+
+ bundle "install"
+
+ expect(lockfile).to include("remote: #{lib_path("rails")}")
+ expect(lockfile).to include("rails (7.0.0)")
+ expect(lockfile).to include("actionpack (7.0.0)")
+ expect(lockfile).to include("activerecord (7.0.0)")
+
+ # Component gems should NOT remain in the GEM section
+ # Extract just the GEM section by splitting appropriately
+ gem_section = lockfile.split("GEM\n").last.split(/\n(PLATFORMS|DEPENDENCIES)/)[0]
+ expect(gem_section).not_to include("actionpack (7.0.0)")
+ expect(gem_section).not_to include("activerecord (7.0.0)")
+ end
+ end
end
diff --git a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock
index 2db720a69f..1d4eae8ffe 100644
--- a/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock
+++ b/spec/bundler/realworld/fixtures/tapioca/Gemfile.lock
@@ -46,4 +46,4 @@ DEPENDENCIES
tapioca
BUNDLED WITH
- 4.0.3
+ 4.0.4
diff --git a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
index c37fbbb7ee..6eb02db3db 100644
--- a/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
+++ b/spec/bundler/realworld/fixtures/warbler/Gemfile.lock
@@ -36,4 +36,4 @@ DEPENDENCIES
warbler!
BUNDLED WITH
- 4.0.3
+ 4.0.4
diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock
index fff9cfe70c..01317be72d 100644
--- a/tool/bundler/dev_gems.rb.lock
+++ b/tool/bundler/dev_gems.rb.lock
@@ -129,4 +129,4 @@ CHECKSUMS
turbo_tests (2.2.5) sha256=3fa31497d12976d11ccc298add29107b92bda94a90d8a0a5783f06f05102509f
BUNDLED WITH
- 4.0.3
+ 4.0.4
diff --git a/tool/bundler/rubocop_gems.rb.lock b/tool/bundler/rubocop_gems.rb.lock
index 70704bfc38..a6d9fb125a 100644
--- a/tool/bundler/rubocop_gems.rb.lock
+++ b/tool/bundler/rubocop_gems.rb.lock
@@ -156,4 +156,4 @@ CHECKSUMS
unicode-emoji (4.1.0) sha256=4997d2d5df1ed4252f4830a9b6e86f932e2013fbff2182a9ce9ccabda4f325a5
BUNDLED WITH
- 4.0.3
+ 4.0.4
diff --git a/tool/bundler/standard_gems.rb.lock b/tool/bundler/standard_gems.rb.lock
index 669e5492a8..c4e2f1e784 100644
--- a/tool/bundler/standard_gems.rb.lock
+++ b/tool/bundler/standard_gems.rb.lock
@@ -176,4 +176,4 @@ CHECKSUMS
unicode-emoji (4.1.0) sha256=4997d2d5df1ed4252f4830a9b6e86f932e2013fbff2182a9ce9ccabda4f325a5
BUNDLED WITH
- 4.0.3
+ 4.0.4
diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock
index d8f7d77122..46c12cfb60 100644
--- a/tool/bundler/test_gems.rb.lock
+++ b/tool/bundler/test_gems.rb.lock
@@ -103,4 +103,4 @@ CHECKSUMS
tilt (2.6.1) sha256=35a99bba2adf7c1e362f5b48f9b581cce4edfba98117e34696dde6d308d84770
BUNDLED WITH
- 4.0.3
+ 4.0.4