bundler 4.0.6 → 4.0.8

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -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 +28 -10
  7. data/lib/bundler/fetcher/dependency.rb +7 -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 +4 -1
  14. data/lib/bundler/man/bundle-config.1.ronn +5 -0
  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/index.rb +6 -0
  41. data/lib/bundler/plugin.rb +6 -3
  42. data/lib/bundler/rubygems_gem_installer.rb +0 -3
  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 +69 -0
  50. data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +4 -1
  51. data/lib/bundler/templates/newgem/newgem.gemspec.tt +0 -7
  52. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +8 -0
  53. data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +6 -0
  54. data/lib/bundler/version.rb +1 -1
  55. data/lib/bundler.rb +1 -1
  56. metadata +3 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a70d61a2817508c06f7a5fd2af83e48fe8499fe7c18e32d59ec791e0f75a10a
4
- data.tar.gz: d9b5194cd5c5c865041445a99db420ebcc7803dde6934490b09a8dc34b19e473
3
+ metadata.gz: a327d6653bfbbbf147f4ad453e8de1cfa602f903bc442d40cc75be55bc13d996
4
+ data.tar.gz: 00b1a894c6d9a7456db80ab909776b62afabaee98280a8d125f14d7bdccd4d32
5
5
  SHA512:
6
- metadata.gz: 320f7f67ebb313f5b6cfa388e3f04a7fcbb8fb50f5854f33d453478c7b741c48966ac2435690c4ab324e2c4cc445a0c3453e272d35097b6c225f3d514971d175
7
- data.tar.gz: 1c7275717e3389f3de5a346dcdb6a71fb9e526529162e76479493e31613a970a87a6a47b9d745a3fa4fe34fd08bb013c31acd1d12f35714d4949c42add015236
6
+ metadata.gz: d5301d616948ebd2d79ba64536b33dae7cbe7e0695d6cf1de020b5a3f2af455a9ea3a6e899ce157d27eb178774a88c1800e2a3bbd5766f735d889f62a0f3fe27
7
+ data.tar.gz: 6cc72947dcea7c66cc14a39d487657e45fc6e914b6081c19bbc65e22658d3575d0928426fd4c890f0c9ef28f50a8b55a6fff5e6a68d44a1e8606dcb5a7d3d895
data/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.8 (2026-03-11)
4
+
5
+ ### Enhancements:
6
+
7
+ - Add a new Bundler config to control how many specs are fetched [#9363](https://github.com/ruby/rubygems/pull/9363)
8
+ - Restrict GitHub Actions workflow permissions for newgem [#9361](https://github.com/ruby/rubygems/pull/9361)
9
+
10
+ ### Bug fixes:
11
+
12
+ - Fix plugin new version not registering [#9355](https://github.com/ruby/rubygems/pull/9355)
13
+
14
+ ## 4.0.7 (2026-02-25)
15
+
16
+ ### Enhancements:
17
+
18
+ - Don't check whether a plugin needs to be installed: [#9328](https://github.com/ruby/rubygems/pull/9328)
19
+ - [rust gem] Major improvements for gem scaffolding (rebased) [#8455](https://github.com/ruby/rubygems/pull/8455)
20
+ - Fix(bundler): only preload git sources for requested groups [#9234](https://github.com/ruby/rubygems/pull/9234)
21
+ - Raise error when gem contains capital letters [#5432](https://github.com/ruby/rubygems/pull/5432)
22
+
23
+ ### Bug fixes:
24
+
25
+ - Fix Bundler crashing when it tries to install plugin: [#9335](https://github.com/ruby/rubygems/pull/9335)
26
+ - Run git operations in parallel (take 2): [#9323](https://github.com/ruby/rubygems/pull/9323)
27
+ - Add support for help flag in plugin commands [#9263](https://github.com/ruby/rubygems/pull/9263)
28
+
29
+ ### Documentation:
30
+
31
+ - [DOC] Fix link in Bundler [#9315](https://github.com/ruby/rubygems/pull/9315)
32
+
3
33
  ## 4.0.6 (2026-02-05)
4
34
 
5
35
  ### 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-03-11".freeze
8
+ @git_commit_sha = "1a32b76b73".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|
@@ -50,7 +50,7 @@ module Bundler
50
50
 
51
51
  def unmarshalled_dep_gems(gem_names)
52
52
  gem_list = []
53
- gem_names.each_slice(Source::Rubygems::API_REQUEST_SIZE) do |names|
53
+ gem_names.each_slice(api_request_size) do |names|
54
54
  marshalled_deps = downloader.fetch(dependency_api_uri(names)).body
55
55
  gem_list.concat(Bundler.safe_load_marshal(marshalled_deps))
56
56
  end
@@ -74,6 +74,12 @@ module Bundler
74
74
  uri.query = "gems=#{CGI.escape(gem_names.sort.join(","))}" if gem_names.any?
75
75
  uri
76
76
  end
77
+
78
+ private
79
+
80
+ def api_request_size
81
+ Bundler.settings[:api_request_size]&.to_i || Source::Rubygems::API_REQUEST_SIZE
82
+ end
77
83
  end
78
84
  end
79
85
  end
@@ -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" "February 2026" ""
3
+ .TH "BUNDLE\-ADD" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-BINSTUBS" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-CACHE" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-CHECK" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-CLEAN" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-CONFIG" "1" "March 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-config\fR \- Set bundler configuration options
6
6
  .SH "SYNOPSIS"
@@ -70,6 +70,9 @@ Any periods in the configuration keys must be replaced with two underscores when
70
70
  .SH "LIST OF AVAILABLE KEYS"
71
71
  The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\.
72
72
  .TP
73
+ \fBapi_request_size\fR (\fBBUNDLE_API_REQUEST_SIZE\fR)
74
+ Configure how many dependencies to fetch when resolving the specifications\. This configuration is only used when fetchig specifications from RubyGems servers that didn't implement the Compact Index API\. Defaults to 100\.
75
+ .TP
73
76
  \fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR)
74
77
  Automatically run \fBbundle install\fR when gems are missing\.
75
78
  .TP
@@ -106,6 +106,11 @@ the environment variable `BUNDLE_LOCAL__RACK`.
106
106
  The following is a list of all configuration keys and their purpose. You can
107
107
  learn more about their operation in [bundle install(1)](bundle-install.1.html).
108
108
 
109
+ * `api_request_size` (`BUNDLE_API_REQUEST_SIZE`):
110
+ Configure how many dependencies to fetch when resolving the specifications.
111
+ This configuration is only used when fetchig specifications from RubyGems
112
+ servers that didn't implement the Compact Index API.
113
+ Defaults to 100.
109
114
  * `auto_install` (`BUNDLE_AUTO_INSTALL`):
110
115
  Automatically run `bundle install` when gems are missing.
111
116
  * `bin` (`BUNDLE_BIN`):
@@ -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" "February 2026" ""
3
+ .TH "BUNDLE\-CONSOLE" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-DOCTOR" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-ENV" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-EXEC" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-FUND" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-GEM" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-HELP" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-INFO" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-INIT" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-INSTALL" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-ISSUE" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-LICENSES" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-LIST" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-LOCK" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-OPEN" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-OUTDATED" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-PLATFORM" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-PLUGIN" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-PRISTINE" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-REMOVE" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-SHOW" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-UPDATE" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE\-VERSION" "1" "March 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" "February 2026" ""
3
+ .TH "BUNDLE" "1" "March 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" "February 2026" ""
3
+ .TH "GEMFILE" "5" "March 2026" ""
4
4
  .SH "NAME"
5
5
  \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
6
6
  .SH "SYNOPSIS"
@@ -119,6 +119,12 @@ module Bundler
119
119
  @plugin_paths[name]
120
120
  end
121
121
 
122
+ def up_to_date?(spec)
123
+ path = installed?(spec.name)
124
+
125
+ path == spec.full_gem_path
126
+ end
127
+
122
128
  def installed_plugins
123
129
  @plugin_paths.keys
124
130
  end
@@ -113,7 +113,7 @@ module Bundler
113
113
 
114
114
  return if definition.dependencies.empty?
115
115
 
116
- plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p }
116
+ plugins = definition.dependencies.map(&:name)
117
117
  installed_specs = Installer.new.install_definition(definition)
118
118
 
119
119
  save_plugins plugins, installed_specs, builder.inferred_plugins
@@ -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.up_to_date?(spec)
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,69 @@
1
+ ---
2
+ name: Build gems
3
+
4
+ on:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+ - "cross-gem/*"
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+ packages: write
14
+
15
+ jobs:
16
+ ci-data:
17
+ runs-on: ubuntu-latest
18
+ outputs:
19
+ result: ${{ steps.fetch.outputs.result }}
20
+ steps:
21
+ - uses: oxidize-rb/actions/fetch-ci-data@v1
22
+ id: fetch
23
+ with:
24
+ supported-ruby-platforms: |
25
+ exclude: ["arm-linux", "x64-mingw32"]
26
+ stable-ruby-versions: |
27
+ exclude: ["head"]
28
+
29
+ source-gem:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v6
33
+
34
+ - uses: ruby/setup-ruby@v1
35
+ with:
36
+ bundler-cache: true
37
+
38
+ - name: Build gem
39
+ run: bundle exec rake build
40
+
41
+ - uses: actions/upload-artifact@v7
42
+ with:
43
+ name: source-gem
44
+ path: pkg/*.gem
45
+
46
+ cross-gem:
47
+ name: Compile native gem for ${{ matrix.platform }}
48
+ runs-on: ubuntu-latest
49
+ needs: ci-data
50
+ strategy:
51
+ matrix:
52
+ platform: ${{ fromJSON(needs.ci-data.outputs.result).supported-ruby-platforms }}
53
+ steps:
54
+ - uses: actions/checkout@v6
55
+
56
+ - uses: ruby/setup-ruby@v1
57
+ with:
58
+ bundler-cache: true
59
+
60
+ - uses: oxidize-rb/actions/cross-gem@v1
61
+ id: cross-gem
62
+ with:
63
+ platform: ${{ matrix.platform }}
64
+ ruby-versions: ${{ join(fromJSON(needs.ci-data.outputs.result).stable-ruby-versions, ',') }}
65
+
66
+ - uses: actions/upload-artifact@v7
67
+ with:
68
+ name: cross-gem
69
+ path: ${{ steps.cross-gem.outputs.gem-path }}
@@ -7,6 +7,9 @@ on:
7
7
 
8
8
  pull_request:
9
9
 
10
+ permissions:
11
+ contents: read
12
+
10
13
  jobs:
11
14
  build:
12
15
  runs-on: ubuntu-latest
@@ -17,7 +20,7 @@ jobs:
17
20
  - '<%= RUBY_VERSION %>'
18
21
 
19
22
  steps:
20
- - uses: actions/checkout@v4
23
+ - uses: actions/checkout@v6
21
24
  with:
22
25
  persist-credentials: false
23
26
  <%- if config[:ext] == 'rust' -%>
@@ -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.8".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.8
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