bundler 4.0.10 → 4.0.12

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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/lib/bundler/build_metadata.rb +1 -1
  4. data/lib/bundler/cli/config.rb +8 -3
  5. data/lib/bundler/cli/gem.rb +1 -1
  6. data/lib/bundler/cli.rb +12 -12
  7. data/lib/bundler/compact_index_client/parser.rb +4 -1
  8. data/lib/bundler/definition.rb +28 -4
  9. data/lib/bundler/installer/parallel_installer.rb +11 -19
  10. data/lib/bundler/lockfile_generator.rb +16 -1
  11. data/lib/bundler/lockfile_parser.rb +23 -1
  12. data/lib/bundler/man/bundle-add.1 +1 -1
  13. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  14. data/lib/bundler/man/bundle-cache.1 +1 -1
  15. data/lib/bundler/man/bundle-check.1 +1 -1
  16. data/lib/bundler/man/bundle-clean.1 +1 -1
  17. data/lib/bundler/man/bundle-config.1 +2 -2
  18. data/lib/bundler/man/bundle-config.1.ronn +1 -1
  19. data/lib/bundler/man/bundle-console.1 +1 -1
  20. data/lib/bundler/man/bundle-doctor.1 +1 -1
  21. data/lib/bundler/man/bundle-env.1 +1 -1
  22. data/lib/bundler/man/bundle-exec.1 +1 -1
  23. data/lib/bundler/man/bundle-fund.1 +1 -1
  24. data/lib/bundler/man/bundle-gem.1 +1 -1
  25. data/lib/bundler/man/bundle-help.1 +1 -1
  26. data/lib/bundler/man/bundle-info.1 +1 -1
  27. data/lib/bundler/man/bundle-init.1 +1 -1
  28. data/lib/bundler/man/bundle-install.1 +1 -1
  29. data/lib/bundler/man/bundle-issue.1 +1 -1
  30. data/lib/bundler/man/bundle-licenses.1 +1 -1
  31. data/lib/bundler/man/bundle-list.1 +1 -1
  32. data/lib/bundler/man/bundle-lock.1 +1 -1
  33. data/lib/bundler/man/bundle-open.1 +1 -1
  34. data/lib/bundler/man/bundle-outdated.1 +1 -1
  35. data/lib/bundler/man/bundle-platform.1 +1 -1
  36. data/lib/bundler/man/bundle-plugin.1 +1 -1
  37. data/lib/bundler/man/bundle-pristine.1 +1 -1
  38. data/lib/bundler/man/bundle-remove.1 +1 -1
  39. data/lib/bundler/man/bundle-show.1 +1 -1
  40. data/lib/bundler/man/bundle-update.1 +1 -1
  41. data/lib/bundler/man/bundle-version.1 +1 -1
  42. data/lib/bundler/man/bundle.1 +1 -1
  43. data/lib/bundler/man/gemfile.5 +1 -1
  44. data/lib/bundler/source/metadata.rb +4 -0
  45. data/lib/bundler/source/path.rb +3 -2
  46. data/lib/bundler/source/rubygems.rb +1 -1
  47. data/lib/bundler/templates/newgem/newgem.gemspec.tt +7 -1
  48. data/lib/bundler/version.rb +1 -1
  49. data/lib/bundler.rb +10 -0
  50. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54c40beb5b2e8ef4f0a575b9d408fe571ef2b1089099fc09d4b46a6adc4307ea
4
- data.tar.gz: 591339a1a0a4512ae8c386c24b98f09ca48ed571a011141dee4874ead6555a2e
3
+ metadata.gz: 94fc49b469e2eb2c15c70f7bb43e4503f0de0962380b5b6eea5909bff3a08d1e
4
+ data.tar.gz: 301b0eb9cb089ba4fda55fcbcd1ad1e65c608c35107906a415546245d58d1368
5
5
  SHA512:
6
- metadata.gz: 15c2b8ba181ff0f418ce40b488b3d148e661992058ed0f1af8a58c3adb774b00fc39e29211c0abd22f51b85098840514fbf35dbb8c5d0c0773f0e4cf22facb8c
7
- data.tar.gz: bf33570321010bd7e2283384c1331ee13bc1f3176de52c16c34a2e56b461c625fc955dfef9ba0d9b157ff0f11591892832eea06621a88facd7e187e85bd8c468
6
+ metadata.gz: ca630b85c261a32145258e2264627f9beca9c45c72cc21ad195a72774d28808fbe57a9b6242af937ac2ee85d636f0f7f73278c97aeae7cf8a7b1de58f7480f50
7
+ data.tar.gz: 40329f0aa226b3e314c740e765ae8d22e298666fcf05454bb9b1788639e4ef1b8bea18cb74f2da33245b0faefcd2dac70175169067f375841decc36bd01523d7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.12 / 2026-05-20
4
+
5
+ ### Enhancements:
6
+
7
+ * Make `bundle config get` return status 1 when the value is not set. Pull request [#9505](https://github.com/ruby/rubygems/pull/9505) by willnet
8
+ * Use Pathname#absolute?. Pull request [#9529](https://github.com/ruby/rubygems/pull/9529) by nobu
9
+ * Deprecate parsing non-lockfile content in LockfileParser. Pull request [#9502](https://github.com/ruby/rubygems/pull/9502) by kurotaky
10
+ * Print a warning for a potential confusion from the indirect dependencies. Pull request [#5029](https://github.com/ruby/rubygems/pull/5029) by junaruga
11
+ * Respect Gemfile bundler setting in `Bundler.setup`. Pull request [#4892](https://github.com/ruby/rubygems/pull/4892) by godfat
12
+
13
+ ### Bug fixes:
14
+
15
+ * Gracefully handle missing checksums in Compact Index. Pull request [#9492](https://github.com/ruby/rubygems/pull/9492) by jneen
16
+ * Skip git source exclusion when lockfile cannot backfill. Pull request [#9544](https://github.com/ruby/rubygems/pull/9544) by yahonda
17
+ * Fix bundle config gemfile unset behavior. Pull request [#9514](https://github.com/ruby/rubygems/pull/9514) by afurm
18
+
19
+ ## 4.0.11 / 2026-04-30
20
+
21
+ ### Enhancements:
22
+
23
+ * Update gem creation guide URL to rubygems.org. Pull request [#9500](https://github.com/ruby/rubygems/pull/9500) by nissyi-gh
24
+ * Lock the checksum of Bundler itself in the lockfile. Pull request [#9366](https://github.com/ruby/rubygems/pull/9366) by Edouard-chin
25
+
26
+ ### Bug fixes:
27
+
28
+ * Fix installing gems with native extensions + transitive dependencies. Pull request [#9477](https://github.com/ruby/rubygems/pull/9477) by nicholasdower
29
+ * Fix the bundler version not being updated in dev/test lockfile. Pull request [#9463](https://github.com/ruby/rubygems/pull/9463) by Edouard-chin
30
+ * Ensure the release CI doesn't break due to the Bundler checksum feature. Pull request [#9436](https://github.com/ruby/rubygems/pull/9436) by Edouard-chin
31
+
32
+ ### Documentation:
33
+
34
+ * Fix formatting for BUNDLE_PREFER_PATCH variable in man page. Pull request [#9474](https://github.com/ruby/rubygems/pull/9474) by toy
35
+
3
36
  ## 4.0.10 / 2026-04-08
4
37
 
5
38
  ### Enhancements:
@@ -5,7 +5,7 @@ module Bundler
5
5
  module BuildMetadata
6
6
  # begin ivars
7
7
  @built_at = nil
8
- @git_commit_sha = "1c1d885018".freeze
8
+ @git_commit_sha = "665f998196".freeze
9
9
  # end ivars
10
10
 
11
11
  # A hash representation of the build metadata.
@@ -87,16 +87,21 @@ module Bundler
87
87
 
88
88
  if value.nil?
89
89
  warn_unused_scope "Ignoring --#{scope} since no value to set was given"
90
+ current_value = Bundler.settings[name]
90
91
 
91
92
  if options[:parseable]
92
93
  if value = Bundler.settings[name]
93
94
  Bundler.ui.info("#{name}=#{value}")
94
95
  end
95
- return
96
+ else
97
+ confirm(name)
96
98
  end
97
99
 
98
- confirm(name)
99
- return
100
+ if current_value.nil?
101
+ exit 1
102
+ else
103
+ return
104
+ end
100
105
  end
101
106
 
102
107
  Bundler.ui.info(message) if message
@@ -288,7 +288,7 @@ module Bundler
288
288
  open_editor(options["edit"], target.join("#{name}.gemspec")) if options[:edit]
289
289
 
290
290
  Bundler.ui.info "\nGem '#{name}' was successfully created. " \
291
- "For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
291
+ "For more information on making a RubyGem visit https://guides.rubygems.org/make-your-own-gem/"
292
292
  end
293
293
 
294
294
  private
data/lib/bundler/cli.rb CHANGED
@@ -61,18 +61,18 @@ module Bundler
61
61
 
62
62
  current_cmd = args.last[:current_command].name
63
63
 
64
- custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile]
65
- if custom_gemfile && !custom_gemfile.empty?
66
- Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
67
- reset_settings = true
68
- end
69
-
70
- # lock --lockfile works differently than install --lockfile
71
- unless current_cmd == "lock"
72
- custom_lockfile = options[:lockfile] || ENV["BUNDLE_LOCKFILE"] || Bundler.settings[:lockfile]
73
- if custom_lockfile && !custom_lockfile.empty?
74
- Bundler::SharedHelpers.set_env "BUNDLE_LOCKFILE", File.expand_path(custom_lockfile)
75
- reset_settings = true
64
+ # `bundle config` manages stored settings, so avoid promoting settings
65
+ # like `gemfile` or `lockfile` to environment variables before it runs.
66
+ unless current_cmd == "config"
67
+ Bundler.configure_custom_gemfile(options[:gemfile])
68
+
69
+ # lock --lockfile works differently than install --lockfile
70
+ unless current_cmd == "lock"
71
+ custom_lockfile = options[:lockfile] || ENV["BUNDLE_LOCKFILE"] || Bundler.settings[:lockfile]
72
+ if custom_lockfile && !custom_lockfile.empty?
73
+ Bundler::SharedHelpers.set_env "BUNDLE_LOCKFILE", File.expand_path(custom_lockfile)
74
+ reset_settings = true
75
+ end
76
76
  end
77
77
  end
78
78
 
@@ -71,7 +71,10 @@ module Bundler
71
71
  # This method gets called at least once for every gem when parsing versions.
72
72
  def parse_version_checksum(line, checksums)
73
73
  return unless (name_end = line.index(" ")) # Artifactory bug causes blank lines in artifactor index files
74
- return unless (checksum_start = line.index(" ", name_end + 1) + 1)
74
+ checksum_start = line.index(" ", name_end + 1)
75
+ return unless checksum_start
76
+ checksum_start += 1
77
+
75
78
  checksum_end = line.size - checksum_start
76
79
 
77
80
  line.freeze # allows slicing into the string to not allocate a copy of the line
@@ -783,7 +783,25 @@ module Bundler
783
783
  end
784
784
 
785
785
  def precompute_source_requirements_for_indirect_dependencies?
786
- sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
786
+ if sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
787
+ true
788
+ else
789
+ non_dependency_api_warning
790
+ false
791
+ end
792
+ end
793
+
794
+ def non_dependency_api_warning
795
+ non_api_sources = sources.non_global_rubygems_sources.reject(&:dependency_api_available?)
796
+ non_api_source_names = non_api_sources.map {|d| " * #{d}" }.join("\n")
797
+
798
+ msg = String.new
799
+ msg << "Your Gemfile contains scoped sources that don't implement a dependency API, namely:\n\n"
800
+ msg << non_api_source_names
801
+ msg << "\n\nUsing the above gem servers may result in installing unexpected gems. " \
802
+ "To resolve this warning, make sure you use gem servers that implement dependency APIs, " \
803
+ "such as gemstash or geminabox gem servers."
804
+ Bundler.ui.warn msg
787
805
  end
788
806
 
789
807
  def current_platform_locked?
@@ -988,6 +1006,8 @@ module Bundler
988
1006
  end
989
1007
  end
990
1008
 
1009
+ sources.metadata_source.checksum_store.merge!(@locked_gems.metadata_source.checksum_store) if @locked_gems
1010
+
991
1011
  changes
992
1012
  end
993
1013
 
@@ -1157,16 +1177,20 @@ module Bundler
1157
1177
  def find_source_requirements
1158
1178
  preload_git_sources
1159
1179
 
1180
+ # Only safe to exclude when locked_requirements (merged below) backfills the gap.
1181
+ nothing_changed = nothing_changed?
1182
+ excluded = nothing_changed ? excluded_git_sources : []
1183
+
1160
1184
  # Record the specs available in each gem's source, so that those
1161
1185
  # specs will be available later when the resolver knows where to
1162
1186
  # look for that gemspec (or its dependencies)
1163
1187
  source_requirements = if precompute_source_requirements_for_indirect_dependencies?
1164
- all_requirements = source_map.all_requirements(excluded_git_sources)
1188
+ all_requirements = source_map.all_requirements(excluded)
1165
1189
  { default: default_source }.merge(all_requirements)
1166
1190
  else
1167
- { default: Source::RubygemsAggregate.new(sources, source_map, excluded_git_sources) }.merge(source_map.direct_requirements)
1191
+ { default: Source::RubygemsAggregate.new(sources, source_map, excluded) }.merge(source_map.direct_requirements)
1168
1192
  end
1169
- source_requirements.merge!(source_map.locked_requirements) if nothing_changed?
1193
+ source_requirements.merge!(source_map.locked_requirements) if nothing_changed
1170
1194
  metadata_dependencies.each do |dep|
1171
1195
  source_requirements[dep.name] = sources.metadata_source
1172
1196
  end
@@ -6,7 +6,7 @@ require_relative "gem_installer"
6
6
  module Bundler
7
7
  class ParallelInstaller
8
8
  class SpecInstallation
9
- attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error
9
+ attr_accessor :spec, :name, :full_name, :post_install_message, :state, :error, :dependencies
10
10
  def initialize(spec)
11
11
  @spec = spec
12
12
  @name = spec.name
@@ -46,25 +46,11 @@ module Bundler
46
46
  !post_install_message.empty?
47
47
  end
48
48
 
49
- def ignorable_dependency?(dep)
50
- dep.type == :development || dep.name == @name
51
- end
52
-
53
- # Checks installed dependencies against spec's dependencies to make
54
- # sure needed dependencies have been installed.
49
+ # Recursively checks that all dependencies (direct and transitive) have been installed.
55
50
  def dependencies_installed?(installed_specs)
56
- dependencies.all? {|d| installed_specs.include? d.name }
57
- end
58
-
59
- # Represents only the non-development dependencies, the ones that are
60
- # itself and are in the total list.
61
- def dependencies
62
- @dependencies ||= all_dependencies.reject {|dep| ignorable_dependency? dep }
63
- end
64
-
65
- # Represents all dependencies
66
- def all_dependencies
67
- @spec.dependencies
51
+ dependencies.all? do |dep|
52
+ installed_specs.include?(dep.name) && dep.dependencies_installed?(installed_specs)
53
+ end
68
54
  end
69
55
 
70
56
  def to_s
@@ -85,6 +71,12 @@ module Bundler
85
71
  @force = force
86
72
  @local = local
87
73
  @specs = all_specs.map {|s| SpecInstallation.new(s) }
74
+ specs_by_name = @specs.to_h {|s| [s.name, s] }
75
+ @specs.each do |spec_install|
76
+ spec_install.dependencies = spec_install.spec.dependencies.filter_map do |dep|
77
+ specs_by_name[dep.name] unless dep.type == :development || dep.name == spec_install.name
78
+ end
79
+ end
88
80
  @specs.each do |spec_install|
89
81
  spec_install.state = :installed if skip.include?(spec_install.name)
90
82
  end if skip
@@ -71,7 +71,8 @@ module Bundler
71
71
  checksums = definition.resolve.map do |spec|
72
72
  spec.source.checksum_store.to_lock(spec)
73
73
  end
74
- add_section("CHECKSUMS", checksums)
74
+
75
+ add_section("CHECKSUMS", checksums + bundler_checksum)
75
76
  end
76
77
 
77
78
  def add_locked_ruby_version
@@ -100,5 +101,19 @@ module Bundler
100
101
  raise ArgumentError, "#{value.inspect} can't be serialized in a lockfile"
101
102
  end
102
103
  end
104
+
105
+ def bundler_checksum
106
+ return [] if Bundler.gem_version.to_s.end_with?(".dev") || ENV["SKIP_BUNDLER_CHECKSUM"]
107
+
108
+ bundler_spec = definition.sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
109
+ return [] unless File.exist?(bundler_spec.cache_file)
110
+
111
+ require "rubygems/package"
112
+
113
+ package = Gem::Package.new(bundler_spec.cache_file)
114
+ definition.sources.metadata_source.checksum_store.register(bundler_spec, Checksum.from_gem_package(package))
115
+
116
+ [definition.sources.metadata_source.checksum_store.to_lock(bundler_spec)]
117
+ end
103
118
  end
104
119
  end
@@ -28,6 +28,7 @@ module Bundler
28
28
 
29
29
  attr_reader(
30
30
  :sources,
31
+ :metadata_source,
31
32
  :dependencies,
32
33
  :specs,
33
34
  :platforms,
@@ -97,6 +98,7 @@ module Bundler
97
98
  def initialize(lockfile, strict: false)
98
99
  @platforms = []
99
100
  @sources = []
101
+ @metadata_source = Source::Metadata.new
100
102
  @dependencies = {}
101
103
  @parse_method = nil
102
104
  @specs = {}
@@ -113,6 +115,17 @@ module Bundler
113
115
  "Run `git checkout HEAD -- #{@lockfile_path}` first to get a clean lock."
114
116
  end
115
117
 
118
+ @valid = lockfile.strip.empty? ||
119
+ lockfile.split(/(?:\r?\n)+/).any? {|l| KNOWN_SECTIONS.include?(l) }
120
+
121
+ unless @valid
122
+ SharedHelpers.feature_deprecated!(
123
+ "Your #{@lockfile_path} does not appear to be a valid lockfile. " \
124
+ "Run `rm #{@lockfile_path}` and then `bundle install` to generate a new lockfile. " \
125
+ "This will raise a LockfileError in a future version of Bundler."
126
+ )
127
+ end
128
+
116
129
  lockfile.split(/((?:\r?\n)+)/) do |line|
117
130
  # split alternates between the line and the following whitespace
118
131
  next @pos.advance!(line) if line.match?(/^\s*$/)
@@ -162,6 +175,10 @@ module Bundler
162
175
  bundler_version.nil? || bundler_version < Gem::Version.new("1.16.2")
163
176
  end
164
177
 
178
+ def valid?
179
+ @valid
180
+ end
181
+
165
182
  private
166
183
 
167
184
  TYPES = {
@@ -252,7 +269,12 @@ module Bundler
252
269
  version = Gem::Version.new(version)
253
270
  platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
254
271
  full_name = Gem::NameTuple.new(name, version, platform).full_name
255
- return unless spec = @specs[full_name]
272
+ spec = @specs[full_name]
273
+
274
+ if name == "bundler"
275
+ spec ||= LazySpecification.new(name, version, platform, @metadata_source)
276
+ end
277
+ return unless spec
256
278
 
257
279
  if checksums
258
280
  checksums.split(",") do |lock_checksum|
@@ -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" "March 2026" ""
3
+ .TH "BUNDLE\-ADD" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-BINSTUBS" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-CACHE" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-CHECK" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-CLEAN" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-CONFIG" "1" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-config\fR \- Set bundler configuration options
6
6
  .SH "SYNOPSIS"
@@ -172,7 +172,7 @@ Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\
172
172
  \fBplugins\fR (\fBBUNDLE_PLUGINS\fR)
173
173
  Enable Bundler's experimental plugin system\.
174
174
  .TP
175
- \fBprefer_patch\fR (BUNDLE_PREFER_PATCH)
175
+ \fBprefer_patch\fR (\fBBUNDLE_PREFER_PATCH\fR)
176
176
  Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\.
177
177
  .TP
178
178
  \fBredirect\fR (\fBBUNDLE_REDIRECT\fR)
@@ -223,7 +223,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
223
223
  Whether Bundler will install gems into the default system path (`Gem.dir`).
224
224
  * `plugins` (`BUNDLE_PLUGINS`):
225
225
  Enable Bundler's experimental plugin system.
226
- * `prefer_patch` (BUNDLE_PREFER_PATCH):
226
+ * `prefer_patch` (`BUNDLE_PREFER_PATCH`):
227
227
  Prefer updating only to next patch version during updates. Makes `bundle update` calls equivalent to `bundler update --patch`.
228
228
  * `redirect` (`BUNDLE_REDIRECT`):
229
229
  The number of redirects allowed for network requests. Defaults to `5`.
@@ -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" "March 2026" ""
3
+ .TH "BUNDLE\-CONSOLE" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-DOCTOR" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-ENV" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-EXEC" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-FUND" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-GEM" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-HELP" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-INFO" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-INIT" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-INSTALL" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-ISSUE" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-LICENSES" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-LIST" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-LOCK" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-OPEN" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-OUTDATED" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-PLATFORM" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-PLUGIN" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-PRISTINE" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-REMOVE" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-SHOW" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-UPDATE" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE\-VERSION" "1" "April 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" "March 2026" ""
3
+ .TH "BUNDLE" "1" "April 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" "March 2026" ""
3
+ .TH "GEMFILE" "5" "April 2026" ""
4
4
  .SH "NAME"
5
5
  \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
6
6
  .SH "SYNOPSIS"
@@ -58,6 +58,10 @@ module Bundler
58
58
  def version_message(spec)
59
59
  "#{spec.name} #{spec.version}"
60
60
  end
61
+
62
+ def checksum_store
63
+ @checksum_store ||= Checksum::Store.new
64
+ end
61
65
  end
62
66
  end
63
67
  end
@@ -220,10 +220,11 @@ module Bundler
220
220
  # Some gem authors put absolute paths in their gemspec
221
221
  # and we have to save them from themselves
222
222
  spec.files = spec.files.filter_map do |path|
223
- next path unless /\A#{Pathname::SEPARATOR_PAT}/o.match?(path)
223
+ pathname = Pathname.new(path)
224
+ next path unless pathname.absolute?
224
225
  next if File.directory?(path)
225
226
  begin
226
- Pathname.new(path).relative_path_from(gem_dir).to_s
227
+ pathname.relative_path_from(gem_dir).to_s
227
228
  rescue ArgumentError
228
229
  path
229
230
  end
@@ -508,7 +508,7 @@ module Bundler
508
508
 
509
509
  # We are using a mutex to reaed and write from/to the hash.
510
510
  # The reason this double synchronization was added is for performance
511
- # and lock the mutex for the shortest possible amount of time. Otherwise,
511
+ # and to lock the mutex for the shortest possible amount of time. Otherwise,
512
512
  # all threads are fighting over this mutex and when it gets acquired it gets locked
513
513
  # until a threads finishes downloading a gem, leaving the other threads waiting
514
514
  # doing nothing.
@@ -22,6 +22,12 @@ Gem::Specification.new do |spec|
22
22
  spec.metadata["changelog_uri"] = "<%= config[:changelog_uri] %>"
23
23
  <%- end -%>
24
24
 
25
+ # Uncomment the line below to require MFA for gem pushes.
26
+ # This helps protect your gem from supply chain attacks by ensuring
27
+ # no one can publish a new version without multi-factor authentication.
28
+ # See: https://guides.rubygems.org/mfa-requirement-opt-in/
29
+ # spec.metadata["rubygems_mfa_required"] = "true"
30
+
25
31
  # Specify which files should be added to the gem when it is released.
26
32
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
27
33
  gemspec = File.basename(__FILE__)
@@ -48,5 +54,5 @@ Gem::Specification.new do |spec|
48
54
  <%- end -%>
49
55
 
50
56
  # For more information and examples about making a new gem, check out our
51
- # guide at: https://bundler.io/guides/creating_gem.html
57
+ # guide at: https://guides.rubygems.org/make-your-own-gem/
52
58
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
3
  module Bundler
4
- VERSION = "4.0.10".freeze
4
+ VERSION = "4.0.12".freeze
5
5
 
6
6
  def self.bundler_major_version
7
7
  @bundler_major_version ||= gem_version.segments.first
data/lib/bundler.rb CHANGED
@@ -156,6 +156,7 @@ module Bundler
156
156
  # Return if all groups are already loaded
157
157
  return @setup if defined?(@setup) && @setup
158
158
 
159
+ configure_custom_gemfile
159
160
  definition.validate_runtime!
160
161
 
161
162
  SharedHelpers.print_major_deprecations!
@@ -586,6 +587,15 @@ module Bundler
586
587
  Bundler.rubygems.clear_paths
587
588
  end
588
589
 
590
+ def configure_custom_gemfile(custom_gemfile = nil)
591
+ custom_gemfile ||= Bundler.settings[:gemfile]
592
+
593
+ if custom_gemfile && !custom_gemfile.empty?
594
+ Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
595
+ reset_settings_and_root!
596
+ end
597
+ end
598
+
589
599
  def self_manager
590
600
  @self_manager ||= begin
591
601
  require_relative "bundler/self_manager"
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.10
4
+ version: 4.0.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - André Arko
@@ -402,7 +402,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
402
402
  - !ruby/object:Gem::Version
403
403
  version: 3.4.1
404
404
  requirements: []
405
- rubygems_version: 4.0.6
405
+ rubygems_version: 4.0.10
406
406
  specification_version: 4
407
407
  summary: The best way to manage your application's dependencies
408
408
  test_files: []