bundler 4.0.21 → 4.1.0.beta1

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/{lib/bundler/vendor/connection_pool/LICENSE → MIT.txt} +8 -6
  3. data/bundler.gemspec +23 -6
  4. data/lib/bundler/build_metadata.rb +2 -2
  5. data/lib/bundler/checksum.rb +40 -25
  6. data/lib/bundler/ci_detector.rb +1 -1
  7. data/lib/bundler/cli/add.rb +3 -4
  8. data/lib/bundler/cli/cache.rb +4 -0
  9. data/lib/bundler/cli/clean.rb +5 -0
  10. data/lib/bundler/cli/common.rb +37 -1
  11. data/lib/bundler/cli/config.rb +4 -2
  12. data/lib/bundler/cli/gem.rb +0 -17
  13. data/lib/bundler/cli/install.rb +4 -5
  14. data/lib/bundler/cli/lock.rb +1 -2
  15. data/lib/bundler/cli/outdated.rb +8 -3
  16. data/lib/bundler/cli/pristine.rb +2 -1
  17. data/lib/bundler/cli/update.rb +21 -12
  18. data/lib/bundler/cli.rb +14 -11
  19. data/lib/bundler/definition.rb +61 -24
  20. data/lib/bundler/dependency.rb +4 -0
  21. data/lib/bundler/dsl.rb +77 -11
  22. data/lib/bundler/endpoint_specification.rb +51 -14
  23. data/lib/bundler/env.rb +7 -24
  24. data/lib/bundler/errors.rb +34 -5
  25. data/lib/bundler/fetcher/compact_index.rb +14 -5
  26. data/lib/bundler/fetcher/connection_pools.rb +150 -0
  27. data/lib/bundler/fetcher/downloader.rb +31 -16
  28. data/lib/bundler/fetcher.rb +8 -47
  29. data/lib/bundler/injector.rb +3 -3
  30. data/lib/bundler/inline.rb +44 -4
  31. data/lib/bundler/installer/parallel_installer.rb +25 -30
  32. data/lib/bundler/installer.rb +20 -6
  33. data/lib/bundler/lazy_specification.rb +44 -17
  34. data/lib/bundler/lockfile_generator.rb +24 -2
  35. data/lib/bundler/lockfile_parser.rb +43 -5
  36. data/lib/bundler/man/bundle-add.1 +7 -4
  37. data/lib/bundler/man/bundle-add.1.ronn +8 -4
  38. data/lib/bundler/man/bundle-binstubs.1 +1 -1
  39. data/lib/bundler/man/bundle-cache.1 +2 -2
  40. data/lib/bundler/man/bundle-cache.1.ronn +2 -2
  41. data/lib/bundler/man/bundle-check.1 +1 -1
  42. data/lib/bundler/man/bundle-clean.1 +1 -1
  43. data/lib/bundler/man/bundle-config.1 +38 -6
  44. data/lib/bundler/man/bundle-config.1.ronn +143 -10
  45. data/lib/bundler/man/bundle-console.1 +1 -1
  46. data/lib/bundler/man/bundle-doctor.1 +1 -1
  47. data/lib/bundler/man/bundle-env.1 +1 -1
  48. data/lib/bundler/man/bundle-exec.1 +1 -1
  49. data/lib/bundler/man/bundle-fund.1 +1 -1
  50. data/lib/bundler/man/bundle-gem.1 +1 -1
  51. data/lib/bundler/man/bundle-help.1 +1 -1
  52. data/lib/bundler/man/bundle-info.1 +1 -1
  53. data/lib/bundler/man/bundle-init.1 +1 -1
  54. data/lib/bundler/man/bundle-install.1 +2 -2
  55. data/lib/bundler/man/bundle-install.1.ronn +4 -4
  56. data/lib/bundler/man/bundle-issue.1 +1 -1
  57. data/lib/bundler/man/bundle-licenses.1 +1 -1
  58. data/lib/bundler/man/bundle-list.1 +1 -1
  59. data/lib/bundler/man/bundle-lock.1 +3 -3
  60. data/lib/bundler/man/bundle-lock.1.ronn +5 -5
  61. data/lib/bundler/man/bundle-open.1 +1 -1
  62. data/lib/bundler/man/bundle-outdated.1 +1 -1
  63. data/lib/bundler/man/bundle-platform.1 +1 -1
  64. data/lib/bundler/man/bundle-plugin.1 +1 -1
  65. data/lib/bundler/man/bundle-pristine.1 +1 -1
  66. data/lib/bundler/man/bundle-remove.1 +1 -1
  67. data/lib/bundler/man/bundle-show.1 +1 -1
  68. data/lib/bundler/man/bundle-update.1 +3 -3
  69. data/lib/bundler/man/bundle-update.1.ronn +3 -5
  70. data/lib/bundler/man/bundle-version.1 +1 -1
  71. data/lib/bundler/man/bundle.1 +1 -1
  72. data/lib/bundler/man/gemfile.5 +45 -1
  73. data/lib/bundler/man/gemfile.5.ronn +53 -0
  74. data/lib/bundler/match_metadata.rb +20 -0
  75. data/lib/bundler/match_platform.rb +25 -2
  76. data/lib/bundler/match_remote_metadata.rb +21 -6
  77. data/lib/bundler/materialization.rb +2 -1
  78. data/lib/bundler/override.rb +69 -0
  79. data/lib/bundler/plugin/dsl.rb +3 -5
  80. data/lib/bundler/plugin/events.rb +55 -13
  81. data/lib/bundler/plugin/index.rb +87 -11
  82. data/lib/bundler/plugin/installer/path.rb +1 -1
  83. data/lib/bundler/plugin/installer.rb +13 -5
  84. data/lib/bundler/plugin.rb +58 -30
  85. data/lib/bundler/remote_specification.rb +6 -3
  86. data/lib/bundler/resolver/base.rb +2 -1
  87. data/lib/bundler/resolver/incompatibility.rb +1 -1
  88. data/lib/bundler/resolver.rb +73 -23
  89. data/lib/bundler/ruby_version.rb +0 -2
  90. data/lib/bundler/rubygems_ext.rb +71 -1
  91. data/lib/bundler/rubygems_gem_installer.rb +41 -2
  92. data/lib/bundler/rubygems_integration.rb +7 -2
  93. data/lib/bundler/runtime.rb +69 -2
  94. data/lib/bundler/self_manager.rb +9 -15
  95. data/lib/bundler/settings.rb +373 -30
  96. data/lib/bundler/shared_helpers.rb +2 -1
  97. data/lib/bundler/source/git/git_proxy.rb +2 -10
  98. data/lib/bundler/source/git.rb +15 -6
  99. data/lib/bundler/source/path/installer.rb +1 -1
  100. data/lib/bundler/source/rubygems/remote.rb +10 -5
  101. data/lib/bundler/source/rubygems.rb +48 -12
  102. data/lib/bundler/spec_set.rb +16 -4
  103. data/lib/bundler/stub_specification.rb +2 -1
  104. data/lib/bundler/templates/newgem/Gemfile.tt +4 -4
  105. data/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -3
  106. data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
  107. data/lib/bundler/templates/newgem/test/minitest/test_newgem.rb.tt +1 -1
  108. data/lib/bundler/ui/shell.rb +0 -4
  109. data/lib/bundler/ui/silent.rb +0 -4
  110. data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +35 -2
  111. data/lib/bundler/vendor/thor/lib/thor/base.rb +2 -1
  112. data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +14 -6
  113. data/lib/bundler/vendor/thor/lib/thor/shell/color.rb +2 -0
  114. data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
  115. data/lib/bundler/vendor/thor/lib/thor.rb +34 -1
  116. data/lib/bundler/vendored_pub_grub.rb +5 -2
  117. data/lib/bundler/vendored_securerandom.rb +11 -8
  118. data/lib/bundler/vendored_uri.rb +14 -14
  119. data/lib/bundler/version.rb +1 -1
  120. data/lib/bundler/worker.rb +3 -2
  121. data/lib/bundler.rb +1 -1
  122. data/lib/rubygems/compact_index_client/cache.rb +122 -0
  123. data/lib/rubygems/compact_index_client/cache_file.rb +147 -0
  124. data/lib/rubygems/compact_index_client/http_fetcher.rb +88 -0
  125. data/lib/rubygems/compact_index_client/parser.rb +90 -0
  126. data/lib/rubygems/compact_index_client/updater.rb +113 -0
  127. data/lib/rubygems/compact_index_client.rb +111 -0
  128. data/lib/rubygems/cooldown_settings.rb +57 -0
  129. data/lib/rubygems/credential_store/native/linux.rb +97 -0
  130. data/lib/rubygems/credential_store/native/macos.rb +88 -0
  131. data/lib/rubygems/credential_store/native/windows.rb +130 -0
  132. data/lib/rubygems/credential_store.rb +332 -0
  133. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/assignment.rb +1 -1
  134. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/basic_package_source.rb +7 -7
  135. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/failure_writer.rb +1 -1
  136. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/incompatibility.rb +4 -4
  137. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/package.rb +1 -1
  138. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/partial_solution.rb +1 -1
  139. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/rubygems.rb +3 -3
  140. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/solve_failure.rb +1 -1
  141. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/static_package_source.rb +3 -3
  142. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/strategy.rb +2 -2
  143. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/term.rb +1 -1
  144. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version.rb +1 -1
  145. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_constraint.rb +3 -3
  146. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_range.rb +1 -1
  147. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_solver.rb +2 -2
  148. data/lib/{bundler → rubygems}/vendor/pub_grub/lib/pub_grub/version_union.rb +1 -1
  149. data/lib/rubygems/vendor/pub_grub/lib/pub_grub.rb +57 -0
  150. data/lib/{bundler → rubygems}/vendor/securerandom/lib/securerandom.rb +10 -6
  151. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/common.rb +119 -119
  152. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/file.rb +13 -13
  153. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ftp.rb +24 -24
  154. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/generic.rb +132 -132
  155. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/http.rb +18 -18
  156. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/https.rb +4 -4
  157. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldap.rb +14 -14
  158. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ldaps.rb +4 -4
  159. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/mailto.rb +21 -21
  160. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc2396_parser.rb +39 -39
  161. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/rfc3986_parser.rb +14 -14
  162. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/version.rb +1 -1
  163. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/ws.rb +12 -12
  164. data/lib/{bundler → rubygems}/vendor/uri/lib/uri/wss.rb +4 -4
  165. data/lib/{bundler → rubygems}/vendor/uri/lib/uri.rb +35 -31
  166. data/lib/rubygems/yaml_serializer.rb +880 -0
  167. metadata +77 -68
  168. data/CHANGELOG.md +0 -5784
  169. data/LICENSE.md +0 -22
  170. data/README.md +0 -58
  171. data/lib/bundler/compact_index_client/cache.rb +0 -107
  172. data/lib/bundler/compact_index_client/cache_file.rb +0 -148
  173. data/lib/bundler/compact_index_client/parser.rb +0 -87
  174. data/lib/bundler/compact_index_client/updater.rb +0 -105
  175. data/lib/bundler/compact_index_client.rb +0 -92
  176. data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +0 -227
  177. data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +0 -3
  178. data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +0 -56
  179. data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +0 -230
  180. data/lib/bundler/vendor/net-http-persistent/README.rdoc +0 -82
  181. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/connection.rb +0 -41
  182. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/pool.rb +0 -65
  183. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent/timed_stack_multi.rb +0 -80
  184. data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +0 -1153
  185. data/lib/bundler/vendor/pub_grub/lib/pub_grub.rb +0 -31
  186. data/lib/bundler/vendored_persistent.rb +0 -11
  187. data/lib/bundler/yaml_serializer.rb +0 -98
  188. /data/lib/{bundler → rubygems}/vendor/pub_grub/LICENSE.txt +0 -0
  189. /data/lib/{bundler → rubygems}/vendor/securerandom/COPYING +0 -0
  190. /data/lib/{bundler → rubygems}/vendor/uri/COPYING +0 -0
@@ -8,8 +8,9 @@ module Bundler
8
8
  include MatchPlatform
9
9
  include ForcePlatform
10
10
 
11
- attr_reader :name, :version, :platform, :materialization
11
+ attr_reader :name, :version, :platform, :materialization, :content_address
12
12
  attr_accessor :source, :remote, :force_ruby_platform, :dependencies, :required_ruby_version, :required_rubygems_version
13
+ attr_accessor :overrides
13
14
 
14
15
  #
15
16
  # For backwards compatibility with existing lockfiles, if the most specific
@@ -26,20 +27,22 @@ module Bundler
26
27
  alias_method :runtime_dependencies, :dependencies
27
28
 
28
29
  def self.from_spec(s)
29
- lazy_spec = new(s.name, s.version, s.platform, s.source)
30
+ lazy_spec = new(s.name, s.version, s.platform, s.source, content_address: s.content_address)
30
31
  lazy_spec.dependencies = s.runtime_dependencies
31
32
  lazy_spec.required_ruby_version = s.required_ruby_version
32
33
  lazy_spec.required_rubygems_version = s.required_rubygems_version
34
+ lazy_spec.overrides = s.overrides if s.is_a?(LazySpecification)
33
35
  lazy_spec
34
36
  end
35
37
 
36
- def initialize(name, version, platform, source = nil, **materialization_options)
38
+ def initialize(name, version, platform, source = nil, content_address: nil, **materialization_options)
37
39
  @name = name
38
40
  @version = version
39
41
  @dependencies = []
40
42
  @required_ruby_version = Gem::Requirement.default
41
43
  @required_rubygems_version = Gem::Requirement.default
42
44
  @platform = platform || Gem::Platform::RUBY
45
+ @content_address = content_address
43
46
 
44
47
  @original_source = source
45
48
  @source = source
@@ -63,19 +66,25 @@ module Bundler
63
66
  end
64
67
 
65
68
  def full_name
66
- @full_name ||= if platform == Gem::Platform::RUBY
69
+ @full_name ||= if Gem::ContentAddress.content_addressed?(self, validate_ruby_abi: false)
70
+ "#{@name}-#{@version}-#{@content_address}"
71
+ elsif platform == Gem::Platform::RUBY
67
72
  "#{@name}-#{@version}"
68
73
  else
69
74
  "#{@name}-#{@version}-#{platform}"
70
75
  end
71
76
  end
72
77
 
78
+ def file_name
79
+ "#{full_name}.gem"
80
+ end
81
+
73
82
  def lock_name
74
83
  @lock_name ||= name_tuple.lock_name
75
84
  end
76
85
 
77
86
  def name_tuple
78
- Gem::NameTuple.new(@name, @version, @platform)
87
+ Gem::NameTuple.new(@name, @version, @platform, content_address: @content_address)
79
88
  end
80
89
 
81
90
  def ==(other)
@@ -110,6 +119,16 @@ module Bundler
110
119
  @name == dependency.name && effective_requirement.satisfied_by?(Gem::Version.new(@version))
111
120
  end
112
121
 
122
+ ##
123
+ # Assigns the content address parsed from the lockfile's CONTENT
124
+ # ADDRESSES section. The full name embeds the content address, so its
125
+ # memoization must be invalidated.
126
+
127
+ def content_address=(value)
128
+ @content_address = value
129
+ @full_name = nil
130
+ end
131
+
113
132
  def to_lock
114
133
  out = String.new
115
134
  out << " #{lock_name}\n"
@@ -128,13 +147,13 @@ module Bundler
128
147
  materialize(self, &:first)
129
148
  end
130
149
 
131
- def materialized_for_installation
132
- @materialization = materialize_for_installation
150
+ def materialized_for_installation(locked_platforms = nil)
151
+ @materialization = materialize_for_installation(locked_platforms)
133
152
 
134
153
  self unless incomplete?
135
154
  end
136
155
 
137
- def materialize_for_installation
156
+ def materialize_for_installation(locked_platforms)
138
157
  source.local!
139
158
 
140
159
  if use_exact_resolved_specifications?
@@ -144,7 +163,7 @@ module Bundler
144
163
  # Exact spec is incompatible; in frozen mode, try to find a compatible platform variant
145
164
  # In non-frozen mode, return nil to trigger re-resolution and lockfile update
146
165
  if Bundler.frozen_bundle?
147
- materialize([name, version]) {|specs| resolve_best_platform(specs) }
166
+ materialize([name, version]) {|specs| resolve_best_platform(specs, locked_platforms: locked_platforms) }
148
167
  end
149
168
  else
150
169
  materialize([name, version]) {|specs| resolve_best_platform(specs) }
@@ -185,12 +204,14 @@ module Bundler
185
204
  # Try platforms in order of preference until finding a compatible spec.
186
205
  # Used for legacy lockfiles and as a fallback when the exact locked spec
187
206
  # is incompatible. Falls back to frozen bundle behavior if none match.
188
- def resolve_best_platform(specs)
189
- find_compatible_platform_spec(specs) || frozen_bundle_fallback(specs)
207
+ def resolve_best_platform(specs, locked_platforms: nil)
208
+ specs = MatchPlatform.select_all_content_address_match(specs, content_address)
209
+
210
+ find_compatible_platform_spec(specs, locked_platforms: locked_platforms) || frozen_bundle_fallback(specs)
190
211
  end
191
212
 
192
- def find_compatible_platform_spec(specs)
193
- candidate_platforms.each do |plat|
213
+ def find_compatible_platform_spec(specs, locked_platforms: nil)
214
+ candidate_platforms(locked_platforms: locked_platforms).each do |plat|
194
215
  candidates = MatchPlatform.select_best_platform_match(specs, plat)
195
216
  spec = choose_compatible(candidates, fallback_to_non_installable: false)
196
217
  return spec if spec
@@ -200,9 +221,14 @@ module Bundler
200
221
 
201
222
  # Platforms to try in order of preference. Ruby platform is last since it
202
223
  # requires compilation, but works when precompiled gems are incompatible.
203
- def candidate_platforms
224
+ # When a set of locked platforms is given (frozen mode), restrict the
225
+ # candidates to those, so we never materialize a platform that wasn't locked.
226
+ def candidate_platforms(locked_platforms: nil)
204
227
  target = source.is_a?(Source::Path) ? platform : Bundler.local_platform
205
- [target, platform, Gem::Platform::RUBY].uniq
228
+ platforms = [target, platform, Gem::Platform::RUBY].uniq
229
+ return platforms unless locked_platforms
230
+
231
+ platforms & locked_platforms
206
232
  end
207
233
 
208
234
  # In frozen mode, accept any candidate. Will error at install time.
@@ -234,8 +260,9 @@ module Bundler
234
260
  # about the mismatch higher up the stack, right before trying to install the
235
261
  # bad gem.
236
262
  def choose_compatible(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
263
+ override_list = overrides || []
237
264
  search = candidates.reverse.find do |spec|
238
- spec.is_a?(StubSpecification) || spec.matches_current_metadata?
265
+ spec.is_a?(StubSpecification) || spec.matches_current_metadata_with_overrides?(override_list)
239
266
  end
240
267
  if search.nil? && fallback_to_non_installable
241
268
  search = candidates.last
@@ -262,7 +289,7 @@ module Bundler
262
289
  spec.dependencies = dependencies
263
290
  else
264
291
  if !source.is_a?(Source::Path) && spec.runtime_dependencies.sort != dependencies.sort
265
- raise IncorrectLockfileDependencies.new(self)
292
+ raise IncorrectLockfileDependencies.new(self, spec.runtime_dependencies, dependencies)
266
293
  end
267
294
  end
268
295
  end
@@ -19,6 +19,7 @@ module Bundler
19
19
  add_sources
20
20
  add_platforms
21
21
  add_dependencies
22
+ add_content_addresses
22
23
  add_checksums
23
24
  add_locked_ruby_version
24
25
  add_bundled_with
@@ -66,10 +67,31 @@ module Bundler
66
67
  end
67
68
  end
68
69
 
70
+ def add_content_addresses
71
+ content_addresses = definition.resolve.filter_map do |spec|
72
+ next unless Gem::ContentAddress.content_addressed?(spec, validate_ruby_abi: false)
73
+
74
+ line = "#{spec.lock_name} #{spec.content_address}"
75
+
76
+ if definition.locked_checksums
77
+ checksums = spec.source.checksum_store.checksums_to_lock(spec.full_name)
78
+ line += " #{checksums}" if checksums
79
+ end
80
+
81
+ line
82
+ end
83
+
84
+ add_section("CONTENT ADDRESSES", content_addresses) unless content_addresses.empty?
85
+ end
86
+
69
87
  def add_checksums
70
88
  return unless definition.locked_checksums
71
- checksums = definition.resolve.map do |spec|
72
- spec.source.checksum_store.to_lock(spec)
89
+ checksums = definition.resolve.filter_map do |spec|
90
+ line = spec.source.checksum_store.to_lock(spec)
91
+
92
+ next if line == spec.lock_name && Gem::ContentAddress.content_addressed?(spec, validate_ruby_abi: false)
93
+
94
+ line
73
95
  end
74
96
 
75
97
  add_section("CHECKSUMS", checksums + bundler_checksum)
@@ -41,6 +41,7 @@ module Bundler
41
41
  BUNDLED = "BUNDLED WITH"
42
42
  DEPENDENCIES = "DEPENDENCIES"
43
43
  CHECKSUMS = "CHECKSUMS"
44
+ CONTENT_ADDRESSES = "CONTENT ADDRESSES"
44
45
  PLATFORMS = "PLATFORMS"
45
46
  RUBY = "RUBY VERSION"
46
47
  GIT = "GIT"
@@ -57,6 +58,7 @@ module Bundler
57
58
  Gem::Version.create("1.12") => [RUBY].freeze,
58
59
  Gem::Version.create("1.13") => [PLUGIN].freeze,
59
60
  Gem::Version.create("2.5.0") => [CHECKSUMS].freeze,
61
+ Gem::Version.create("4.1.0") => [CONTENT_ADDRESSES].freeze,
60
62
  }.freeze
61
63
 
62
64
  KNOWN_SECTIONS = SECTIONS_BY_VERSION_INTRODUCED.values.flatten!.freeze
@@ -95,14 +97,14 @@ module Bundler
95
97
  lockfile_contents.split(BUNDLED).last.strip
96
98
  end
97
99
 
98
- def initialize(lockfile, strict: false)
100
+ def initialize(lockfile, strict: false, lockfile_path: nil)
99
101
  @platforms = []
100
102
  @sources = []
101
103
  @metadata_source = Source::Metadata.new
102
104
  @dependencies = {}
103
105
  @parse_method = nil
104
106
  @specs = {}
105
- @lockfile_path = begin
107
+ @lockfile_path = lockfile_path || begin
106
108
  SharedHelpers.relative_lockfile_path
107
109
  rescue GemfileNotFound
108
110
  "Gemfile.lock"
@@ -140,6 +142,8 @@ module Bundler
140
142
  # for all gemfiles that don't already explicitly include the feature.
141
143
  @checksums = true
142
144
  @parse_method = :parse_checksum
145
+ elsif line == CONTENT_ADDRESSES
146
+ @parse_method = :parse_content_address
143
147
  elsif line == PLATFORMS
144
148
  @parse_method = :parse_platform
145
149
  elsif line == RUBY
@@ -227,6 +231,16 @@ module Bundler
227
231
  $ # Line end
228
232
  /xo
229
233
 
234
+ NAME_VERSION_CONTENT_ADDRESS = /
235
+ ^#{space}{2}(?!#{space}) # Exactly 2 spaces at the start of the line
236
+ (.*?) # Name
237
+ #{space}\(([^-]*) # Space, followed by version
238
+ -(.*)\) # Platform, always present for content-addressable gems
239
+ #{space}([0-9a-f]{8,64}) # Content address
240
+ (?:#{space}([^ ]+))? # Optional checksums
241
+ $ # Line end
242
+ /xo
243
+
230
244
  def parse_dependency(line)
231
245
  return unless line =~ NAME_VERSION
232
246
  spaces = $1
@@ -268,7 +282,8 @@ module Bundler
268
282
 
269
283
  version = Gem::Version.new(version)
270
284
  platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
271
- full_name = Gem::NameTuple.new(name, version, platform).full_name
285
+ name_tuple = Gem::NameTuple.new(name, version, platform)
286
+ full_name = name_tuple.full_name
272
287
  spec = @specs[full_name]
273
288
 
274
289
  if name == "bundler"
@@ -280,10 +295,33 @@ module Bundler
280
295
  checksums.split(",") do |lock_checksum|
281
296
  column = line.index(lock_checksum) + 1
282
297
  checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
283
- spec.source.checksum_store.register(spec, checksum)
298
+ spec.source.checksum_store.register(name_tuple, checksum)
284
299
  end
285
300
  else
286
- spec.source.checksum_store.register(spec, nil)
301
+ spec.source.checksum_store.register(name_tuple, nil)
302
+ end
303
+ end
304
+
305
+ def parse_content_address(line)
306
+ return unless line =~ NAME_VERSION_CONTENT_ADDRESS
307
+
308
+ name = -$1
309
+ version = Gem::Version.new($2)
310
+ platform = Gem::Platform.new($3)
311
+ content_address = $4
312
+ checksums = $5
313
+
314
+ spec = @specs[Gem::NameTuple.new(name, version, platform).full_name]
315
+ return unless spec
316
+
317
+ spec.content_address = content_address
318
+
319
+ return unless checksums
320
+
321
+ checksums.split(",") do |lock_checksum|
322
+ column = line.index(lock_checksum) + 1
323
+ checksum = Checksum.from_lock(lock_checksum, "#{@lockfile_path}:#{@pos.line}:#{column}")
324
+ spec.source.checksum_store.register(spec, checksum)
287
325
  end
288
326
  end
289
327
 
@@ -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" "April 2026" ""
3
+ .TH "BUNDLE\-ADD" "1" "May 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
6
6
  .SH "SYNOPSIS"
@@ -46,13 +46,16 @@ Do not print progress information to the standard output\.
46
46
  Adds the gem to the Gemfile but does not install it\.
47
47
  .TP
48
48
  \fB\-\-optimistic\fR
49
- Adds optimistic declaration of version\.
49
+ Ignored (now default behavior)
50
+ .TP
51
+ \fB\-\-pessimistic\fR
52
+ Adds pessimistic declaration of version\.
50
53
  .TP
51
54
  \fB\-\-strict\fR
52
55
  Adds strict declaration of version\.
53
56
  .TP
54
57
  \fB\-\-cooldown=<number>\fR
55
- Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
58
+ Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding every other cooldown setting, RubyGems' own included\. See \fBcooldown\fR in bundle\-config(1) for precedence rules\.
56
59
  .SH "EXAMPLES"
57
60
  .IP "1." 4
58
61
  You can add the \fBrails\fR gem to the Gemfile without any version restriction\. The source of the gem will be the global source\.
@@ -65,7 +68,7 @@ You can add the \fBrails\fR gem with version greater than 1\.1 (not including 1\
65
68
  .IP "3." 4
66
69
  You can use the \fBhttps://gems\.example\.com\fR custom source and assign the gem to a group\.
67
70
  .IP
68
- \fBbundle add rails \-\-version "~> 5\.0\.0" \-\-source "https://gems\.example\.com" \-\-group "development"\fR
71
+ \fBbundle add rails \-\-version ">= 5\.0\.0" \-\-source "https://gems\.example\.com" \-\-group "development"\fR
69
72
  .IP "4." 4
70
73
  The following adds the \fBgem\fR entry to the Gemfile without installing the gem\. You can install gems later via \fBbundle install\fR\.
71
74
  .IP
@@ -51,15 +51,19 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.
51
51
  Adds the gem to the Gemfile but does not install it.
52
52
 
53
53
  * `--optimistic`:
54
- Adds optimistic declaration of version.
54
+ Ignored (now default behavior)
55
+
56
+ * `--pessimistic`:
57
+ Adds pessimistic declaration of version.
55
58
 
56
59
  * `--strict`:
57
60
  Adds strict declaration of version.
58
61
 
59
62
  * `--cooldown=<number>`:
60
63
  Only consider gem versions published at least <number> days ago when
61
- resolving. Pass `0` to disable cooldown for this run. See `cooldown`
62
- in bundle-config(1) for precedence rules.
64
+ resolving. Pass `0` to disable cooldown for this run, overriding every
65
+ other cooldown setting, RubyGems' own included. See `cooldown` in
66
+ bundle-config(1) for precedence rules.
63
67
 
64
68
  ## EXAMPLES
65
69
 
@@ -75,7 +79,7 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.
75
79
  3. You can use the `https://gems.example.com` custom source and assign the gem
76
80
  to a group.
77
81
 
78
- `bundle add rails --version "~> 5.0.0" --source "https://gems.example.com" --group "development"`
82
+ `bundle add rails --version ">= 5.0.0" --source "https://gems.example.com" --group "development"`
79
83
 
80
84
  4. The following adds the `gem` entry to the Gemfile without installing the
81
85
  gem. You can install gems later via `bundle install`.
@@ -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" "April 2026" ""
3
+ .TH "BUNDLE\-BINSTUBS" "1" "May 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" "April 2026" ""
3
+ .TH "BUNDLE\-CACHE" "1" "May 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
6
6
  .SH "SYNOPSIS"
@@ -18,7 +18,7 @@ Include gems for all platforms present in the lockfile, not only the current one
18
18
  Specify a different cache path than the default (vendor/cache)\.
19
19
  .TP
20
20
  \fB\-\-cooldown=<number>\fR
21
- Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. See \fBcooldown\fR in bundle\-config(1)\.
21
+ Only consider gem versions published at least \fInumber\fR days ago when resolving before caching\. Pass \fB0\fR to disable cooldown for this run, overriding every other cooldown setting, RubyGems' own included\. See \fBcooldown\fR in bundle\-config(1)\.
22
22
  .TP
23
23
  \fB\-\-gemfile=GEMFILE\fR
24
24
  Use the specified gemfile instead of Gemfile\.
@@ -24,8 +24,8 @@ use the gems in the cache in preference to the ones on `rubygems.org`.
24
24
  * `--cooldown=<number>`:
25
25
  Only consider gem versions published at least <number> days ago when
26
26
  resolving before caching. Pass `0` to disable cooldown for this run,
27
- overriding any per-source or global configuration. See `cooldown` in
28
- bundle-config(1).
27
+ overriding every other cooldown setting, RubyGems' own included. See
28
+ `cooldown` in bundle-config(1).
29
29
 
30
30
  * `--gemfile=GEMFILE`:
31
31
  Use the specified gemfile instead of Gemfile.
@@ -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" "April 2026" ""
3
+ .TH "BUNDLE\-CHECK" "1" "May 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" "April 2026" ""
3
+ .TH "BUNDLE\-CLEAN" "1" "May 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" "April 2026" ""
3
+ .TH "BUNDLE\-CONFIG" "1" "May 2026" ""
4
4
  .SH "NAME"
5
5
  \fBbundle\-config\fR \- Set bundler configuration options
6
6
  .SH "SYNOPSIS"
@@ -70,7 +70,7 @@ 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
  .IP "\(bu" 4
73
- \fBapi_request_size\fR (\fBBUNDLE_API_REQUEST_SIZE\fR): 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\.
73
+ \fBapi_request_size\fR (\fBBUNDLE_API_REQUEST_SIZE\fR): Configure how many dependencies to fetch when resolving the specifications\. This configuration is only used when fetching specifications from RubyGems servers that didn't implement the Compact Index API\. Defaults to 100\.
74
74
  .IP "\(bu" 4
75
75
  \fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR): Automatically run \fBbundle install\fR when gems are missing\.
76
76
  .IP "\(bu" 4
@@ -90,16 +90,34 @@ The following is a list of all configuration keys and their purpose\. You can le
90
90
  .IP
91
91
  The effective cooldown for any given gem is resolved from three layers, highest precedence first:
92
92
  .IP "1." 4
93
- CLI flag \fB\-\-cooldown N\fR on \fBinstall\fR, \fBupdate\fR, \fBadd\fR, and \fBoutdated\fR\.
93
+ CLI flag \fB\-\-cooldown N\fR on \fBinstall\fR, \fBupdate\fR, \fBadd\fR, \fBcache\fR, \fBlock\fR, and \fBoutdated\fR\.
94
94
  .IP "2." 4
95
95
  This setting (\fBbundle config set cooldown N\fR or \fBBUNDLE_COOLDOWN=N\fR)\.
96
96
  .IP "3." 4
97
97
  The per\-source \fBcooldown:\fR keyword in the Gemfile, such as \fBsource "https://rubygems\.org", cooldown: 7\fR\.
98
98
  .IP "" 0
99
99
  .IP
100
- The CLI flag and this setting apply uniformly to every source, including ones declared with their own \fBcooldown:\fR value\. To keep a private registry permanently exempt while still cooling down public gems, declare \fBsource "https://internal", cooldown: 0\fR in the Gemfile; remember that \fB\-\-cooldown N\fR on the command line will still override it for that single run\.
100
+ The CLI flag and this setting apply uniformly to every source, including ones declared with their own \fBcooldown:\fR value\. To exempt a private registry while still cooling down public gems, declare \fBsource "https://internal", cooldown: 0\fR in the Gemfile\. That exemption is not absolute\. \fB\-\-cooldown N\fR on the command line overrides it for a single run, and a gemrc cooldown raises it the same way it raises any other layer, as described below\. Where a gemrc cooldown is configured, \fB\-\-cooldown 0\fR is the only way to get the exemption back\.
101
+ .IP
102
+ RubyGems has a cooldown of its own, set with \fBgem\fR's \fB\-\-cooldown\fR flag or the \fB:cooldown:\fR key in the gemrc file, and the two are read together\. Whatever the three layers above resolve to is raised to the gemrc value, and the longer of the two wins\. It carries the other way round as well\. \fBgem install\fR, \fBgem update\fR and \fBgem outdated\fR read this setting and \fBBUNDLE_COOLDOWN\fR, so a cooldown configured for either tool covers both\. The Gemfile per\-source \fBcooldown:\fR is the exception, since \fBgem\fR never reads a Gemfile\. A configured \fB0\fR takes part like any other value rather than switching the cooldown off, so \fBbundle config set cooldown 0\fR does not cancel a gemrc cooldown\. The \fB\-\-cooldown\fR flag is what bypasses the other tool's setting\. It wins outright, which is why \fB\-\-cooldown 0\fR remains the escape hatch for an urgent update\.
103
+ .IP
104
+ The value must be a non\-negative integer\. \fB\-\-cooldown\fR rejects anything else outright, while a value coming from this setting, from \fBBUNDLE_COOLDOWN\fR or from the gemrc file only warns, because a typo left in a config file should not make every command fail\. Such a value takes no part in the resolution above, so a per\-source \fBcooldown:\fR in the Gemfile, or a usable value configured for the other tool, still applies\. The warning names where the value came from, since either tool reports the other's setting as well as its own\.
101
105
  .IP
102
106
  Cooldown filtering depends on the gem server providing a per\-version \fBcreated_at\fR timestamp in the v2 compact\-index format\. Versions without that metadata \- older gem servers, historical entries that predate the v2 cutover on \fBrubygems\.org\fR, or private registries that still emit the v1 format \- are treated as outside the cooldown window and remain resolvable\. If you rely on cooldown for supply\-chain protection, confirm that the gem server emits \fBcreated_at\fR in its \fB/info/<gem>\fR responses\.
107
+ .IP
108
+ A \fBcreated_at\fR timestamp is read as UTC when it carries no time zone offset\. \fBrubygems\.org\fR always sends one, but a third\-party server that omits it would otherwise shift the cooldown window by the offset of whatever machine runs bundler\.
109
+ .IP "\(bu" 4
110
+ \fBcredential_store\fR (\fBBUNDLE_CREDENTIAL_STORE\fR): Experimental: store and read host credentials (the values otherwise set via \fBbundle config set <host> <user:pass>\fR) in a credential store instead of the plain text config file\. Set it to \fBtrue\fR to use the operating system's native store (macOS Keychain, Linux Secret Service, Windows Credential Manager) when one is available on this platform, or to the name of a backend provided by a third\-party gem, such as \fB1password\fR\. Falls back to the config file when the store is unavailable or fails, warning that the credential was written in plain text\. Defaults to false\. Credentials already written to the config file are not migrated automatically; re\-run \fBbundle config set <host> <user:pass>\fR with the setting enabled to move each one into the store\. Being experimental, the name and behavior of this setting may change in a future release\.
111
+ .IP
112
+ The value is read in three ways\. An empty value and the false values Bundler takes everywhere else (\fBfalse\fR, \fBf\fR, \fBno\fR, \fBn\fR, \fB0\fR) turn the store off\. \fBtrue\fR, \fBt\fR, \fByes\fR, \fBy\fR, \fBon\fR and \fB1\fR select the native store\. Case does not matter for any of those\. Anything else is a backend name, taken as written, and only lowercase letters, digits, \fB_\fR and \fB\-\fR are recognized in one\. So \fBoff\fR names a backend rather than turning the store off, which \fBfalse\fR does\.
113
+ .IP
114
+ A credential kept in the store is never printed back\. \fBbundle config get <host>\fR and \fBbundle config list\fR name the key and say that its value lives in the credential store\. With \fB\-\-parseable\fR, such a key is left out entirely, since that output is meant to be read back by \fBbundle config set\fR\. A third\-party backend is not required to enumerate what it holds, so a credential kept in one may not be listed at all\.
115
+ .IP
116
+ The store belongs to the machine's user, not to a project, so \fB\-\-local\fR and \fB\-\-global\fR make no difference to where a credential is kept\. Setting a host's credential in one project changes it for every project on the machine, and unsetting it there removes it everywhere\. Protecting the store itself is the operating system's job, or that of whichever backend you selected\.
117
+ .IP
118
+ A credential given in the environment, such as \fBBUNDLE_GEMS__EXAMPLE__COM\fR, takes precedence over the stored one, so a CI run can pass its own credentials without the store getting in the way\. The store takes precedence over the config file\.
119
+ .IP
120
+ The store can also be selected per host with \fBcredential_store\.<host>\fR (\fBBUNDLE_CREDENTIAL_STORE__<HOST>\fR), for example \fBbundle config set credential_store\.gems\.example\.com code_artifact\fR\. That host then uses only the named backend, with no chaining to the global one, while every other host keeps following the global setting\. Setting a host's value to \fBfalse\fR keeps that one host on the config file even when a global store is enabled\.
103
121
  .IP "\(bu" 4
104
122
  \fBdefault_cli_command\fR (\fBBUNDLE_DEFAULT_CLI_COMMAND\fR): The command that running \fBbundle\fR without arguments should run\. Defaults to \fBcli_help\fR since Bundler 4, but can also be \fBinstall\fR which was the previous default\.
105
123
  .IP "\(bu" 4
@@ -137,13 +155,19 @@ Cooldown filtering depends on the gem server providing a per\-version \fBcreated
137
155
  .IP "\(bu" 4
138
156
  \fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can download and install in parallel\. Defaults to the number of available processors\.
139
157
  .IP "\(bu" 4
158
+ \fBkeep_outdated_cache\fR (\fBBUNDLE_KEEP_OUTDATED_CACHE\fR): Whether Bundler should leave outdated gems unpruned when caching\. Defaults to false\.
159
+ .IP "\(bu" 4
140
160
  \fBlockfile\fR (\fBBUNDLE_LOCKFILE\fR): The path to the lockfile that bundler should use\. By default, Bundler adds \fB\.lock\fR to the end of the \fBgemfile\fR entry\. Can be set to \fBfalse\fR in the Gemfile to disable lockfile creation entirely (see gemfile(5))\.
141
161
  .IP "\(bu" 4
142
162
  \fBlockfile_checksums\fR (\fBBUNDLE_LOCKFILE_CHECKSUMS\fR): Whether Bundler should include a checksums section in new lockfiles, to protect from compromised gem sources\. Defaults to true\. Bundler's own checksum is only included when its \fB\.gem\fR file is cached, which may not be the case when Bundler is installed as a default gem\.
143
163
  .IP "\(bu" 4
164
+ \fBno_build_extension\fR (\fBBUNDLE_NO_BUILD_EXTENSION\fR): Whether Bundler should skip building native extensions during installation\. When set, gems are installed without compiling their C extensions\. To build extensions later, unset this setting and run \fBbundle pristine <gem>\fR\.
165
+ .IP "\(bu" 4
144
166
  \fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\.
145
167
  .IP "\(bu" 4
146
- \fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\.
168
+ \fBno_install_plugin\fR (\fBBUNDLE_NO_INSTALL_PLUGIN\fR): Whether Bundler should skip installing RubyGems plugins during installation\. When set, plugin files are not written to the plugins directory\. To install plugins later, unset this setting and run \fBbundle pristine <gem>\fR\.
169
+ .IP "\(bu" 4
170
+ \fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Deprecated name for \fBkeep_outdated_cache\fR\. Each priority level is checked for \fBkeep_outdated_cache\fR and then for \fBno_prune\fR, and the first value found wins\. \fBno_prune\fR will be removed in Bundler 5\.
147
171
  .IP "\(bu" 4
148
172
  \fBonly\fR (\fBBUNDLE_ONLY\fR): A space\-separated list of groups to install only gems of the specified groups\. Please check carefully if you want to install also gems without a group, because they get put inside \fBdefault\fR group\. For example \fBonly test:default\fR will install all gems specified in test group and without one\.
149
173
  .IP "\(bu" 4
@@ -155,6 +179,8 @@ Cooldown filtering depends on the gem server providing a per\-version \fBcreated
155
179
  .IP "\(bu" 4
156
180
  \fBprefer_patch\fR (\fBBUNDLE_PREFER_PATCH\fR): Prefer updating only to next patch version during updates\. Makes \fBbundle update\fR calls equivalent to \fBbundler update \-\-patch\fR\.
157
181
  .IP "\(bu" 4
182
+ \fBprune\fR (\fBBUNDLE_PRUNE\fR): A space\-separated or \fB:\fR\-separated list of Bundler\-managed artifacts to delete after a successful \fBbundle install\fR, \fBbundle update\fR or \fBbundle cache\fR, and on \fBbundle clean\fR\. \fBcache\fR removes the download cache under the bundle path, which holds both the cached \fB\.gem\fR files and the git mirrors\. \fBgit\fR removes the \fB\.git\fR directory of every checked out git gem\. Any value that is not a category name is read as a boolean, so \fBBUNDLE_PRUNE=1\fR selects every category and keeps doing so as categories are added\. This is meant for container images and other throwaway environments\. \fBThe setting only takes effect when a bundle path is set\.\fR Without one Bundler installs into the system gem directory, where the cache is shared with RubyGems and holds gem files Bundler never put there, so pruning is skipped with a warning\. Set a path with \fBBUNDLE_PATH\fR or \fBbundle config set path <dir>\fR\. A pruned artifact comes back only when Bundler has to install that gem again, so a later \fBbundle install\fR does not restore it on its own\. \fBbundle install \-\-redownload\fR does, and \fBbundle pristine\fR works once it has, though with \fBprune\fR still set the reinstall prunes again at the end\.
183
+ .IP "\(bu" 4
158
184
  \fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\.
159
185
  .IP "\(bu" 4
160
186
  \fBretry\fR (\fBBUNDLE_RETRY\fR): The number of times to retry failed network requests\. Defaults to \fB3\fR\.
@@ -175,7 +201,7 @@ Cooldown filtering depends on the gem server providing a per\-version \fBcreated
175
201
  .IP "\(bu" 4
176
202
  \fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\.
177
203
  .IP "\(bu" 4
178
- \fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\.
204
+ \fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests, applied to each request individually\. A network operation retried by Bundler may wait a multiple of this value in total\. Defaults to \fB10\fR\.
179
205
  .IP "\(bu" 4
180
206
  \fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
181
207
  .IP "\(bu" 4
@@ -326,6 +352,12 @@ Any \fB\.\fR characters in a host name are mapped to a double underscore (\fB__\
326
352
  .IP "" 0
327
353
  .P
328
354
  This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you'll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\.
355
+ .SH "PROXY SUPPORT"
356
+ Bundler reads the proxy for a gem source from the \fB:http_proxy\fR key in the RubyGems configuration file (\fB~/\.gemrc\fR), falling back to the environment\. For an \fBhttps\fR source, \fBhttps_proxy\fR (or \fBHTTPS_PROXY\fR) takes precedence over \fBhttp_proxy\fR (or \fBHTTP_PROXY\fR), which is only used when no https\-specific proxy is set\. Proxy credentials that are not embedded in the proxy URL are read from \fBHTTP_PROXY_USER\fR and \fBHTTP_PROXY_PASS\fR, or from \fBHTTPS_PROXY_USER\fR and \fBHTTPS_PROXY_PASS\fR when the https proxy is used\.
357
+ .P
358
+ Setting \fB:http_proxy: :no_proxy\fR in the RubyGems configuration file disables proxies entirely, including any proxy environment variables\. To keep using a proxy from the environment, remove that line\. To configure a proxy in the file, replace \fB:no_proxy\fR with an explicit proxy URL\.
359
+ .P
360
+ The \fBNO_PROXY\fR (or \fBno_proxy\fR) environment variable lists hosts that are reached directly, bypassing the proxy\. An entry matches the host itself and its subdomains, so \fBNO_PROXY=example\.com\fR bypasses both \fBexample\.com\fR and \fBsub\.example\.com\fR, but not \fBmyexample\.com\fR\. An entry starting with a dot matches only subdomains\. A value of \fB*\fR bypasses the proxy for every host\.
329
361
  .SH "CONFIGURE BUNDLER DIRECTORIES"
330
362
  Bundler's home, cache and plugin directories and config file can be configured through environment variables\. The default location for Bundler's home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values
331
363
  .IP "" 4