bundler 4.0.5 → 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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/lib/bundler/build_metadata.rb +2 -2
  4. data/lib/bundler/cli/gem.rb +8 -0
  5. data/lib/bundler/cli.rb +4 -0
  6. data/lib/bundler/definition.rb +29 -11
  7. data/lib/bundler/fetcher/downloader.rb +0 -1
  8. data/lib/bundler/man/bundle-add.1 +1 -1
  9. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  10. data/lib/bundler/man/bundle-cache.1 +1 -1
  11. data/lib/bundler/man/bundle-check.1 +1 -1
  12. data/lib/bundler/man/bundle-clean.1 +1 -1
  13. data/lib/bundler/man/bundle-config.1 +18 -2
  14. data/lib/bundler/man/bundle-config.1.ronn +15 -1
  15. data/lib/bundler/man/bundle-console.1 +1 -1
  16. data/lib/bundler/man/bundle-doctor.1 +1 -1
  17. data/lib/bundler/man/bundle-env.1 +1 -1
  18. data/lib/bundler/man/bundle-exec.1 +1 -1
  19. data/lib/bundler/man/bundle-fund.1 +1 -1
  20. data/lib/bundler/man/bundle-gem.1 +1 -1
  21. data/lib/bundler/man/bundle-help.1 +1 -1
  22. data/lib/bundler/man/bundle-info.1 +1 -1
  23. data/lib/bundler/man/bundle-init.1 +1 -1
  24. data/lib/bundler/man/bundle-install.1 +1 -1
  25. data/lib/bundler/man/bundle-issue.1 +1 -1
  26. data/lib/bundler/man/bundle-licenses.1 +1 -1
  27. data/lib/bundler/man/bundle-list.1 +1 -1
  28. data/lib/bundler/man/bundle-lock.1 +1 -1
  29. data/lib/bundler/man/bundle-open.1 +1 -1
  30. data/lib/bundler/man/bundle-outdated.1 +1 -1
  31. data/lib/bundler/man/bundle-platform.1 +1 -1
  32. data/lib/bundler/man/bundle-plugin.1 +1 -1
  33. data/lib/bundler/man/bundle-pristine.1 +1 -1
  34. data/lib/bundler/man/bundle-remove.1 +1 -1
  35. data/lib/bundler/man/bundle-show.1 +1 -1
  36. data/lib/bundler/man/bundle-update.1 +1 -1
  37. data/lib/bundler/man/bundle-version.1 +1 -1
  38. data/lib/bundler/man/bundle.1 +1 -1
  39. data/lib/bundler/man/gemfile.5 +1 -1
  40. data/lib/bundler/plugin.rb +5 -2
  41. data/lib/bundler/rubygems_gem_installer.rb +0 -3
  42. data/lib/bundler/source/git/git_proxy.rb +1 -1
  43. data/lib/bundler/source/rubygems_aggregate.rb +4 -1
  44. data/lib/bundler/source_map.rb +6 -2
  45. data/lib/bundler/templates/newgem/Cargo.toml.tt +6 -0
  46. data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +7 -0
  47. data/lib/bundler/templates/newgem/ext/newgem/build.rs.tt +5 -0
  48. data/lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt +13 -2
  49. data/lib/bundler/templates/newgem/github/workflows/build-gems.yml.tt +65 -0
  50. data/lib/bundler/templates/newgem/newgem.gemspec.tt +0 -7
  51. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +8 -0
  52. data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +6 -0
  53. data/lib/bundler/version.rb +1 -1
  54. data/lib/bundler.rb +1 -1
  55. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 52862172905cfd08239e83453f143d7dfae83a465e83cdef7206c78bf9480a4a
4
- data.tar.gz: d1d308a70d8140622b33924ff272abe0400d6f7f53557f0806e1da69e3cbcfd7
3
+ metadata.gz: 5a885222998dfbe801692cb3fde27432339068b6273f33d0104e25509d18682d
4
+ data.tar.gz: 5ec66951013a0e8b87db477eae402b15b3f37f768d846515f1b6101e0e47b388
5
5
  SHA512:
6
- metadata.gz: e8e6c576ac1dd40f5b419ae67951b32a7031c6b8c95f3c24f1ef6560eed003b776367028cfbb8899ba1fae09b9d951b96b77d9c8cfe8c2391ff1c4439e2b85a6
7
- data.tar.gz: b66816af7f759593af6d0e6dea83bda8307244522b97b5c22f6e0504043e682ba4a015820b261c12deb9852b914d793c154bfd6e072e9286086e154016777373
6
+ metadata.gz: 20bdb8aab69b64c68f6bed37bbf1912113ab452b0fd4f6ffe1bb4455556c28df301287dea1cc0faeb45efbf37426300eada625efb34d57b4ab9929d3c05ffade
7
+ data.tar.gz: 9a4019d82dd530eac1ac0c6724cad21f6136a78df3ec0a03c63251764ef9190a056a851675550ce3bd4f9965f6040ae9125517ca1038cdbe04a7b97c0c853053
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
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
+
22
+ ## 4.0.6 (2026-02-05)
23
+
24
+ ### Bug fixes:
25
+
26
+ - Fix gzip cache corruption when recovering from HTTP 416 responses [#9272](https://github.com/ruby/rubygems/pull/9272)
27
+ - Fallback git/path sources to default source [#9301](https://github.com/ruby/rubygems/pull/9301)
28
+ - Ensure revision is always re-resolved in `git_proxy.rb` [#9294](https://github.com/ruby/rubygems/pull/9294)
29
+
30
+ ### Documentation:
31
+
32
+ - Clarify local gem override docs to require git-sourced gems [#9305](https://github.com/ruby/rubygems/pull/9305)
33
+
3
34
  ## 4.0.5 (2026-01-29)
4
35
 
5
36
  ### Enhancements:
@@ -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-01-29".freeze
8
- @git_commit_sha = "6d11c1f49d".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
 
@@ -1077,7 +1078,7 @@ module Bundler
1077
1078
  end
1078
1079
  end
1079
1080
 
1080
- if parent_dep && parent_dep.source.is_a?(Source::Path)
1081
+ if parent_dep && parent_dep.source.is_a?(Source::Path) && parent_dep.source.specs[s]&.any?
1081
1082
  replacement_source = parent_dep.source
1082
1083
  else
1083
1084
  replacement_source = sources.get(lockfile_source)
@@ -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|
@@ -54,7 +54,6 @@ module Bundler
54
54
  when Gem::Net::HTTPRequestedRangeNotSatisfiable
55
55
  new_headers = headers.dup
56
56
  new_headers.delete("Range")
57
- new_headers["Accept-Encoding"] = "gzip"
58
57
  fetch(uri, new_headers)
59
58
  when Gem::Net::HTTPRequestEntityTooLarge
60
59
  raise FallbackError, response.body
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-ADD" "1" "September 2025" ""
3
+ .TH "BUNDLE\-ADD" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-BINSTUBS" "1" "September 2025" ""
3
+ .TH "BUNDLE\-BINSTUBS" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CACHE" "1" "September 2025" ""
3
+ .TH "BUNDLE\-CACHE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CHECK" "1" "September 2025" ""
3
+ .TH "BUNDLE\-CHECK" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CLEAN" "1" "September 2025" ""
3
+ .TH "BUNDLE\-CLEAN" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CONFIG" "1" "September 2025" ""
3
+ .TH "BUNDLE\-CONFIG" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-config\fR \- Set bundler configuration options
6
6
  .SH "SYNOPSIS"
@@ -248,7 +248,16 @@ bundle config set \-\-local local\.GEM_NAME /path/to/local/git/repository
248
248
  .fi
249
249
  .IP "" 0
250
250
  .P
251
- For example, in order to use a local Rack repository, a developer could call:
251
+ Important: This feature only works for gems that are specified with a git source in your Gemfile\. It does not work for gems installed from RubyGems or other sources\. The gem must be defined with \fBgit:\fR option pointing to a remote repository\.
252
+ .P
253
+ For example, if your Gemfile contains:
254
+ .IP "" 4
255
+ .nf
256
+ gem "rack", git: "https://github\.com/rack/rack\.git", branch: "main"
257
+ .fi
258
+ .IP "" 0
259
+ .P
260
+ Then you can use a local Rack repository by running:
252
261
  .IP "" 4
253
262
  .nf
254
263
  bundle config set \-\-local local\.rack ~/Work/git/rack
@@ -260,6 +269,13 @@ Now instead of checking out the remote git repository, the local override will b
260
269
  Bundler does many checks to ensure a developer won't work with invalid references\. Particularly, we force a developer to specify a branch in the \fBGemfile\fR in order to use this feature\. If the branch specified in the \fBGemfile\fR and the current branch in the local git repository do not match, Bundler will abort\. This ensures that a developer is always working against the correct branches, and prevents accidental locking to a different branch\.
261
270
  .P
262
271
  Finally, Bundler also ensures that the current revision in the \fBGemfile\.lock\fR exists in the local git repository\. By doing this, Bundler forces you to fetch the latest changes in the remotes\.
272
+ .P
273
+ If you need to temporarily use a local version of a gem that is normally installed from RubyGems (not from git), use a path source instead:
274
+ .IP "" 4
275
+ .nf
276
+ gem "rack", path: "~/Work/git/rack"
277
+ .fi
278
+ .IP "" 0
263
279
  .SH "MIRRORS OF GEM SOURCES"
264
280
  Bundler supports overriding gem sources with mirrors\. This allows you to configure rubygems\.org as the gem source in your Gemfile while still using your mirror to fetch gems\.
265
281
  .IP "" 4
@@ -295,7 +295,16 @@ up a local override:
295
295
 
296
296
  bundle config set --local local.GEM_NAME /path/to/local/git/repository
297
297
 
298
- For example, in order to use a local Rack repository, a developer could call:
298
+ Important: This feature only works for gems that are specified with a git
299
+ source in your Gemfile. It does not work for gems installed from RubyGems
300
+ or other sources. The gem must be defined with `git:` option pointing to a
301
+ remote repository.
302
+
303
+ For example, if your Gemfile contains:
304
+
305
+ gem "rack", git: "https://github.com/rack/rack.git", branch: "main"
306
+
307
+ Then you can use a local Rack repository by running:
299
308
 
300
309
  bundle config set --local local.rack ~/Work/git/rack
301
310
 
@@ -321,6 +330,11 @@ Finally, Bundler also ensures that the current revision in the
321
330
  `Gemfile.lock` exists in the local git repository. By doing this, Bundler
322
331
  forces you to fetch the latest changes in the remotes.
323
332
 
333
+ If you need to temporarily use a local version of a gem that is normally
334
+ installed from RubyGems (not from git), use a path source instead:
335
+
336
+ gem "rack", path: "~/Work/git/rack"
337
+
324
338
  ## MIRRORS OF GEM SOURCES
325
339
 
326
340
  Bundler supports overriding gem sources with mirrors. This allows you to
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-CONSOLE" "1" "September 2025" ""
3
+ .TH "BUNDLE\-CONSOLE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-console\fR \- Open an IRB session with the bundle pre\-loaded
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-DOCTOR" "1" "September 2025" ""
3
+ .TH "BUNDLE\-DOCTOR" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-doctor\fR \- Checks the bundle for common problems
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-ENV" "1" "September 2025" ""
3
+ .TH "BUNDLE\-ENV" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-env\fR \- Print information about the environment Bundler is running under
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-EXEC" "1" "September 2025" ""
3
+ .TH "BUNDLE\-EXEC" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-exec\fR \- Execute a command in the context of the bundle
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-FUND" "1" "September 2025" ""
3
+ .TH "BUNDLE\-FUND" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-fund\fR \- Lists information about gems seeking funding assistance
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-GEM" "1" "September 2025" ""
3
+ .TH "BUNDLE\-GEM" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-HELP" "1" "September 2025" ""
3
+ .TH "BUNDLE\-HELP" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-help\fR \- Displays detailed help for each subcommand
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-INFO" "1" "September 2025" ""
3
+ .TH "BUNDLE\-INFO" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-info\fR \- Show information for the given gem in your bundle
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-INIT" "1" "September 2025" ""
3
+ .TH "BUNDLE\-INIT" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-init\fR \- Generates a Gemfile into the current working directory
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-INSTALL" "1" "September 2025" ""
3
+ .TH "BUNDLE\-INSTALL" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-ISSUE" "1" "September 2025" ""
3
+ .TH "BUNDLE\-ISSUE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-issue\fR \- Get help reporting Bundler issues
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-LICENSES" "1" "September 2025" ""
3
+ .TH "BUNDLE\-LICENSES" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-licenses\fR \- Print the license of all gems in the bundle
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-LIST" "1" "September 2025" ""
3
+ .TH "BUNDLE\-LIST" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-list\fR \- List all the gems in the bundle
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-LOCK" "1" "September 2025" ""
3
+ .TH "BUNDLE\-LOCK" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-OPEN" "1" "September 2025" ""
3
+ .TH "BUNDLE\-OPEN" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-OUTDATED" "1" "September 2025" ""
3
+ .TH "BUNDLE\-OUTDATED" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-outdated\fR \- List installed gems with newer versions available
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-PLATFORM" "1" "September 2025" ""
3
+ .TH "BUNDLE\-PLATFORM" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-platform\fR \- Displays platform compatibility information
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-PLUGIN" "1" "September 2025" ""
3
+ .TH "BUNDLE\-PLUGIN" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-plugin\fR \- Manage Bundler plugins
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-PRISTINE" "1" "September 2025" ""
3
+ .TH "BUNDLE\-PRISTINE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-REMOVE" "1" "September 2025" ""
3
+ .TH "BUNDLE\-REMOVE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-remove\fR \- Removes gems from the Gemfile
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-SHOW" "1" "September 2025" ""
3
+ .TH "BUNDLE\-SHOW" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-UPDATE" "1" "September 2025" ""
3
+ .TH "BUNDLE\-UPDATE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-update\fR \- Update your gems to the latest available versions
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE\-VERSION" "1" "September 2025" ""
3
+ .TH "BUNDLE\-VERSION" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-version\fR \- Prints Bundler version information
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "BUNDLE" "1" "September 2025" ""
3
+ .TH "BUNDLE" "1" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\fR \- Ruby Dependency Management
6
6
  .SH "SYNOPSIS"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.10.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.10.1
3
- .TH "GEMFILE" "5" "September 2025" ""
3
+ .TH "GEMFILE" "5" "February 2026" ""
4
4
  .SH "NAME"
5
5
  \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
6
6
  .SH "SYNOPSIS"
@@ -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?
@@ -137,7 +137,7 @@ module Bundler
137
137
  git "fetch", "--force", "--quiet", *extra_fetch_args(ref), dir: destination
138
138
  end
139
139
 
140
- git "reset", "--hard", @revision, dir: destination
140
+ git "reset", "--hard", revision, dir: destination
141
141
 
142
142
  if submodules
143
143
  git_retry "submodule", "update", "--init", "--recursive", dir: destination
@@ -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.5".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.5
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
@@ -400,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
400
402
  - !ruby/object:Gem::Version
401
403
  version: 3.4.1
402
404
  requirements: []
403
- rubygems_version: 3.6.9
405
+ rubygems_version: 4.0.3
404
406
  specification_version: 4
405
407
  summary: The best way to manage your application's dependencies
406
408
  test_files: []