diff --git a/.github/workflows/bundler.yml b/.github/workflows/bundler.yml index 7ea6be4aec21..223316c9d47e 100644 --- a/.github/workflows/bundler.yml +++ b/.github/workflows/bundler.yml @@ -30,23 +30,29 @@ jobs: ruby: - { name: ruby-3.2, value: 3.2.9 } - - { name: ruby-3.3, value: 3.3.9 } - - { name: ruby-3.4, value: 3.4.5 } + - { name: ruby-3.3, value: 3.3.10 } + - { name: ruby-3.4, value: 3.4.8 } + - { name: ruby-4.0, value: 4.0.0 } include: - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.2, value: 3.2.9 }, timeout: 90 } - - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.3, value: 3.3.9 }, timeout: 90 } - - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.4, value: 3.4.5 }, timeout: 90 } + - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.3, value: 3.3.10 }, timeout: 90 } + - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.4, value: 3.4.8 }, timeout: 90 } + - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-4.0, value: 4.0.0 }, timeout: 90 } # Ruby 3.2 is about 20 minutes slower than 3.3/3.4, so it will be excluded from testing. - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.9 }, timeout: 150, group: a } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.9 }, timeout: 150, group: b } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.9 }, timeout: 150, group: c } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.9 }, timeout: 150, group: d } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.5 }, timeout: 150, group: a } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.5 }, timeout: 150, group: b } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.5 }, timeout: 150, group: c } - - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.5 }, timeout: 150, group: d } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.10 }, timeout: 150, group: a } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.10 }, timeout: 150, group: b } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.10 }, timeout: 150, group: c } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.3, value: 3.3.10 }, timeout: 150, group: d } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.8 }, timeout: 150, group: a } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.8 }, timeout: 150, group: b } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.8 }, timeout: 150, group: c } + - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-3.4, value: 3.4.8 }, timeout: 150, group: d } + # - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-4.0, value: 4.0.0 }, timeout: 150, group: a } + # - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-4.0, value: 4.0.0 }, timeout: 150, group: b } + # - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-4.0, value: 4.0.0 }, timeout: 150, group: c } + # - { os: { name: Windows, value: windows-2025 }, ruby: { name: ruby-4.0, value: 4.0.0 }, timeout: 150, group: d } - { os: { name: Ubuntu, value: ubuntu-24.04 }, ruby: { name: jruby, value: jruby-10.0.2.0 } } - { os: { name: Windows, value: windows-2025 }, ruby: { name: jruby, value: jruby-10.0.2.0 } } @@ -59,7 +65,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none diff --git a/.github/workflows/daily-bundler.yml b/.github/workflows/daily-bundler.yml index 14f78a83c661..a45e980f666d 100644 --- a/.github/workflows/daily-bundler.yml +++ b/.github/workflows/daily-bundler.yml @@ -25,7 +25,7 @@ jobs: persist-credentials: false - name: Set up Ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ruby-head bundler: none diff --git a/.github/workflows/daily-rubygems.yml b/.github/workflows/daily-rubygems.yml index e7512f869f03..cbc16ec76665 100644 --- a/.github/workflows/daily-rubygems.yml +++ b/.github/workflows/daily-rubygems.yml @@ -28,7 +28,7 @@ jobs: persist-credentials: false - name: Set up Ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby }} bundler: none diff --git a/.github/workflows/install-rubygems.yml b/.github/workflows/install-rubygems.yml index fee2d0f0d247..d5a46f230deb 100644 --- a/.github/workflows/install-rubygems.yml +++ b/.github/workflows/install-rubygems.yml @@ -35,7 +35,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none @@ -128,7 +128,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none @@ -170,7 +170,7 @@ jobs: with: persist-credentials: false - name: Setup original ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: 3.2 bundler: none @@ -191,7 +191,7 @@ jobs: GEM_HOME: bar GEM_PATH: bar - name: Setup final ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: 3.3 bundler: none @@ -220,7 +220,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none diff --git a/.github/workflows/realworld-bundler.yml b/.github/workflows/realworld-bundler.yml index 7447bf59c3c6..39627df46a58 100644 --- a/.github/workflows/realworld-bundler.yml +++ b/.github/workflows/realworld-bundler.yml @@ -26,13 +26,15 @@ jobs: ruby: - { name: ruby-3.2, value: 3.2.9 } - - { name: ruby-3.3, value: 3.3.9 } - - { name: ruby-3.4, value: 3.4.5 } + - { name: ruby-3.3, value: 3.3.10 } + - { name: ruby-3.4, value: 3.4.8 } + - { name: ruby-4.0, value: 4.0.0 } include: - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.2, value: 3.2.9 } } - - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.3, value: 3.3.9 } } - - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.4, value: 3.4.5 } } + - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.3, value: 3.3.10 } } + - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-3.4, value: 3.4.8 } } + - { os: { name: macOS, value: macos-15 }, ruby: { name: ruby-4.0, value: 4.0.0 } } env: RGV: .. RUBYOPT: --disable-gems @@ -41,7 +43,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none @@ -64,9 +66,9 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: - ruby-version: 3.4.5 + ruby-version: 3.4.8 bundler: none - name: Prepare tapioca run: ../../../../bin/bundle install @@ -91,7 +93,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none @@ -115,9 +117,9 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: - ruby-version: 3.4.5 + ruby-version: 3.4.8 bundler: none - name: Prepare dependencies run: bin/rake setup diff --git a/.github/workflows/rubygems.yml b/.github/workflows/rubygems.yml index 90a920bc3cb8..f37377877d3e 100644 --- a/.github/workflows/rubygems.yml +++ b/.github/workflows/rubygems.yml @@ -28,8 +28,9 @@ jobs: ruby: - { name: "3.2", value: 3.2.9 } - - { name: "3.3", value: 3.3.9 } - - { name: "3.4", value: 3.4.5 } + - { name: "3.3", value: 3.3.10 } + - { name: "3.4", value: 3.4.8 } + - { name: "4.0", value: 4.0.0 } include: - ruby: { name: jruby, value: jruby-10.0.2.0 } @@ -43,7 +44,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none diff --git a/.github/workflows/system-rubygems-bundler.yml b/.github/workflows/system-rubygems-bundler.yml index 50b717431324..a6c7f77e8a1e 100644 --- a/.github/workflows/system-rubygems-bundler.yml +++ b/.github/workflows/system-rubygems-bundler.yml @@ -37,7 +37,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none diff --git a/.github/workflows/truffleruby-bundler.yml b/.github/workflows/truffleruby-bundler.yml index c7715071150d..3f7bb03c96da 100644 --- a/.github/workflows/truffleruby-bundler.yml +++ b/.github/workflows/truffleruby-bundler.yml @@ -28,7 +28,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: truffleruby-24.2.1 bundler: none diff --git a/.github/workflows/ubuntu-lint.yml b/.github/workflows/ubuntu-lint.yml index 0dda6a140eeb..01bf7721ec13 100644 --- a/.github/workflows/ubuntu-lint.yml +++ b/.github/workflows/ubuntu-lint.yml @@ -75,7 +75,7 @@ jobs: with: persist-credentials: false - name: Setup ruby - uses: ruby/setup-ruby@8aeb6ff8030dd539317f8e1769a044873b56ea71 # v1.268.0 + uses: ruby/setup-ruby@b90be12699fdfcbee4440c2bba85f6f460446bb0 # v1.279.0 with: ruby-version: ${{ matrix.ruby.value }} bundler: none diff --git a/CHANGELOG.md b/CHANGELOG.md index 2357165cef8d..b620d2ecde44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 4.0.4 / 2026-01-15 + +### Enhancements: + +* Remove date require from rebuild command. Pull request + [#9232](https://github.com/ruby/rubygems/pull/9232) by jeremyevans +* Installs bundler 4.0.4 as a default gem. + +### Bug fixes: + +* Add a missing "require 'etc'" statement:. Pull request + [#9242](https://github.com/ruby/rubygems/pull/9242) by Edouard-chin + ## 4.0.3 / 2025-12-23 ### Enhancements: diff --git a/bundler/CHANGELOG.md b/bundler/CHANGELOG.md index df09a5ba07ca..fee83430ea53 100644 --- a/bundler/CHANGELOG.md +++ b/bundler/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 4.0.4 (2026-01-15) + +### Enhancements: + + - Validate more options for add sub-command [#5905](https://github.com/ruby/rubygems/pull/5905) + - Support Ruby 4.1 [#9219](https://github.com/ruby/rubygems/pull/9219) + +### Bug fixes: + + - Fix dependency source bug in bundler [#9213](https://github.com/ruby/rubygems/pull/9213) + - Retain current bundler version on `bundle clean` [#9221](https://github.com/ruby/rubygems/pull/9221) + ## 4.0.3 (2025-12-23) ### Enhancements: diff --git a/bundler/lib/bundler/cli/add.rb b/bundler/lib/bundler/cli/add.rb index 12a681a81688..9f1760409617 100644 --- a/bundler/lib/bundler/cli/add.rb +++ b/bundler/lib/bundler/cli/add.rb @@ -36,6 +36,16 @@ def inject_dependencies 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/bundler/lib/bundler/current_ruby.rb b/bundler/lib/bundler/current_ruby.rb index ab6520a106a4..17c7655adb58 100644 --- a/bundler/lib/bundler/current_ruby.rb +++ b/bundler/lib/bundler/current_ruby.rb @@ -11,7 +11,7 @@ def self.current_ruby 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/bundler/lib/bundler/definition.rb b/bundler/lib/bundler/definition.rb index 2fa7d0d27794..5ab577f504c3 100644 --- a/bundler/lib/bundler/definition.rb +++ b/bundler/lib/bundler/definition.rb @@ -1066,7 +1066,22 @@ def converge_specs(specs) 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/bundler/lib/bundler/rubygems_integration.rb b/bundler/lib/bundler/rubygems_integration.rb index d8f95cffb8fc..e04ef232592a 100644 --- a/bundler/lib/bundler/rubygems_integration.rb +++ b/bundler/lib/bundler/rubygems_integration.rb @@ -432,7 +432,7 @@ def default_specs 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/bundler/lib/bundler/runtime.rb b/bundler/lib/bundler/runtime.rb index 5eb827dcb2a8..5280e72aa24b 100644 --- a/bundler/lib/bundler/runtime.rb +++ b/bundler/lib/bundler/runtime.rb @@ -174,7 +174,14 @@ def clean(dry_run = false) 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/bundler/lib/bundler/version.rb b/bundler/lib/bundler/version.rb index 732b4a05631e..8c039d16a06c 100644 --- a/bundler/lib/bundler/version.rb +++ b/bundler/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/bundler/spec/bundler/current_ruby_spec.rb b/bundler/spec/bundler/current_ruby_spec.rb index aa19a4140765..79eb802aa522 100644 --- a/bundler/spec/bundler/current_ruby_spec.rb +++ b/bundler/spec/bundler/current_ruby_spec.rb @@ -23,6 +23,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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/bundler/spec/commands/add_spec.rb b/bundler/spec/commands/add_spec.rb index 00aa6415e11c..ed98a914f326 100644 --- a/bundler/spec/commands/add_spec.rb +++ b/bundler/spec/commands/add_spec.rb @@ -236,6 +236,40 @@ 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/bundler/spec/commands/clean_spec.rb b/bundler/spec/commands/clean_spec.rb index 6b678d0aa545..793aacf5c2b5 100644 --- a/bundler/spec/commands/clean_spec.rb +++ b/bundler/spec/commands/clean_spec.rb @@ -898,4 +898,41 @@ def should_not_have_gems(*gems) 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/bundler/spec/install/gemfile/sources_spec.rb b/bundler/spec/install/gemfile/sources_spec.rb index c0b4d98f1c5c..90f87ed0c5da 100644 --- a/bundler/spec/install/gemfile/sources_spec.rb +++ b/bundler/spec/install/gemfile/sources_spec.rb @@ -1079,4 +1079,120 @@ 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/bundler/spec/realworld/fixtures/tapioca/Gemfile.lock b/bundler/spec/realworld/fixtures/tapioca/Gemfile.lock index 2db720a69f46..1d4eae8ffe0b 100644 --- a/bundler/spec/realworld/fixtures/tapioca/Gemfile.lock +++ b/bundler/spec/realworld/fixtures/tapioca/Gemfile.lock @@ -46,4 +46,4 @@ DEPENDENCIES tapioca BUNDLED WITH - 4.0.3 + 4.0.4 diff --git a/bundler/spec/realworld/fixtures/warbler/Gemfile.lock b/bundler/spec/realworld/fixtures/warbler/Gemfile.lock index c37fbbb7eed5..6eb02db3db73 100644 --- a/bundler/spec/realworld/fixtures/warbler/Gemfile.lock +++ b/bundler/spec/realworld/fixtures/warbler/Gemfile.lock @@ -36,4 +36,4 @@ DEPENDENCIES warbler! BUNDLED WITH - 4.0.3 + 4.0.4 diff --git a/lib/rubygems.rb b/lib/rubygems.rb index e99176fec0e1..9e90e608a50d 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 77a474ef1ddf..23b9d7b3ba92 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 90aa25dc0728..914e41367731 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -943,7 +943,12 @@ def build_args 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/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 72ca9d826258..d2ca933a632c 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -1610,7 +1610,7 @@ def test_pass_down_the_job_option_to_make gem_make_out = File.read(File.join(gemspec.extension_dir, "gem_make.out")) if vc_windows? && nmake_found? - refute_includes(gem_make_out, "-j4") + refute_includes(gem_make_out, " -j4") else assert_includes(gem_make_out, "make -j4") end diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index 3bb4a72c4151..5ed12ad48140 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -722,7 +722,7 @@ def test_pass_down_the_job_option_to_make gem_make_out = File.read(File.join(gemspec.extension_dir, "gem_make.out")) if vc_windows? && nmake_found? - refute_includes(gem_make_out, "-j2") + refute_includes(gem_make_out, " -j2") else assert_includes(gem_make_out, "make -j2") end diff --git a/tool/bundler/dev_gems.rb.lock b/tool/bundler/dev_gems.rb.lock index fff9cfe70cb1..01317be72d11 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/lint_gems.rb.lock b/tool/bundler/lint_gems.rb.lock index 9d4823728151..7607c762d29d 100644 --- a/tool/bundler/lint_gems.rb.lock +++ b/tool/bundler/lint_gems.rb.lock @@ -119,4 +119,4 @@ CHECKSUMS wmi-lite (1.0.7) sha256=116ef5bb470dbe60f58c2db9047af3064c16245d6562c646bc0d90877e27ddda BUNDLED WITH - 4.0.3 + 4.0.4 diff --git a/tool/bundler/release_gems.rb.lock b/tool/bundler/release_gems.rb.lock index 86a0df95c279..130079b4a621 100644 --- a/tool/bundler/release_gems.rb.lock +++ b/tool/bundler/release_gems.rb.lock @@ -87,4 +87,4 @@ CHECKSUMS uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 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 70704bfc3889..a6d9fb125a5e 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 669e5492a8a0..c4e2f1e78485 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 d8f7d7712284..46c12cfb6022 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 diff --git a/tool/bundler/vendor_gems.rb.lock b/tool/bundler/vendor_gems.rb.lock index 19269bb5afab..8aef85935918 100644 --- a/tool/bundler/vendor_gems.rb.lock +++ b/tool/bundler/vendor_gems.rb.lock @@ -72,4 +72,4 @@ CHECKSUMS uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 BUNDLED WITH - 4.0.3 + 4.0.4