bundler 4.0.6 → 4.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a70d61a2817508c06f7a5fd2af83e48fe8499fe7c18e32d59ec791e0f75a10a
4
- data.tar.gz: d9b5194cd5c5c865041445a99db420ebcc7803dde6934490b09a8dc34b19e473
3
+ metadata.gz: 5a885222998dfbe801692cb3fde27432339068b6273f33d0104e25509d18682d
4
+ data.tar.gz: 5ec66951013a0e8b87db477eae402b15b3f37f768d846515f1b6101e0e47b388
5
5
  SHA512:
6
- metadata.gz: 320f7f67ebb313f5b6cfa388e3f04a7fcbb8fb50f5854f33d453478c7b741c48966ac2435690c4ab324e2c4cc445a0c3453e272d35097b6c225f3d514971d175
7
- data.tar.gz: 1c7275717e3389f3de5a346dcdb6a71fb9e526529162e76479493e31613a970a87a6a47b9d745a3fa4fe34fd08bb013c31acd1d12f35714d4949c42add015236
6
+ metadata.gz: 20bdb8aab69b64c68f6bed37bbf1912113ab452b0fd4f6ffe1bb4455556c28df301287dea1cc0faeb45efbf37426300eada625efb34d57b4ab9929d3c05ffade
7
+ data.tar.gz: 9a4019d82dd530eac1ac0c6724cad21f6136a78df3ec0a03c63251764ef9190a056a851675550ce3bd4f9965f6040ae9125517ca1038cdbe04a7b97c0c853053
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.7 (2026-02-25)
4
+
5
+ ### Enhancements:
6
+
7
+ - Don't check whether a plugin needs to be installed: [#9328](https://github.com/ruby/rubygems/pull/9328)
8
+ - [rust gem] Major improvements for gem scaffolding (rebased) [#8455](https://github.com/ruby/rubygems/pull/8455)
9
+ - Fix(bundler): only preload git sources for requested groups [#9234](https://github.com/ruby/rubygems/pull/9234)
10
+ - Raise error when gem contains capital letters [#5432](https://github.com/ruby/rubygems/pull/5432)
11
+
12
+ ### Bug fixes:
13
+
14
+ - Fix Bundler crashing when it tries to install plugin: [#9335](https://github.com/ruby/rubygems/pull/9335)
15
+ - Run git operations in parallel (take 2): [#9323](https://github.com/ruby/rubygems/pull/9323)
16
+ - Add support for help flag in plugin commands [#9263](https://github.com/ruby/rubygems/pull/9263)
17
+
18
+ ### Documentation:
19
+
20
+ - [DOC] Fix link in Bundler [#9315](https://github.com/ruby/rubygems/pull/9315)
21
+
3
22
  ## 4.0.6 (2026-02-05)
4
23
 
5
24
  ### Bug fixes:
@@ -4,8 +4,8 @@ module Bundler
4
4
  # Represents metadata from when the Bundler gem was built.
5
5
  module BuildMetadata
6
6
  # begin ivars
7
- @built_at = "2026-02-05".freeze
8
- @git_commit_sha = "0947d9cf5b".freeze
7
+ @built_at = "2026-02-25".freeze
8
+ @git_commit_sha = "049c458564".freeze
9
9
  # end ivars
10
10
 
11
11
  # A hash representation of the build metadata.
@@ -158,6 +158,9 @@ module Bundler
158
158
  case config[:ci]
159
159
  when "github"
160
160
  templates.merge!("github/workflows/main.yml.tt" => ".github/workflows/main.yml")
161
+ if extension == "rust"
162
+ templates.merge!("github/workflows/build-gems.yml.tt" => ".github/workflows/build-gems.yml")
163
+ end
161
164
  config[:ignore_paths] << ".github/"
162
165
  when "gitlab"
163
166
  templates.merge!("gitlab-ci.yml.tt" => ".gitlab-ci.yml")
@@ -228,6 +231,7 @@ module Bundler
228
231
  templates.merge!(
229
232
  "Cargo.toml.tt" => "Cargo.toml",
230
233
  "ext/newgem/Cargo.toml.tt" => "ext/#{name}/Cargo.toml",
234
+ "ext/newgem/build.rs.tt" => "ext/#{name}/build.rs",
231
235
  "ext/newgem/extconf-rust.rb.tt" => "ext/#{name}/extconf.rb",
232
236
  "ext/newgem/src/lib.rs.tt" => "ext/#{name}/src/lib.rs",
233
237
  )
@@ -435,6 +439,10 @@ module Bundler
435
439
  exit 1
436
440
  end
437
441
 
442
+ if /[A-Z]/.match?(name)
443
+ Bundler.ui.warn "Gem names with capital letters are not recommended. Please use only lowercase letters, numbers, and hyphens."
444
+ end
445
+
438
446
  constant_name = constant_array.join("::")
439
447
 
440
448
  existing_constant = constant_array.inject(Object) do |c, s|
data/lib/bundler/cli.rb CHANGED
@@ -155,6 +155,10 @@ module Bundler
155
155
  def help(cli = nil)
156
156
  cli = self.class.all_aliases[cli] if self.class.all_aliases[cli]
157
157
 
158
+ if Bundler.settings[:plugins] && Bundler::Plugin.command?(cli) && !self.class.all_commands.key?(cli)
159
+ return Bundler::Plugin.exec_command(cli, ["--help"])
160
+ end
161
+
158
162
  case cli
159
163
  when "gemfile" then command = "gemfile"
160
164
  when nil then command = "bundle"
@@ -249,6 +249,7 @@ module Bundler
249
249
  end
250
250
 
251
251
  def missing_specs
252
+ preload_git_sources
252
253
  resolve.missing_specs_for(requested_dependencies)
253
254
  end
254
255
 
@@ -1125,26 +1126,43 @@ module Bundler
1125
1126
  end
1126
1127
 
1127
1128
  def preload_git_sources
1128
- sources.git_sources.each {|source| preload_git_source_worker.enq(source) }
1129
- ensure
1130
- preload_git_source_worker.stop
1131
- end
1132
-
1133
- def find_source_requirements
1134
- if Gem.ruby_version >= Gem::Version.new("3.3")
1129
+ if Gem.ruby_version < Gem::Version.new("3.3")
1135
1130
  # Ruby 3.2 has a bug that incorrectly triggers a circular dependency warning. This version will continue to
1136
1131
  # fetch git repositories one by one.
1137
- preload_git_sources
1132
+ return
1138
1133
  end
1139
1134
 
1135
+ begin
1136
+ needed_git_sources.each {|source| preload_git_source_worker.enq(source) }
1137
+ ensure
1138
+ preload_git_source_worker.stop
1139
+ end
1140
+ end
1141
+
1142
+ # Git sources needed for the requested groups (excludes sources only used by --without groups)
1143
+ def needed_git_sources
1144
+ needed_deps = dependencies_for(requested_groups)
1145
+ sources.git_sources.select do |source|
1146
+ needed_deps.any? {|d| d.source == source }
1147
+ end
1148
+ end
1149
+
1150
+ # Git sources that should be excluded (only used by --without groups)
1151
+ def excluded_git_sources
1152
+ sources.git_sources - needed_git_sources
1153
+ end
1154
+
1155
+ def find_source_requirements
1156
+ preload_git_sources
1157
+
1140
1158
  # Record the specs available in each gem's source, so that those
1141
1159
  # specs will be available later when the resolver knows where to
1142
1160
  # look for that gemspec (or its dependencies)
1143
1161
  source_requirements = if precompute_source_requirements_for_indirect_dependencies?
1144
- all_requirements = source_map.all_requirements
1162
+ all_requirements = source_map.all_requirements(excluded_git_sources)
1145
1163
  { default: default_source }.merge(all_requirements)
1146
1164
  else
1147
- { default: Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
1165
+ { default: Source::RubygemsAggregate.new(sources, source_map, excluded_git_sources) }.merge(source_map.direct_requirements)
1148
1166
  end
1149
1167
  source_requirements.merge!(source_map.locked_requirements) if nothing_changed?
1150
1168
  metadata_dependencies.each do |dep|
@@ -253,10 +253,13 @@ module Bundler
253
253
  # @param [Array<String>] names of inferred source plugins that can be ignored
254
254
  def save_plugins(plugins, specs, optional_plugins = [])
255
255
  plugins.each do |name|
256
- next if index.installed?(name)
257
-
258
256
  spec = specs[name]
259
257
 
258
+ # It's possible that the `plugin` found in the Gemfile don't appear in the specs. For instance when
259
+ # calling `BUNDLE_WITHOUT=default bundle install`, the plugins will not get installed.
260
+ next if spec.nil?
261
+ next if index.installed?(name)
262
+
260
263
  save_plugin(name, spec, optional_plugins.include?(name))
261
264
  end
262
265
  end
@@ -71,9 +71,6 @@ module Bundler
71
71
  def generate_plugins
72
72
  return unless Gem::Installer.method_defined?(:generate_plugins, false)
73
73
 
74
- latest = Gem::Specification.stubs_for(spec.name).first
75
- return if latest && latest.version > spec.version
76
-
77
74
  ensure_writable_dir @plugins_dir
78
75
 
79
76
  if spec.plugins.empty?
@@ -5,9 +5,10 @@ module Bundler
5
5
  class RubygemsAggregate
6
6
  attr_reader :source_map, :sources
7
7
 
8
- def initialize(sources, source_map)
8
+ def initialize(sources, source_map, excluded_sources = [])
9
9
  @sources = sources
10
10
  @source_map = source_map
11
+ @excluded_sources = excluded_sources
11
12
 
12
13
  @index = build_index
13
14
  end
@@ -31,6 +32,8 @@ module Bundler
31
32
  dependency_names = source_map.pinned_spec_names
32
33
 
33
34
  sources.all_sources.each do |source|
35
+ next if @excluded_sources.include?(source)
36
+
34
37
  source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
35
38
  idx.add_source source.specs
36
39
  dependency_names.concat(source.unmet_deps).uniq!
@@ -14,10 +14,14 @@ module Bundler
14
14
  direct_requirements.reject {|_, source| source == skip }.keys
15
15
  end
16
16
 
17
- def all_requirements
17
+ def all_requirements(excluded_sources = [])
18
18
  requirements = direct_requirements.dup
19
19
 
20
- unmet_deps = sources.non_default_explicit_sources.map do |source|
20
+ explicit_sources = sources.non_default_explicit_sources.reject do |source|
21
+ excluded_sources.include?(source)
22
+ end
23
+
24
+ unmet_deps = explicit_sources.map do |source|
21
25
  (source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
22
26
  previous_source = requirements[indirect_dependency_name]
23
27
  if previous_source.nil?
@@ -5,3 +5,9 @@
5
5
  [workspace]
6
6
  members = ["./ext/<%= config[:name] %>"]
7
7
  resolver = "2"
8
+
9
+ [profile.release]
10
+ # By default, debug symbols are stripped from the final binary which makes it
11
+ # harder to debug if something goes wrong. It's recommended to keep debug
12
+ # symbols in the release build so that you can debug the final binary if needed.
13
+ debug = true
@@ -13,3 +13,10 @@ crate-type = ["cdylib"]
13
13
 
14
14
  [dependencies]
15
15
  magnus = { version = "0.8.2" }
16
+ rb-sys = { version = "0.9", features = ["stable-api-compiled-fallback"] }
17
+
18
+ [build-dependencies]
19
+ rb-sys-env = "0.2.2"
20
+
21
+ [dev-dependencies]
22
+ rb-sys-test-helpers = { version = "0.2.2" }
@@ -0,0 +1,5 @@
1
+ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
2
+ let _ = rb_sys_env::activate()?;
3
+
4
+ Ok(())
5
+ }
@@ -1,7 +1,7 @@
1
1
  use magnus::{function, prelude::*, Error, Ruby};
2
2
 
3
- fn hello(subject: String) -> String {
4
- format!("Hello from Rust, {subject}!")
3
+ pub fn hello(subject: String) -> String {
4
+ format!("Hello {subject}, from Rust!")
5
5
  }
6
6
 
7
7
  #[magnus::init]
@@ -10,3 +10,14 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
10
10
  module.define_singleton_method("hello", function!(hello, 1))?;
11
11
  Ok(())
12
12
  }
13
+
14
+ #[cfg(test)]
15
+ mod tests {
16
+ use rb_sys_test_helpers::ruby_test;
17
+ use super::hello;
18
+
19
+ #[ruby_test]
20
+ fn test_hello() {
21
+ assert_eq!("Hello world, from Rust!", hello("world".to_string()));
22
+ }
23
+ }
@@ -0,0 +1,65 @@
1
+ ---
2
+ name: Build gems
3
+
4
+ on:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+ - "cross-gem/*"
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ ci-data:
13
+ runs-on: ubuntu-latest
14
+ outputs:
15
+ result: ${{ steps.fetch.outputs.result }}
16
+ steps:
17
+ - uses: oxidize-rb/actions/fetch-ci-data@v1
18
+ id: fetch
19
+ with:
20
+ supported-ruby-platforms: |
21
+ exclude: ["arm-linux", "x64-mingw32"]
22
+ stable-ruby-versions: |
23
+ exclude: ["head"]
24
+
25
+ source-gem:
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+
30
+ - uses: ruby/setup-ruby@v1
31
+ with:
32
+ bundler-cache: true
33
+
34
+ - name: Build gem
35
+ run: bundle exec rake build
36
+
37
+ - uses: actions/upload-artifact@v3
38
+ with:
39
+ name: source-gem
40
+ path: pkg/*.gem
41
+
42
+ cross-gem:
43
+ name: Compile native gem for ${{ matrix.platform }}
44
+ runs-on: ubuntu-latest
45
+ needs: ci-data
46
+ strategy:
47
+ matrix:
48
+ platform: ${{ fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms }}
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - uses: ruby/setup-ruby@v1
53
+ with:
54
+ bundler-cache: true
55
+
56
+ - uses: oxidize-rb/actions/cross-gem@v1
57
+ id: cross-gem
58
+ with:
59
+ platform: ${{ matrix.platform }}
60
+ ruby-versions: ${{ join(fromJSON(needs.ci-data.outputs.result).stable-ruby-versions, ',') }}
61
+
62
+ - uses: actions/upload-artifact@v3
63
+ with:
64
+ name: cross-gem
65
+ path: ${{ steps.cross-gem.outputs.gem-path }}
@@ -15,10 +15,6 @@ Gem::Specification.new do |spec|
15
15
  spec.license = "MIT"
16
16
  <%- end -%>
17
17
  spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>"
18
- <%- if config[:ext] == 'rust' -%>
19
- spec.required_rubygems_version = ">= <%= config[:rust_builder_required_rubygems_version] %>"
20
- <%- end -%>
21
-
22
18
  spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
23
19
  spec.metadata["homepage_uri"] = spec.homepage
24
20
  spec.metadata["source_code_uri"] = "<%= config[:source_code_uri] %>"
@@ -44,9 +40,6 @@ Gem::Specification.new do |spec|
44
40
 
45
41
  # Uncomment to register a new dependency of your gem
46
42
  # spec.add_dependency "example-gem", "~> 1.0"
47
- <%- if config[:ext] == 'rust' -%>
48
- spec.add_dependency "rb_sys", "~> 0.9.91"
49
- <%- end -%>
50
43
  <%- if config[:ext] == 'go' -%>
51
44
  spec.add_dependency "go_gem", "~> 0.2"
52
45
  <%- end -%>
@@ -5,7 +5,15 @@ RSpec.describe <%= config[:constant_name] %> do
5
5
  expect(<%= config[:constant_name] %>::VERSION).not_to be nil
6
6
  end
7
7
 
8
+ <%- if config[:ext] == 'rust' -%>
9
+ it "can call into Rust" do
10
+ result = <%= config[:constant_name] %>.hello("world")
11
+
12
+ expect(result).to be("Hello earth, from Rust!")
13
+ end
14
+ <%- else -%>
8
15
  it "does something useful" do
9
16
  expect(false).to eq(true)
10
17
  end
18
+ <%- end -%>
11
19
  end
@@ -7,7 +7,13 @@ class <%= config[:minitest_constant_name] %> < Minitest::Test
7
7
  refute_nil ::<%= config[:constant_name] %>::VERSION
8
8
  end
9
9
 
10
+ <%- if config[:ext] == 'rust' -%>
11
+ def test_hello_world
12
+ assert_equal "Hello earth, from Rust!", <%= config[:constant_name] %>.hello("world")
13
+ end
14
+ <%- else -%>
10
15
  def test_it_does_something_useful
11
16
  assert false
12
17
  end
18
+ <%- end -%>
13
19
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "4.0.6".freeze
4
+ VERSION = "4.0.7".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= gem_version.segments.first
data/lib/bundler.rb CHANGED
@@ -172,7 +172,7 @@ module Bundler
172
172
  self_manager.restart_with_locked_bundler_if_needed
173
173
  end
174
174
 
175
- # Automatically install dependencies if settings[:auto_install] exists.
175
+ # Automatically install dependencies if <tt>settings[:auto_install]</tt> exists.
176
176
  # This is set through config cmd `bundle config set --global auto_install 1`.
177
177
  #
178
178
  # Note that this method `nil`s out the global Definition object, so it
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bundler
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.6
4
+ version: 4.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -247,6 +247,7 @@ files:
247
247
  - lib/bundler/templates/newgem/circleci/config.yml.tt
248
248
  - lib/bundler/templates/newgem/exe/newgem.tt
249
249
  - lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt
250
+ - lib/bundler/templates/newgem/ext/newgem/build.rs.tt
250
251
  - lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt
251
252
  - lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt
252
253
  - lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt
@@ -256,6 +257,7 @@ files:
256
257
  - lib/bundler/templates/newgem/ext/newgem/newgem.go.tt
257
258
  - lib/bundler/templates/newgem/ext/newgem/newgem.h.tt
258
259
  - lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt
260
+ - lib/bundler/templates/newgem/github/workflows/build-gems.yml.tt
259
261
  - lib/bundler/templates/newgem/github/workflows/main.yml.tt
260
262
  - lib/bundler/templates/newgem/gitignore.tt
261
263
  - lib/bundler/templates/newgem/gitlab-ci.yml.tt