bundler 4.0.12 → 4.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/bundler/build_metadata.rb +1 -1
- data/lib/bundler/cli/add.rb +3 -0
- data/lib/bundler/cli/common.rb +6 -0
- data/lib/bundler/cli/install.rb +3 -0
- data/lib/bundler/cli/outdated.rb +42 -2
- data/lib/bundler/cli/update.rb +2 -0
- data/lib/bundler/cli.rb +4 -0
- data/lib/bundler/dsl.rb +6 -2
- data/lib/bundler/endpoint_specification.rb +11 -1
- data/lib/bundler/installer.rb +5 -0
- data/lib/bundler/man/bundle-add.1 +4 -1
- data/lib/bundler/man/bundle-add.1.ronn +6 -1
- data/lib/bundler/man/bundle-config.1 +120 -156
- data/lib/bundler/man/bundle-config.1.ronn +30 -0
- data/lib/bundler/man/bundle-install.1 +4 -1
- data/lib/bundler/man/bundle-install.1.ronn +9 -1
- data/lib/bundler/man/bundle-outdated.1 +16 -13
- data/lib/bundler/man/bundle-outdated.1.ronn +19 -12
- data/lib/bundler/man/bundle-update.1 +4 -1
- data/lib/bundler/man/bundle-update.1.ronn +8 -0
- data/lib/bundler/remote_specification.rb +1 -1
- data/lib/bundler/resolver.rb +42 -1
- data/lib/bundler/rubygems_ext.rb +22 -0
- data/lib/bundler/rubygems_gem_installer.rb +1 -1
- data/lib/bundler/settings.rb +1 -0
- data/lib/bundler/source/git/git_proxy.rb +7 -2
- data/lib/bundler/source/rubygems/remote.rb +12 -2
- data/lib/bundler/source/rubygems.rb +51 -3
- data/lib/bundler/source_list.rb +6 -2
- data/lib/bundler/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6aecb16228f32866a007c26b7a70fd787bcf81d42ee002004ba3ec2dd2625694
|
|
4
|
+
data.tar.gz: 5bce03c60cbf8034dfc540848298fbe3d8958314dc8513b61c0e8238f180f096
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4500a906181c0c43b1384fd9dda403dcc00ec11466911c156b01b309f2886336e756057af742396786ad2a0111e1a650729ad7bc03d09d04b0984a3770d4ebf4
|
|
7
|
+
data.tar.gz: 11e96f5ebdeca17df80db3506f010fd190b35c12cc8fd82532f6eeea9b51aa7b113a353c1cf88df215846c0226696a672813a79bf06202a3e5ffd7b543b0805a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.13 / 2026-06-03
|
|
4
|
+
|
|
5
|
+
### Enhancements:
|
|
6
|
+
|
|
7
|
+
* Do not hard-code permissions for new gem directories during bundle install. Pull request [#9557](https://github.com/ruby/rubygems/pull/9557) by maxfelsher-cgi
|
|
8
|
+
* Clear gem specification cache after acquiring process lock. Pull request [#9310](https://github.com/ruby/rubygems/pull/9310) by ngan
|
|
9
|
+
* Show release date with bundle outdated. Pull request [#9337](https://github.com/ruby/rubygems/pull/9337) by hsbt
|
|
10
|
+
|
|
11
|
+
### Bug fixes:
|
|
12
|
+
|
|
13
|
+
* Apply cooldown to locally installed gem versions. Pull request [#9582](https://github.com/ruby/rubygems/pull/9582) by hsbt
|
|
14
|
+
|
|
15
|
+
### Security:
|
|
16
|
+
|
|
17
|
+
* Add `cooldown` to delay newly published gem. Pull request [#9576](https://github.com/ruby/rubygems/pull/9576) by hsbt
|
|
18
|
+
|
|
3
19
|
## 4.0.12 / 2026-05-20
|
|
4
20
|
|
|
5
21
|
### Enhancements:
|
data/lib/bundler/cli/add.rb
CHANGED
|
@@ -14,6 +14,9 @@ module Bundler
|
|
|
14
14
|
def run
|
|
15
15
|
Bundler.ui.level = "warn" if options[:quiet]
|
|
16
16
|
|
|
17
|
+
Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
|
|
18
|
+
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
|
|
19
|
+
|
|
17
20
|
validate_options!
|
|
18
21
|
inject_dependencies
|
|
19
22
|
perform_bundle_install unless options["skip-install"]
|
data/lib/bundler/cli/common.rb
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module Bundler
|
|
4
4
|
module CLI::Common
|
|
5
|
+
def self.validate_cooldown!(value)
|
|
6
|
+
return if value.nil?
|
|
7
|
+
return if value.is_a?(Integer) && value >= 0
|
|
8
|
+
raise InvalidOption, "Expected `--cooldown` to be a non-negative integer, got #{value.inspect}"
|
|
9
|
+
end
|
|
10
|
+
|
|
5
11
|
def self.output_post_install_messages(messages)
|
|
6
12
|
return if Bundler.settings["ignore_messages"]
|
|
7
13
|
messages.to_a.each do |name, msg|
|
data/lib/bundler/cli/install.rb
CHANGED
|
@@ -112,6 +112,9 @@ module Bundler
|
|
|
112
112
|
|
|
113
113
|
Bundler.settings.set_command_option_if_given :jobs, options["jobs"]
|
|
114
114
|
|
|
115
|
+
Bundler::CLI::Common.validate_cooldown!(options["cooldown"])
|
|
116
|
+
Bundler.settings.set_command_option_if_given :cooldown, options["cooldown"]
|
|
117
|
+
|
|
115
118
|
Bundler.settings.set_command_option_if_given :no_prune, options["no-prune"]
|
|
116
119
|
|
|
117
120
|
Bundler.settings.set_command_option_if_given :no_install, options["no-install"]
|
data/lib/bundler/cli/outdated.rb
CHANGED
|
@@ -26,6 +26,9 @@ module Bundler
|
|
|
26
26
|
def run
|
|
27
27
|
check_for_deployment_mode!
|
|
28
28
|
|
|
29
|
+
Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
|
|
30
|
+
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
|
|
31
|
+
|
|
29
32
|
Bundler.definition.validate_runtime!
|
|
30
33
|
current_specs = Bundler.ui.silence { Bundler.definition.resolve }
|
|
31
34
|
|
|
@@ -199,7 +202,15 @@ module Bundler
|
|
|
199
202
|
end
|
|
200
203
|
|
|
201
204
|
spec_outdated_info = "#{active_spec.name} (newest #{spec_version}, " \
|
|
202
|
-
"installed #{current_version}#{dependency_version}
|
|
205
|
+
"installed #{current_version}#{dependency_version}"
|
|
206
|
+
|
|
207
|
+
release_date = release_date_for(active_spec)
|
|
208
|
+
spec_outdated_info += ", released #{release_date}" unless release_date.empty?
|
|
209
|
+
|
|
210
|
+
remaining = cooldown_days_remaining(active_spec)
|
|
211
|
+
spec_outdated_info += ", in cooldown for #{remaining} more day#{"s" if remaining > 1}" if remaining
|
|
212
|
+
|
|
213
|
+
spec_outdated_info += ")"
|
|
203
214
|
|
|
204
215
|
output_message = if options[:parseable]
|
|
205
216
|
spec_outdated_info.to_s
|
|
@@ -215,13 +226,25 @@ module Bundler
|
|
|
215
226
|
def gem_column_for(current_spec, active_spec, dependency, groups)
|
|
216
227
|
current_version = "#{current_spec.version}#{current_spec.git_version}"
|
|
217
228
|
spec_version = "#{active_spec.version}#{active_spec.git_version}"
|
|
229
|
+
remaining = cooldown_days_remaining(active_spec)
|
|
230
|
+
spec_version += " (cooldown #{remaining}d)" if remaining
|
|
218
231
|
dependency = dependency.requirement if dependency
|
|
219
232
|
|
|
220
233
|
ret_val = [active_spec.name, current_version, spec_version, dependency.to_s, groups.to_s]
|
|
234
|
+
ret_val << release_date_for(active_spec)
|
|
221
235
|
ret_val << loaded_from_for(active_spec).to_s if Bundler.ui.debug?
|
|
222
236
|
ret_val
|
|
223
237
|
end
|
|
224
238
|
|
|
239
|
+
def cooldown_days_remaining(spec, now = Time.now)
|
|
240
|
+
return nil unless spec.respond_to?(:created_at) && spec.created_at
|
|
241
|
+
return nil unless spec.respond_to?(:remote) && spec.remote
|
|
242
|
+
days = spec.remote.effective_cooldown
|
|
243
|
+
return nil if days.nil? || days <= 0
|
|
244
|
+
remaining = days - ((now - spec.created_at) / 86_400.0)
|
|
245
|
+
remaining > 0 ? remaining.ceil : nil
|
|
246
|
+
end
|
|
247
|
+
|
|
225
248
|
def check_for_deployment_mode!
|
|
226
249
|
return unless Bundler.frozen_bundle?
|
|
227
250
|
suggested_command = if Bundler.settings.locations("frozen").keys.&([:global, :local]).any?
|
|
@@ -283,11 +306,28 @@ module Bundler
|
|
|
283
306
|
end
|
|
284
307
|
|
|
285
308
|
def table_header
|
|
286
|
-
header = ["Gem", "Current", "Latest", "Requested", "Groups"]
|
|
309
|
+
header = ["Gem", "Current", "Latest", "Requested", "Groups", "Release Date"]
|
|
287
310
|
header << "Path" if Bundler.ui.debug?
|
|
288
311
|
header
|
|
289
312
|
end
|
|
290
313
|
|
|
314
|
+
def release_date_for(spec)
|
|
315
|
+
return "" unless spec.respond_to?(:date)
|
|
316
|
+
|
|
317
|
+
date = spec.date
|
|
318
|
+
return "" unless date
|
|
319
|
+
|
|
320
|
+
return "" unless Gem.const_defined?(:DEFAULT_SOURCE_DATE_EPOCH)
|
|
321
|
+
default_date = Time.at(Gem::DEFAULT_SOURCE_DATE_EPOCH).utc
|
|
322
|
+
default_date = Time.utc(default_date.year, default_date.month, default_date.day)
|
|
323
|
+
|
|
324
|
+
date = date.utc if date.respond_to?(:utc)
|
|
325
|
+
|
|
326
|
+
return "" if date == default_date
|
|
327
|
+
|
|
328
|
+
date.strftime("%Y-%m-%d")
|
|
329
|
+
end
|
|
330
|
+
|
|
291
331
|
def justify(row, sizes)
|
|
292
332
|
row.each_with_index.map do |element, index|
|
|
293
333
|
element.ljust(sizes[index])
|
data/lib/bundler/cli/update.rb
CHANGED
|
@@ -66,6 +66,8 @@ module Bundler
|
|
|
66
66
|
opts["force"] = options[:redownload] if options[:redownload]
|
|
67
67
|
|
|
68
68
|
Bundler.settings.set_command_option_if_given :jobs, opts["jobs"]
|
|
69
|
+
Bundler::CLI::Common.validate_cooldown!(options[:cooldown])
|
|
70
|
+
Bundler.settings.set_command_option_if_given :cooldown, options[:cooldown]
|
|
69
71
|
|
|
70
72
|
Bundler.definition.validate_runtime!
|
|
71
73
|
|
data/lib/bundler/cli.rb
CHANGED
|
@@ -274,6 +274,7 @@ module Bundler
|
|
|
274
274
|
method_option "target-rbconfig", type: :string, banner: "Path to rbconfig.rb for the deployment target platform"
|
|
275
275
|
method_option "without", type: :array, banner: "Exclude gems that are part of the specified named group (removed)."
|
|
276
276
|
method_option "with", type: :array, banner: "Include gems that are part of the specified named group (removed)."
|
|
277
|
+
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
|
|
277
278
|
def install
|
|
278
279
|
%w[clean deployment frozen no-prune path shebang without with].each do |option|
|
|
279
280
|
remembered_flag_deprecation(option)
|
|
@@ -324,6 +325,7 @@ module Bundler
|
|
|
324
325
|
method_option "strict", type: :boolean, banner: "Do not allow any gem to be updated past latest --patch | --minor | --major"
|
|
325
326
|
method_option "conservative", type: :boolean, banner: "Use bundle install conservative update behavior and do not allow shared dependencies to be updated."
|
|
326
327
|
method_option "all", type: :boolean, banner: "Update everything."
|
|
328
|
+
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
|
|
327
329
|
def update(*gems)
|
|
328
330
|
require_relative "cli/update"
|
|
329
331
|
Bundler.settings.temporary(no_install: false) do
|
|
@@ -405,6 +407,7 @@ module Bundler
|
|
|
405
407
|
method_option "skip-install", type: :boolean, banner: "Adds gem to the Gemfile but does not install it"
|
|
406
408
|
method_option "optimistic", type: :boolean, banner: "Adds optimistic declaration of version to gem"
|
|
407
409
|
method_option "strict", type: :boolean, banner: "Adds strict declaration of version to gem"
|
|
410
|
+
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
|
|
408
411
|
def add(*gems)
|
|
409
412
|
require_relative "cli/add"
|
|
410
413
|
Add.new(options.dup, gems).run
|
|
@@ -435,6 +438,7 @@ module Bundler
|
|
|
435
438
|
method_option "filter-patch", type: :boolean, banner: "Only list patch newer versions"
|
|
436
439
|
method_option "parseable", aliases: "--porcelain", type: :boolean, banner: "Use minimal formatting for more parseable output"
|
|
437
440
|
method_option "only-explicit", type: :boolean, banner: "Only list gems specified in your Gemfile, not their dependencies"
|
|
441
|
+
method_option "cooldown", type: :numeric, banner: "Only consider gem versions published at least N days ago. Use 0 to disable."
|
|
438
442
|
def outdated(*gems)
|
|
439
443
|
require_relative "cli/outdated"
|
|
440
444
|
Outdated.new(options, gems).run
|
data/lib/bundler/dsl.rb
CHANGED
|
@@ -116,6 +116,10 @@ module Bundler
|
|
|
116
116
|
options = args.last.is_a?(Hash) ? args.pop.dup : {}
|
|
117
117
|
options = normalize_hash(options)
|
|
118
118
|
source = normalize_source(source)
|
|
119
|
+
cooldown = options["cooldown"]
|
|
120
|
+
if cooldown && !(cooldown.is_a?(Integer) && cooldown >= 0)
|
|
121
|
+
raise InvalidOption, "Expected `cooldown` to be a non-negative integer, got #{cooldown.inspect}"
|
|
122
|
+
end
|
|
119
123
|
|
|
120
124
|
if options.key?("type")
|
|
121
125
|
options["type"] = options["type"].to_s
|
|
@@ -130,9 +134,9 @@ module Bundler
|
|
|
130
134
|
source_opts = options.merge("uri" => source)
|
|
131
135
|
with_source(@sources.add_plugin_source(options["type"], source_opts), &blk)
|
|
132
136
|
elsif block_given?
|
|
133
|
-
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
|
|
137
|
+
with_source(@sources.add_rubygems_source("remotes" => source, "cooldown" => cooldown), &blk)
|
|
134
138
|
else
|
|
135
|
-
@sources.add_global_rubygems_remote(source)
|
|
139
|
+
@sources.add_global_rubygems_remote(source, cooldown: cooldown)
|
|
136
140
|
end
|
|
137
141
|
end
|
|
138
142
|
|
|
@@ -5,7 +5,7 @@ module Bundler
|
|
|
5
5
|
class EndpointSpecification < Gem::Specification
|
|
6
6
|
include MatchRemoteMetadata
|
|
7
7
|
|
|
8
|
-
attr_reader :name, :version, :platform, :checksum
|
|
8
|
+
attr_reader :name, :version, :platform, :checksum, :created_at
|
|
9
9
|
attr_writer :dependencies
|
|
10
10
|
attr_accessor :remote, :locked_platform
|
|
11
11
|
|
|
@@ -145,6 +145,7 @@ module Bundler
|
|
|
145
145
|
unless data
|
|
146
146
|
@required_ruby_version = nil
|
|
147
147
|
@required_rubygems_version = nil
|
|
148
|
+
@created_at = nil
|
|
148
149
|
return
|
|
149
150
|
end
|
|
150
151
|
|
|
@@ -161,6 +162,15 @@ module Bundler
|
|
|
161
162
|
@required_rubygems_version = Gem::Requirement.new(v)
|
|
162
163
|
when "ruby"
|
|
163
164
|
@required_ruby_version = Gem::Requirement.new(v)
|
|
165
|
+
when "created_at"
|
|
166
|
+
value = v.is_a?(Array) ? v.last : v
|
|
167
|
+
if value.is_a?(String)
|
|
168
|
+
@created_at = begin
|
|
169
|
+
Time.new(value)
|
|
170
|
+
rescue ArgumentError
|
|
171
|
+
nil
|
|
172
|
+
end
|
|
173
|
+
end
|
|
164
174
|
end
|
|
165
175
|
end
|
|
166
176
|
rescue StandardError => e
|
data/lib/bundler/installer.rb
CHANGED
|
@@ -63,6 +63,11 @@ module Bundler
|
|
|
63
63
|
Bundler.create_bundle_path
|
|
64
64
|
|
|
65
65
|
ProcessLock.lock do
|
|
66
|
+
# Invalidate any stale gem specification cache from before we acquired the lock.
|
|
67
|
+
# Another process may have installed gems while we were waiting.
|
|
68
|
+
Gem::Specification.reset
|
|
69
|
+
@definition.sources.clear_cache
|
|
70
|
+
|
|
66
71
|
@definition.ensure_equivalent_gemfile_and_lockfile(options[:deployment])
|
|
67
72
|
|
|
68
73
|
if @definition.dependencies.empty?
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
|
|
6
6
|
.SH "SYNOPSIS"
|
|
7
|
-
\fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-path=PATH] [\-\-git=GIT|\-\-github=GITHUB] [\-\-branch=BRANCH] [\-\-ref=REF] [\-\-quiet] [\-\-skip\-install] [\-\-strict|\-\-optimistic]
|
|
7
|
+
\fBbundle add\fR \fIGEM_NAME\fR [\-\-group=GROUP] [\-\-version=VERSION] [\-\-source=SOURCE] [\-\-path=PATH] [\-\-git=GIT|\-\-github=GITHUB] [\-\-branch=BRANCH] [\-\-ref=REF] [\-\-cooldown=NUMBER] [\-\-quiet] [\-\-skip\-install] [\-\-strict|\-\-optimistic]
|
|
8
8
|
.SH "DESCRIPTION"
|
|
9
9
|
Adds the named gem to the [\fBGemfile(5)\fR][Gemfile(5)] and run \fBbundle install\fR\. \fBbundle install\fR can be avoided by using the flag \fB\-\-skip\-install\fR\.
|
|
10
10
|
.SH "OPTIONS"
|
|
@@ -50,6 +50,9 @@ Adds optimistic declaration of version\.
|
|
|
50
50
|
.TP
|
|
51
51
|
\fB\-\-strict\fR
|
|
52
52
|
Adds strict declaration of version\.
|
|
53
|
+
.TP
|
|
54
|
+
\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\.
|
|
53
56
|
.SH "EXAMPLES"
|
|
54
57
|
.IP "1." 4
|
|
55
58
|
You can add the \fBrails\fR gem to the Gemfile without any version restriction\. The source of the gem will be the global source\.
|
|
@@ -5,7 +5,7 @@ bundle-add(1) -- Add gem to the Gemfile and run bundle install
|
|
|
5
5
|
|
|
6
6
|
`bundle add` <GEM_NAME> [--group=GROUP] [--version=VERSION] [--source=SOURCE]
|
|
7
7
|
[--path=PATH] [--git=GIT|--github=GITHUB] [--branch=BRANCH] [--ref=REF]
|
|
8
|
-
[--quiet] [--skip-install] [--strict|--optimistic]
|
|
8
|
+
[--cooldown=NUMBER] [--quiet] [--skip-install] [--strict|--optimistic]
|
|
9
9
|
|
|
10
10
|
## DESCRIPTION
|
|
11
11
|
|
|
@@ -56,6 +56,11 @@ Adds the named gem to the [`Gemfile(5)`][Gemfile(5)] and run `bundle install`.
|
|
|
56
56
|
* `--strict`:
|
|
57
57
|
Adds strict declaration of version.
|
|
58
58
|
|
|
59
|
+
* `--cooldown=<number>`:
|
|
60
|
+
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.
|
|
63
|
+
|
|
59
64
|
## EXAMPLES
|
|
60
65
|
|
|
61
66
|
1. You can add the `rails` gem to the Gemfile without any version restriction.
|
|
@@ -69,162 +69,126 @@ The canonical form of this configuration is \fB"without"\fR\. To convert the can
|
|
|
69
69
|
Any periods in the configuration keys must be replaced with two underscores when setting it via environment variables\. The configuration key \fBlocal\.rack\fR becomes the environment variable \fBBUNDLE_LOCAL__RACK\fR\.
|
|
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
|
-
.
|
|
73
|
-
\fBapi_request_size\fR (\fBBUNDLE_API_REQUEST_SIZE\fR)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
\
|
|
77
|
-
|
|
78
|
-
.
|
|
79
|
-
\
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
\
|
|
83
|
-
|
|
84
|
-
.
|
|
85
|
-
\
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
\
|
|
89
|
-
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
.
|
|
97
|
-
\
|
|
98
|
-
|
|
99
|
-
.
|
|
100
|
-
\
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
\
|
|
104
|
-
|
|
105
|
-
.
|
|
106
|
-
\
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
\
|
|
110
|
-
|
|
111
|
-
.
|
|
112
|
-
\
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
\
|
|
116
|
-
Stop Bundler from accessing gems installed to RubyGems' normal location\.
|
|
117
|
-
.
|
|
118
|
-
\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
\
|
|
122
|
-
|
|
123
|
-
.
|
|
124
|
-
\
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
\
|
|
128
|
-
|
|
129
|
-
.
|
|
130
|
-
\
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
\
|
|
134
|
-
|
|
135
|
-
.
|
|
136
|
-
\
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
\
|
|
140
|
-
|
|
141
|
-
.
|
|
142
|
-
\
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
\
|
|
146
|
-
|
|
147
|
-
.
|
|
148
|
-
\
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
\
|
|
152
|
-
|
|
153
|
-
.
|
|
154
|
-
\
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
\
|
|
158
|
-
|
|
159
|
-
.
|
|
160
|
-
\
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
\
|
|
164
|
-
|
|
165
|
-
.
|
|
166
|
-
\
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
\
|
|
170
|
-
|
|
171
|
-
.
|
|
172
|
-
\
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
\
|
|
176
|
-
|
|
177
|
-
.
|
|
178
|
-
\
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
\
|
|
182
|
-
|
|
183
|
-
.
|
|
184
|
-
\
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
\
|
|
188
|
-
|
|
189
|
-
.
|
|
190
|
-
\
|
|
191
|
-
|
|
192
|
-
.TP
|
|
193
|
-
\fBsimulate_version\fR (\fBBUNDLE_SIMULATE_VERSION\fR)
|
|
194
|
-
The virtual version Bundler should use for activating feature flags\. Can be used to simulate all the new functionality that will be enabled in a future major version\.
|
|
195
|
-
.TP
|
|
196
|
-
\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR)
|
|
197
|
-
Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\.
|
|
198
|
-
.TP
|
|
199
|
-
\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR)
|
|
200
|
-
Path to a designated file containing a X\.509 client certificate and key in PEM format\.
|
|
201
|
-
.TP
|
|
202
|
-
\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR)
|
|
203
|
-
The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\.
|
|
204
|
-
.TP
|
|
205
|
-
\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR)
|
|
206
|
-
The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\.
|
|
207
|
-
.TP
|
|
208
|
-
\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR)
|
|
209
|
-
The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\.
|
|
210
|
-
.TP
|
|
211
|
-
\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR)
|
|
212
|
-
Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
|
|
213
|
-
.TP
|
|
214
|
-
\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR)
|
|
215
|
-
The custom user agent fragment Bundler includes in API requests\.
|
|
216
|
-
.TP
|
|
217
|
-
\fBverbose\fR (\fBBUNDLE_VERBOSE\fR)
|
|
218
|
-
Whether Bundler should print verbose output\. Defaults to \fBfalse\fR, unless the \fB\-\-verbose\fR CLI flag is used\.
|
|
219
|
-
.TP
|
|
220
|
-
\fBversion\fR (\fBBUNDLE_VERSION\fR)
|
|
221
|
-
The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\.
|
|
222
|
-
.TP
|
|
223
|
-
\fBwith\fR (\fBBUNDLE_WITH\fR)
|
|
224
|
-
A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should install\.
|
|
225
|
-
.TP
|
|
226
|
-
\fBwithout\fR (\fBBUNDLE_WITHOUT\fR)
|
|
227
|
-
A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should not install\.
|
|
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\.
|
|
74
|
+
.IP "\(bu" 4
|
|
75
|
+
\fBauto_install\fR (\fBBUNDLE_AUTO_INSTALL\fR): Automatically run \fBbundle install\fR when gems are missing\.
|
|
76
|
+
.IP "\(bu" 4
|
|
77
|
+
\fBbin\fR (\fBBUNDLE_BIN\fR): If configured, \fBbundle binstubs\fR will install executables from gems in the bundle to the specified directory\. Otherwise it will create them in a \fBbin\fR directory relative to the Gemfile directory\. These executables run in Bundler's context\. If used, you might add this directory to your environment's \fBPATH\fR variable\. For instance, if the \fBrails\fR gem comes with a \fBrails\fR executable, \fBbundle binstubs\fR will create a \fBbin/rails\fR executable that ensures that all referred dependencies will be resolved using the bundled gems\.
|
|
78
|
+
.IP "\(bu" 4
|
|
79
|
+
\fBcache_all\fR (\fBBUNDLE_CACHE_ALL\fR): Cache all gems, including path and git gems\. This needs to be explicitly before bundler 4, but will be the default on bundler 4\.
|
|
80
|
+
.IP "\(bu" 4
|
|
81
|
+
\fBcache_all_platforms\fR (\fBBUNDLE_CACHE_ALL_PLATFORMS\fR): Cache gems for all platforms\.
|
|
82
|
+
.IP "\(bu" 4
|
|
83
|
+
\fBcache_path\fR (\fBBUNDLE_CACHE_PATH\fR): The directory that bundler will place cached gems in when running \fBbundle package\fR, and that bundler will look in when installing gems\. Defaults to \fBvendor/cache\fR\.
|
|
84
|
+
.IP "\(bu" 4
|
|
85
|
+
\fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. Defaults to \fBtrue\fR in Bundler 4, as long as \fBpath\fR is not explicitly configured\.
|
|
86
|
+
.IP "\(bu" 4
|
|
87
|
+
\fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\.
|
|
88
|
+
.IP "\(bu" 4
|
|
89
|
+
\fBcooldown\fR (\fBBUNDLE_COOLDOWN\fR): Number of days a published gem version must age before bundler will resolve to it\. Defaults to unset (no cooldown)\. Pass \fB0\fR to disable cooldown for an individual run\.
|
|
90
|
+
.IP
|
|
91
|
+
The effective cooldown for any given gem is resolved from three layers, highest precedence first:
|
|
92
|
+
.IP "1." 4
|
|
93
|
+
CLI flag \fB\-\-cooldown N\fR on \fBinstall\fR, \fBupdate\fR, \fBadd\fR, and \fBoutdated\fR\.
|
|
94
|
+
.IP "2." 4
|
|
95
|
+
This setting (\fBbundle config set cooldown N\fR or \fBBUNDLE_COOLDOWN=N\fR)\.
|
|
96
|
+
.IP "3." 4
|
|
97
|
+
The per\-source \fBcooldown:\fR keyword in the Gemfile, such as \fBsource "https://rubygems\.org", cooldown: 7\fR\.
|
|
98
|
+
.IP "" 0
|
|
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\.
|
|
101
|
+
.IP
|
|
102
|
+
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\.
|
|
103
|
+
.IP "\(bu" 4
|
|
104
|
+
\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
|
+
.IP "\(bu" 4
|
|
106
|
+
\fBdeployment\fR (\fBBUNDLE_DEPLOYMENT\fR): Equivalent to setting \fBfrozen\fR to \fBtrue\fR and \fBpath\fR to \fBvendor/bundle\fR\.
|
|
107
|
+
.IP "\(bu" 4
|
|
108
|
+
\fBdisable_checksum_validation\fR (\fBBUNDLE_DISABLE_CHECKSUM_VALIDATION\fR): Allow installing gems even if they do not match the checksum provided by RubyGems\.
|
|
109
|
+
.IP "\(bu" 4
|
|
110
|
+
\fBdisable_exec_load\fR (\fBBUNDLE_DISABLE_EXEC_LOAD\fR): Stop Bundler from using \fBload\fR to launch an executable in\-process in \fBbundle exec\fR\.
|
|
111
|
+
.IP "\(bu" 4
|
|
112
|
+
\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR): Allow Bundler to use a local git override without a branch specified in the Gemfile\.
|
|
113
|
+
.IP "\(bu" 4
|
|
114
|
+
\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\.
|
|
115
|
+
.IP "\(bu" 4
|
|
116
|
+
\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems' normal location\.
|
|
117
|
+
.IP "\(bu" 4
|
|
118
|
+
\fBdisable_version_check\fR (\fBBUNDLE_DISABLE_VERSION_CHECK\fR): Stop Bundler from checking if a newer Bundler version is available on rubygems\.org\.
|
|
119
|
+
.IP "\(bu" 4
|
|
120
|
+
\fBforce_ruby_platform\fR (\fBBUNDLE_FORCE_RUBY_PLATFORM\fR): Ignore the current machine's platform and install only \fBruby\fR platform gems\. As a result, gems with native extensions will be compiled from source\.
|
|
121
|
+
.IP "\(bu" 4
|
|
122
|
+
\fBfrozen\fR (\fBBUNDLE_FROZEN\fR): Disallow any automatic changes to \fBGemfile\.lock\fR\. Bundler commands will be blocked unless the lockfile can be installed exactly as written\. Usually this will happen when changing the \fBGemfile\fR manually and forgetting to update the lockfile through \fBbundle lock\fR or \fBbundle install\fR\.
|
|
123
|
+
.IP "\(bu" 4
|
|
124
|
+
\fBgem\.github_username\fR (\fBBUNDLE_GEM__GITHUB_USERNAME\fR): Sets a GitHub username or organization to be used in the \fBREADME\fR and \fB\.gemspec\fR files when you create a new gem via \fBbundle gem\fR command\. It can be overridden by passing an explicit \fB\-\-github\-username\fR flag to \fBbundle gem\fR\.
|
|
125
|
+
.IP "\(bu" 4
|
|
126
|
+
\fBgem\.push_key\fR (\fBBUNDLE_GEM__PUSH_KEY\fR): Sets the \fB\-\-key\fR parameter for \fBgem push\fR when using the \fBrake release\fR command with a private gemstash server\.
|
|
127
|
+
.IP "\(bu" 4
|
|
128
|
+
\fBgemfile\fR (\fBBUNDLE_GEMFILE\fR): The name of the file that bundler should use as the \fBGemfile\fR\. This location of this file also sets the root of the project, which is used to resolve relative paths in the \fBGemfile\fR, among other things\. By default, bundler will search up from the current working directory until it finds a \fBGemfile\fR\.
|
|
129
|
+
.IP "\(bu" 4
|
|
130
|
+
\fBglobal_gem_cache\fR (\fBBUNDLE_GLOBAL_GEM_CACHE\fR): Whether Bundler should cache all gems and compiled extensions globally, rather than locally to the configured installation path\.
|
|
131
|
+
.IP "\(bu" 4
|
|
132
|
+
\fBignore_funding_requests\fR (\fBBUNDLE_IGNORE_FUNDING_REQUESTS\fR): When set, no funding requests will be printed\.
|
|
133
|
+
.IP "\(bu" 4
|
|
134
|
+
\fBignore_messages\fR (\fBBUNDLE_IGNORE_MESSAGES\fR): When set, no post install messages will be printed\. To silence a single gem, use dot notation like \fBignore_messages\.httparty true\fR\.
|
|
135
|
+
.IP "\(bu" 4
|
|
136
|
+
\fBinit_gems_rb\fR (\fBBUNDLE_INIT_GEMS_RB\fR): Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\.
|
|
137
|
+
.IP "\(bu" 4
|
|
138
|
+
\fBjobs\fR (\fBBUNDLE_JOBS\fR): The number of gems Bundler can download and install in parallel\. Defaults to the number of available processors\.
|
|
139
|
+
.IP "\(bu" 4
|
|
140
|
+
\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
|
+
.IP "\(bu" 4
|
|
142
|
+
\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\.
|
|
143
|
+
.IP "\(bu" 4
|
|
144
|
+
\fBno_install\fR (\fBBUNDLE_NO_INSTALL\fR): Whether \fBbundle package\fR should skip installing gems\.
|
|
145
|
+
.IP "\(bu" 4
|
|
146
|
+
\fBno_prune\fR (\fBBUNDLE_NO_PRUNE\fR): Whether Bundler should leave outdated gems unpruned when caching\.
|
|
147
|
+
.IP "\(bu" 4
|
|
148
|
+
\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
|
+
.IP "\(bu" 4
|
|
150
|
+
\fBpath\fR (\fBBUNDLE_PATH\fR): The location on disk where all gems in your bundle will be located regardless of \fB$GEM_HOME\fR or \fB$GEM_PATH\fR values\. Bundle gems not found in this location will be installed by \fBbundle install\fR\. When not set, Bundler install by default to a \fB\.bundle\fR directory relative to repository root in Bundler 4, and to the default system path (\fBGem\.dir\fR) before Bundler 4\. That means that before Bundler 4, Bundler shares this location with Rubygems, and \fBgem install \|\.\|\.\|\.\fR will have gems installed in the same location and therefore, gems installed without \fBpath\fR set will show up by calling \fBgem list\fR\. This will not be the case in Bundler 4\.
|
|
151
|
+
.IP "\(bu" 4
|
|
152
|
+
\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\.
|
|
153
|
+
.IP "\(bu" 4
|
|
154
|
+
\fBplugins\fR (\fBBUNDLE_PLUGINS\fR): Enable Bundler's experimental plugin system\.
|
|
155
|
+
.IP "\(bu" 4
|
|
156
|
+
\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
|
+
.IP "\(bu" 4
|
|
158
|
+
\fBredirect\fR (\fBBUNDLE_REDIRECT\fR): The number of redirects allowed for network requests\. Defaults to \fB5\fR\.
|
|
159
|
+
.IP "\(bu" 4
|
|
160
|
+
\fBretry\fR (\fBBUNDLE_RETRY\fR): The number of times to retry failed network requests\. Defaults to \fB3\fR\.
|
|
161
|
+
.IP "\(bu" 4
|
|
162
|
+
\fBshebang\fR (\fBBUNDLE_SHEBANG\fR): The program name that should be invoked for generated binstubs\. Defaults to the ruby install name used to generate the binstub\.
|
|
163
|
+
.IP "\(bu" 4
|
|
164
|
+
\fBsilence_deprecations\fR (\fBBUNDLE_SILENCE_DEPRECATIONS\fR): Whether Bundler should silence deprecation warnings for behavior that will be changed in the next major version\.
|
|
165
|
+
.IP "\(bu" 4
|
|
166
|
+
\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\.
|
|
167
|
+
.IP "\(bu" 4
|
|
168
|
+
\fBsimulate_version\fR (\fBBUNDLE_SIMULATE_VERSION\fR): The virtual version Bundler should use for activating feature flags\. Can be used to simulate all the new functionality that will be enabled in a future major version\.
|
|
169
|
+
.IP "\(bu" 4
|
|
170
|
+
\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\.
|
|
171
|
+
.IP "\(bu" 4
|
|
172
|
+
\fBssl_client_cert\fR (\fBBUNDLE_SSL_CLIENT_CERT\fR): Path to a designated file containing a X\.509 client certificate and key in PEM format\.
|
|
173
|
+
.IP "\(bu" 4
|
|
174
|
+
\fBssl_verify_mode\fR (\fBBUNDLE_SSL_VERIFY_MODE\fR): The SSL verification mode Bundler uses when making HTTPS requests\. Defaults to verify peer\.
|
|
175
|
+
.IP "\(bu" 4
|
|
176
|
+
\fBsystem_bindir\fR (\fBBUNDLE_SYSTEM_BINDIR\fR): The location where RubyGems installs binstubs\. Defaults to \fBGem\.bindir\fR\.
|
|
177
|
+
.IP "\(bu" 4
|
|
178
|
+
\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\.
|
|
179
|
+
.IP "\(bu" 4
|
|
180
|
+
\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
|
+
.IP "\(bu" 4
|
|
182
|
+
\fBuser_agent\fR (\fBBUNDLE_USER_AGENT\fR): The custom user agent fragment Bundler includes in API requests\.
|
|
183
|
+
.IP "\(bu" 4
|
|
184
|
+
\fBverbose\fR (\fBBUNDLE_VERBOSE\fR): Whether Bundler should print verbose output\. Defaults to \fBfalse\fR, unless the \fB\-\-verbose\fR CLI flag is used\.
|
|
185
|
+
.IP "\(bu" 4
|
|
186
|
+
\fBversion\fR (\fBBUNDLE_VERSION\fR): The version of Bundler to use when running under Bundler environment\. Defaults to \fBlockfile\fR\. You can also specify \fBsystem\fR or \fBx\.y\.z\fR\. \fBlockfile\fR will use the Bundler version specified in the \fBGemfile\.lock\fR, \fBsystem\fR will use the system version of Bundler, and \fBx\.y\.z\fR will use the specified version of Bundler\.
|
|
187
|
+
.IP "\(bu" 4
|
|
188
|
+
\fBwith\fR (\fBBUNDLE_WITH\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should install\.
|
|
189
|
+
.IP "\(bu" 4
|
|
190
|
+
\fBwithout\fR (\fBBUNDLE_WITHOUT\fR): A space\-separated or \fB:\fR\-separated list of groups whose gems bundler should not install\.
|
|
191
|
+
.IP "" 0
|
|
228
192
|
.SH "BUILD OPTIONS"
|
|
229
193
|
You can use \fBbundle config\fR to give Bundler the flags to pass to the gem installer every time bundler tries to install a particular gem\.
|
|
230
194
|
.P
|
|
@@ -137,6 +137,36 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
|
|
137
137
|
explicitly configured.
|
|
138
138
|
* `console` (`BUNDLE_CONSOLE`):
|
|
139
139
|
The console that `bundle console` starts. Defaults to `irb`.
|
|
140
|
+
* `cooldown` (`BUNDLE_COOLDOWN`):
|
|
141
|
+
Number of days a published gem version must age before bundler will
|
|
142
|
+
resolve to it. Defaults to unset (no cooldown). Pass `0` to disable
|
|
143
|
+
cooldown for an individual run.
|
|
144
|
+
|
|
145
|
+
The effective cooldown for any given gem is resolved from three
|
|
146
|
+
layers, highest precedence first:
|
|
147
|
+
|
|
148
|
+
1. CLI flag `--cooldown N` on `install`, `update`, `add`, and
|
|
149
|
+
`outdated`.
|
|
150
|
+
2. This setting (`bundle config set cooldown N` or
|
|
151
|
+
`BUNDLE_COOLDOWN=N`).
|
|
152
|
+
3. The per-source `cooldown:` keyword in the Gemfile, such as
|
|
153
|
+
`source "https://rubygems.org", cooldown: 7`.
|
|
154
|
+
|
|
155
|
+
The CLI flag and this setting apply uniformly to every source,
|
|
156
|
+
including ones declared with their own `cooldown:` value. To keep a
|
|
157
|
+
private registry permanently exempt while still cooling down public
|
|
158
|
+
gems, declare `source "https://internal", cooldown: 0` in the
|
|
159
|
+
Gemfile; remember that `--cooldown N` on the command line will
|
|
160
|
+
still override it for that single run.
|
|
161
|
+
|
|
162
|
+
Cooldown filtering depends on the gem server providing a per-version
|
|
163
|
+
`created_at` timestamp in the v2 compact-index format. Versions
|
|
164
|
+
without that metadata - older gem servers, historical entries that
|
|
165
|
+
predate the v2 cutover on `rubygems.org`, or private registries that
|
|
166
|
+
still emit the v1 format - are treated as outside the cooldown
|
|
167
|
+
window and remain resolvable. If you rely on cooldown for
|
|
168
|
+
supply-chain protection, confirm that the gem server emits
|
|
169
|
+
`created_at` in its `/info/<gem>` responses.
|
|
140
170
|
* `default_cli_command` (`BUNDLE_DEFAULT_CLI_COMMAND`):
|
|
141
171
|
The command that running `bundle` without arguments should run. Defaults to
|
|
142
172
|
`cli_help` since Bundler 4, but can also be `install` which was the previous
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
|
|
6
6
|
.SH "SYNOPSIS"
|
|
7
|
-
\fBbundle install\fR [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-lockfile=LOCKFILE] [\-\-no\-cache] [\-\-no\-lock] [\-\-prefer\-local] [\-\-quiet] [\-\-retry=NUMBER] [\-\-standalone[=GROUP[ GROUP\|\.\|\.\|\.]]] [\-\-trust\-policy=TRUST\-POLICY] [\-\-target\-rbconfig=TARGET\-RBCONFIG]
|
|
7
|
+
\fBbundle install\fR [\-\-cooldown=NUMBER] [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-local] [\-\-lockfile=LOCKFILE] [\-\-no\-cache] [\-\-no\-lock] [\-\-prefer\-local] [\-\-quiet] [\-\-retry=NUMBER] [\-\-standalone[=GROUP[ GROUP\|\.\|\.\|\.]]] [\-\-trust\-policy=TRUST\-POLICY] [\-\-target\-rbconfig=TARGET\-RBCONFIG]
|
|
8
8
|
.SH "DESCRIPTION"
|
|
9
9
|
Install the gems specified in your Gemfile(5)\. If this is the first time you run bundle install (and a \fBGemfile\.lock\fR does not exist), Bundler will fetch all remote sources, resolve dependencies and install all needed gems\.
|
|
10
10
|
.P
|
|
@@ -13,6 +13,9 @@ If a \fBGemfile\.lock\fR does exist, and you have not updated your Gemfile(5), B
|
|
|
13
13
|
If a \fBGemfile\.lock\fR does exist, and you have updated your Gemfile(5), Bundler will use the dependencies in the \fBGemfile\.lock\fR for all gems that you did not update, but will re\-resolve the dependencies of gems that you did update\. You can find more information about this update process below under \fICONSERVATIVE UPDATING\fR\.
|
|
14
14
|
.SH "OPTIONS"
|
|
15
15
|
.TP
|
|
16
|
+
\fB\-\-cooldown=<number>\fR
|
|
17
|
+
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. See \fBcooldown\fR in bundle\-config(1) for details on the precedence between the CLI flag, Bundler config, and Gemfile per\-source settings\.
|
|
18
|
+
.TP
|
|
16
19
|
\fB\-\-force\fR, \fB\-\-redownload\fR
|
|
17
20
|
Force reinstalling every gem, even if already installed\.
|
|
18
21
|
.TP
|
|
@@ -3,7 +3,8 @@ bundle-install(1) -- Install the dependencies specified in your Gemfile
|
|
|
3
3
|
|
|
4
4
|
## SYNOPSIS
|
|
5
5
|
|
|
6
|
-
`bundle install` [--
|
|
6
|
+
`bundle install` [--cooldown=NUMBER]
|
|
7
|
+
[--force]
|
|
7
8
|
[--full-index]
|
|
8
9
|
[--gemfile=GEMFILE]
|
|
9
10
|
[--jobs=NUMBER]
|
|
@@ -37,6 +38,13 @@ update process below under [CONSERVATIVE UPDATING][].
|
|
|
37
38
|
|
|
38
39
|
## OPTIONS
|
|
39
40
|
|
|
41
|
+
* `--cooldown=<number>`:
|
|
42
|
+
Only consider gem versions published at least <number> days ago when
|
|
43
|
+
resolving. Pass `0` to disable cooldown for this run, overriding any
|
|
44
|
+
per-source or global configuration. See `cooldown` in bundle-config(1)
|
|
45
|
+
for details on the precedence between the CLI flag, Bundler config,
|
|
46
|
+
and Gemfile per-source settings.
|
|
47
|
+
|
|
40
48
|
* `--force`, `--redownload`:
|
|
41
49
|
Force reinstalling every gem, even if already installed.
|
|
42
50
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-outdated\fR \- List installed gems with newer versions available
|
|
6
6
|
.SH "SYNOPSIS"
|
|
7
|
-
\fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-filter\-strict | \-\-strict] [\-\-update\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit]
|
|
7
|
+
\fBbundle outdated\fR [GEM] [\-\-local] [\-\-pre] [\-\-source] [\-\-filter\-strict | \-\-strict] [\-\-update\-strict] [\-\-parseable | \-\-porcelain] [\-\-group=GROUP] [\-\-groups] [\-\-patch|\-\-minor|\-\-major] [\-\-filter\-major] [\-\-filter\-minor] [\-\-filter\-patch] [\-\-only\-explicit] [\-\-cooldown=NUMBER]
|
|
8
8
|
.SH "DESCRIPTION"
|
|
9
9
|
Outdated lists the names and versions of gems that have a newer version available in the given source\. Calling outdated with [GEM [GEM]] will only check for newer versions of the given gems\. Prerelease gems are ignored by default\. If your gems are up to date, Bundler will exit with a status of 0\. Otherwise, it will exit 1\.
|
|
10
10
|
.SH "OPTIONS"
|
|
@@ -53,6 +53,9 @@ Only list patch newer versions\.
|
|
|
53
53
|
.TP
|
|
54
54
|
\fB\-\-only\-explicit\fR
|
|
55
55
|
Only list gems specified in your Gemfile, not their dependencies\.
|
|
56
|
+
.TP
|
|
57
|
+
\fB\-\-cooldown=<number>\fR
|
|
58
|
+
Annotate (rather than hide) versions that are still inside the cooldown window of \fInumber\fR days\. The prose output appends "in cooldown for Nd more days" and the table form adds "(cooldown Nd)" to the Latest column\. See \fBcooldown\fR in bundle\-config(1)\.
|
|
56
59
|
.SH "PATCH LEVEL OPTIONS"
|
|
57
60
|
See bundle update(1) \fIbundle\-update\.1\.html\fR for details\.
|
|
58
61
|
.SH "FILTERING OUTPUT"
|
|
@@ -61,42 +64,42 @@ The 3 filtering options do not affect the resolution of versions, merely what ve
|
|
|
61
64
|
If the regular output shows the following:
|
|
62
65
|
.IP "" 4
|
|
63
66
|
.nf
|
|
64
|
-
* Gem Current Latest Requested Groups
|
|
65
|
-
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
|
|
66
|
-
* hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default
|
|
67
|
-
* headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test
|
|
67
|
+
* Gem Current Latest Requested Groups Release Date
|
|
68
|
+
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test 2024\-02\-05
|
|
69
|
+
* hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default 2023\-11\-10
|
|
70
|
+
* headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test 2022\-08\-19
|
|
68
71
|
.fi
|
|
69
72
|
.IP "" 0
|
|
70
73
|
.P
|
|
71
74
|
\fB\-\-filter\-major\fR would only show:
|
|
72
75
|
.IP "" 4
|
|
73
76
|
.nf
|
|
74
|
-
* Gem Current Latest Requested Groups
|
|
75
|
-
* hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default
|
|
77
|
+
* Gem Current Latest Requested Groups Release Date
|
|
78
|
+
* hashie 1\.2\.0 3\.4\.6 = 1\.2\.0 default 2023\-11\-10
|
|
76
79
|
.fi
|
|
77
80
|
.IP "" 0
|
|
78
81
|
.P
|
|
79
82
|
\fB\-\-filter\-minor\fR would only show:
|
|
80
83
|
.IP "" 4
|
|
81
84
|
.nf
|
|
82
|
-
* Gem Current Latest Requested Groups
|
|
83
|
-
* headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test
|
|
85
|
+
* Gem Current Latest Requested Groups Release Date
|
|
86
|
+
* headless 2\.2\.3 2\.3\.1 = 2\.2\.3 test 2022\-08\-19
|
|
84
87
|
.fi
|
|
85
88
|
.IP "" 0
|
|
86
89
|
.P
|
|
87
90
|
\fB\-\-filter\-patch\fR would only show:
|
|
88
91
|
.IP "" 4
|
|
89
92
|
.nf
|
|
90
|
-
* Gem Current Latest Requested Groups
|
|
91
|
-
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
|
|
93
|
+
* Gem Current Latest Requested Groups Release Date
|
|
94
|
+
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test 2024\-02\-05
|
|
92
95
|
.fi
|
|
93
96
|
.IP "" 0
|
|
94
97
|
.P
|
|
95
98
|
Filter options can be combined\. \fB\-\-filter\-minor\fR and \fB\-\-filter\-patch\fR would show:
|
|
96
99
|
.IP "" 4
|
|
97
100
|
.nf
|
|
98
|
-
* Gem Current Latest Requested Groups
|
|
99
|
-
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test
|
|
101
|
+
* Gem Current Latest Requested Groups Release Date
|
|
102
|
+
* faker 1\.6\.5 1\.6\.6 ~> 1\.4 development, test 2024\-02\-05
|
|
100
103
|
.fi
|
|
101
104
|
.IP "" 0
|
|
102
105
|
.P
|
|
@@ -16,6 +16,7 @@ bundle-outdated(1) -- List installed gems with newer versions available
|
|
|
16
16
|
[--filter-minor]
|
|
17
17
|
[--filter-patch]
|
|
18
18
|
[--only-explicit]
|
|
19
|
+
[--cooldown=NUMBER]
|
|
19
20
|
|
|
20
21
|
## DESCRIPTION
|
|
21
22
|
|
|
@@ -71,6 +72,12 @@ are up to date, Bundler will exit with a status of 0. Otherwise, it will exit 1.
|
|
|
71
72
|
* `--only-explicit`:
|
|
72
73
|
Only list gems specified in your Gemfile, not their dependencies.
|
|
73
74
|
|
|
75
|
+
* `--cooldown=<number>`:
|
|
76
|
+
Annotate (rather than hide) versions that are still inside the
|
|
77
|
+
cooldown window of <number> days. The prose output appends "in
|
|
78
|
+
cooldown for Nd more days" and the table form adds "(cooldown Nd)" to
|
|
79
|
+
the Latest column. See `cooldown` in bundle-config(1).
|
|
80
|
+
|
|
74
81
|
## PATCH LEVEL OPTIONS
|
|
75
82
|
|
|
76
83
|
See [bundle update(1)](bundle-update.1.html) for details.
|
|
@@ -82,29 +89,29 @@ in the output.
|
|
|
82
89
|
|
|
83
90
|
If the regular output shows the following:
|
|
84
91
|
|
|
85
|
-
* Gem Current Latest Requested Groups
|
|
86
|
-
* faker 1.6.5 1.6.6 ~> 1.4 development, test
|
|
87
|
-
* hashie 1.2.0 3.4.6 = 1.2.0 default
|
|
88
|
-
* headless 2.2.3 2.3.1 = 2.2.3 test
|
|
92
|
+
* Gem Current Latest Requested Groups Release Date
|
|
93
|
+
* faker 1.6.5 1.6.6 ~> 1.4 development, test 2024-02-05
|
|
94
|
+
* hashie 1.2.0 3.4.6 = 1.2.0 default 2023-11-10
|
|
95
|
+
* headless 2.2.3 2.3.1 = 2.2.3 test 2022-08-19
|
|
89
96
|
|
|
90
97
|
`--filter-major` would only show:
|
|
91
98
|
|
|
92
|
-
* Gem Current Latest Requested Groups
|
|
93
|
-
* hashie 1.2.0 3.4.6 = 1.2.0 default
|
|
99
|
+
* Gem Current Latest Requested Groups Release Date
|
|
100
|
+
* hashie 1.2.0 3.4.6 = 1.2.0 default 2023-11-10
|
|
94
101
|
|
|
95
102
|
`--filter-minor` would only show:
|
|
96
103
|
|
|
97
|
-
* Gem Current Latest Requested Groups
|
|
98
|
-
* headless 2.2.3 2.3.1 = 2.2.3 test
|
|
104
|
+
* Gem Current Latest Requested Groups Release Date
|
|
105
|
+
* headless 2.2.3 2.3.1 = 2.2.3 test 2022-08-19
|
|
99
106
|
|
|
100
107
|
`--filter-patch` would only show:
|
|
101
108
|
|
|
102
|
-
* Gem Current Latest Requested Groups
|
|
103
|
-
* faker 1.6.5 1.6.6 ~> 1.4 development, test
|
|
109
|
+
* Gem Current Latest Requested Groups Release Date
|
|
110
|
+
* faker 1.6.5 1.6.6 ~> 1.4 development, test 2024-02-05
|
|
104
111
|
|
|
105
112
|
Filter options can be combined. `--filter-minor` and `--filter-patch` would show:
|
|
106
113
|
|
|
107
|
-
* Gem Current Latest Requested Groups
|
|
108
|
-
* faker 1.6.5 1.6.6 ~> 1.4 development, test
|
|
114
|
+
* Gem Current Latest Requested Groups Release Date
|
|
115
|
+
* faker 1.6.5 1.6.6 ~> 1.4 development, test 2024-02-05
|
|
109
116
|
|
|
110
117
|
Combining all three `filter` options would be the same result as providing none of them.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
.SH "NAME"
|
|
5
5
|
\fBbundle\-update\fR \- Update your gems to the latest available versions
|
|
6
6
|
.SH "SYNOPSIS"
|
|
7
|
-
\fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative]
|
|
7
|
+
\fBbundle update\fR \fI*gems\fR [\-\-all] [\-\-group=NAME] [\-\-source=NAME] [\-\-local] [\-\-ruby] [\-\-bundler[=VERSION]] [\-\-cooldown=NUMBER] [\-\-force] [\-\-full\-index] [\-\-gemfile=GEMFILE] [\-\-jobs=NUMBER] [\-\-quiet] [\-\-patch|\-\-minor|\-\-major] [\-\-pre] [\-\-strict] [\-\-conservative]
|
|
8
8
|
.SH "DESCRIPTION"
|
|
9
9
|
Update the gems specified (all gems, if \fB\-\-all\fR flag is used), ignoring the previously installed gems specified in the \fBGemfile\.lock\fR\. In general, you should use bundle install(1) \fIbundle\-install\.1\.html\fR to install the same exact gems and versions across machines\.
|
|
10
10
|
.P
|
|
@@ -64,6 +64,9 @@ Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR
|
|
|
64
64
|
.TP
|
|
65
65
|
\fB\-\-conservative\fR
|
|
66
66
|
Use bundle install conservative update behavior and do not allow indirect dependencies to be updated\.
|
|
67
|
+
.TP
|
|
68
|
+
\fB\-\-cooldown=<number>\fR
|
|
69
|
+
Only consider gem versions published at least \fInumber\fR days ago when resolving\. Pass \fB0\fR to disable cooldown for this run, overriding any per\-source or global configuration\. Combine with \fB\-\-conservative\fR to minimize transitive churn when bypassing cooldown for an urgent update\. See \fBcooldown\fR in bundle\-config(1)\.
|
|
67
70
|
.SH "UPDATING ALL GEMS"
|
|
68
71
|
If you run \fBbundle update \-\-all\fR, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
|
|
69
72
|
.P
|
|
@@ -9,6 +9,7 @@ bundle-update(1) -- Update your gems to the latest available versions
|
|
|
9
9
|
[--local]
|
|
10
10
|
[--ruby]
|
|
11
11
|
[--bundler[=VERSION]]
|
|
12
|
+
[--cooldown=NUMBER]
|
|
12
13
|
[--force]
|
|
13
14
|
[--full-index]
|
|
14
15
|
[--gemfile=GEMFILE]
|
|
@@ -91,6 +92,13 @@ gem.
|
|
|
91
92
|
* `--conservative`:
|
|
92
93
|
Use bundle install conservative update behavior and do not allow indirect dependencies to be updated.
|
|
93
94
|
|
|
95
|
+
* `--cooldown=<number>`:
|
|
96
|
+
Only consider gem versions published at least <number> days ago when
|
|
97
|
+
resolving. Pass `0` to disable cooldown for this run, overriding any
|
|
98
|
+
per-source or global configuration. Combine with `--conservative` to
|
|
99
|
+
minimize transitive churn when bypassing cooldown for an urgent
|
|
100
|
+
update. See `cooldown` in bundle-config(1).
|
|
101
|
+
|
|
94
102
|
## UPDATING ALL GEMS
|
|
95
103
|
|
|
96
104
|
If you run `bundle update --all`, bundler will ignore
|
|
@@ -12,7 +12,7 @@ module Bundler
|
|
|
12
12
|
|
|
13
13
|
attr_reader :name, :version, :platform
|
|
14
14
|
attr_writer :dependencies
|
|
15
|
-
attr_accessor :source, :remote, :locked_platform
|
|
15
|
+
attr_accessor :source, :remote, :locked_platform, :created_at
|
|
16
16
|
|
|
17
17
|
def initialize(name, version, platform, spec_fetcher)
|
|
18
18
|
@name = name
|
data/lib/bundler/resolver.rb
CHANGED
|
@@ -184,6 +184,9 @@ module Bundler
|
|
|
184
184
|
|
|
185
185
|
platforms_explanation = specs_matching_other_platforms.any? ? " for any resolution platforms (#{package.platforms.join(", ")})" : ""
|
|
186
186
|
custom_explanation = "#{constraint} could not be found in #{repository_for(package)}#{platforms_explanation}"
|
|
187
|
+
if hint = cooldown_hint(specs_matching_other_platforms)
|
|
188
|
+
custom_explanation += " (#{hint})"
|
|
189
|
+
end
|
|
187
190
|
|
|
188
191
|
label = "#{name} (#{constraint_string})"
|
|
189
192
|
extended_explanation = other_specs_matching_message(specs_matching_other_platforms, label) if specs_matching_other_platforms.any?
|
|
@@ -353,6 +356,10 @@ module Bundler
|
|
|
353
356
|
message << "\n#{other_specs_matching_message(specs, matching_part)}"
|
|
354
357
|
end
|
|
355
358
|
|
|
359
|
+
if hint = cooldown_hint(specs_matching_requirement)
|
|
360
|
+
message << "\n\n#{hint}."
|
|
361
|
+
end
|
|
362
|
+
|
|
356
363
|
if specs_matching_requirement.any? && (hint = platform_mismatch_hint)
|
|
357
364
|
message << "\n\n#{hint}"
|
|
358
365
|
end
|
|
@@ -396,7 +403,7 @@ module Bundler
|
|
|
396
403
|
end
|
|
397
404
|
|
|
398
405
|
def filter_specs(specs, package)
|
|
399
|
-
filter_remote_specs(filter_prereleases(specs, package), package)
|
|
406
|
+
filter_remote_specs(filter_cooldown(filter_prereleases(specs, package)), package)
|
|
400
407
|
end
|
|
401
408
|
|
|
402
409
|
def filter_prereleases(specs, package)
|
|
@@ -405,6 +412,40 @@ module Bundler
|
|
|
405
412
|
specs.reject {|s| s.version.prerelease? }
|
|
406
413
|
end
|
|
407
414
|
|
|
415
|
+
def filter_cooldown(specs)
|
|
416
|
+
return specs if specs.empty?
|
|
417
|
+
excluded_versions = cooldown_excluded_versions(specs)
|
|
418
|
+
return specs if excluded_versions.empty?
|
|
419
|
+
specs.reject {|s| excluded_versions.include?([s.name, s.version]) }
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def cooldown_excluded_versions(specs)
|
|
423
|
+
excluded = {}
|
|
424
|
+
specs.each do |spec|
|
|
425
|
+
next unless cooldown_excluded?(spec)
|
|
426
|
+
excluded[[spec.name, spec.version]] = true
|
|
427
|
+
end
|
|
428
|
+
excluded
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
def cooldown_hint(specs)
|
|
432
|
+
excluded_versions = cooldown_excluded_versions(specs)
|
|
433
|
+
return nil if excluded_versions.empty?
|
|
434
|
+
"#{excluded_versions.size} version#{"s" if excluded_versions.size > 1} excluded by the cooldown setting; pass `--cooldown 0` to bypass"
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
def cooldown_excluded?(spec)
|
|
438
|
+
return false unless spec.respond_to?(:created_at) && spec.created_at
|
|
439
|
+
return false unless spec.respond_to?(:remote) && spec.remote
|
|
440
|
+
days = spec.remote.effective_cooldown
|
|
441
|
+
return false if days.nil? || days <= 0
|
|
442
|
+
(cooldown_now - spec.created_at) < (days * 86_400)
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def cooldown_now
|
|
446
|
+
@cooldown_now ||= Time.now
|
|
447
|
+
end
|
|
448
|
+
|
|
408
449
|
def filter_remote_specs(specs, package)
|
|
409
450
|
if package.prefer_local?
|
|
410
451
|
local_specs = specs.select {|s| s.is_a?(StubSpecification) }
|
data/lib/bundler/rubygems_ext.rb
CHANGED
|
@@ -465,6 +465,28 @@ module Gem
|
|
|
465
465
|
Resolver::APISet::GemParser.prepend(UnfreezeCompactIndexParsedResponse)
|
|
466
466
|
end
|
|
467
467
|
|
|
468
|
+
# RubyGems before 4.0.13 split compact index dependency/requirement entries
|
|
469
|
+
# on every colon, which mangles metadata values that contain colons such as
|
|
470
|
+
# the `created_at` timestamps the cooldown feature relies on. Split only on
|
|
471
|
+
# the first colon so those values survive on older RubyGems.
|
|
472
|
+
#
|
|
473
|
+
# The module is defined unconditionally so it stays testable on any RubyGems,
|
|
474
|
+
# but only prepended when the host RubyGems still has the buggy behavior.
|
|
475
|
+
module SplitCompactIndexEntryOnFirstColon
|
|
476
|
+
private
|
|
477
|
+
|
|
478
|
+
def parse_dependency(string)
|
|
479
|
+
dependency = string.split(":", 2)
|
|
480
|
+
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
|
|
481
|
+
dependency[0] = -dependency[0]
|
|
482
|
+
dependency
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
unless Gem.rubygems_version >= Gem::Version.new("4.0.13")
|
|
487
|
+
Resolver::APISet::GemParser.prepend(SplitCompactIndexEntryOnFirstColon)
|
|
488
|
+
end
|
|
489
|
+
|
|
468
490
|
if Gem.rubygems_version < Gem::Version.new("3.6.0")
|
|
469
491
|
class Package; end
|
|
470
492
|
require "rubygems/package/tar_reader"
|
data/lib/bundler/settings.rb
CHANGED
|
@@ -432,9 +432,14 @@ module Bundler
|
|
|
432
432
|
end
|
|
433
433
|
|
|
434
434
|
def capture3_args_for(cmd, dir)
|
|
435
|
-
|
|
435
|
+
# Disable automatic maintenance so a background commit-graph write in
|
|
436
|
+
# the source repo can't race the hardlinking local clone and fail with
|
|
437
|
+
# "hardlink different from source".
|
|
438
|
+
opts = ["-c", "gc.auto=0", "-c", "maintenance.auto=false"]
|
|
436
439
|
|
|
437
|
-
["git",
|
|
440
|
+
return ["git", *opts, *cmd] unless dir
|
|
441
|
+
|
|
442
|
+
["git", "-C", dir.to_s, *opts, *cmd]
|
|
438
443
|
end
|
|
439
444
|
|
|
440
445
|
def extra_clone_args
|
|
@@ -4,9 +4,9 @@ module Bundler
|
|
|
4
4
|
class Source
|
|
5
5
|
class Rubygems
|
|
6
6
|
class Remote
|
|
7
|
-
attr_reader :uri, :anonymized_uri, :original_uri
|
|
7
|
+
attr_reader :uri, :anonymized_uri, :original_uri, :cooldown
|
|
8
8
|
|
|
9
|
-
def initialize(uri)
|
|
9
|
+
def initialize(uri, cooldown: nil)
|
|
10
10
|
orig_uri = uri
|
|
11
11
|
uri = Bundler.settings.mirror_for(uri)
|
|
12
12
|
@original_uri = orig_uri if orig_uri != uri
|
|
@@ -14,6 +14,16 @@ module Bundler
|
|
|
14
14
|
|
|
15
15
|
@uri = apply_auth(uri, fallback_auth).freeze
|
|
16
16
|
@anonymized_uri = remove_auth(@uri).freeze
|
|
17
|
+
@cooldown = cooldown
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Returns the cooldown days that apply to this remote, resolving the
|
|
21
|
+
# precedence CLI > config > Gemfile per-source. Returns nil if no
|
|
22
|
+
# cooldown applies.
|
|
23
|
+
def effective_cooldown
|
|
24
|
+
override = Bundler.settings[:cooldown]
|
|
25
|
+
return override if override
|
|
26
|
+
@cooldown
|
|
17
27
|
end
|
|
18
28
|
|
|
19
29
|
MAX_CACHE_SLUG_HOST_SIZE = 255 - 1 - 32 # 255 minus dot minus MD5 length
|
|
@@ -16,6 +16,7 @@ module Bundler
|
|
|
16
16
|
def initialize(options = {})
|
|
17
17
|
@options = options
|
|
18
18
|
@remotes = []
|
|
19
|
+
@remote_cooldowns = {}
|
|
19
20
|
@dependency_names = []
|
|
20
21
|
@allow_remote = false
|
|
21
22
|
@allow_cached = false
|
|
@@ -25,7 +26,8 @@ module Bundler
|
|
|
25
26
|
@gem_installers = {}
|
|
26
27
|
@gem_installers_mutex = Mutex.new
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
cooldown = options["cooldown"]
|
|
30
|
+
Array(options["remotes"]).reverse_each {|r| add_remote(r, cooldown: cooldown) }
|
|
29
31
|
|
|
30
32
|
@lockfile_remotes = @remotes if options["from_lockfile"]
|
|
31
33
|
end
|
|
@@ -148,6 +150,13 @@ module Bundler
|
|
|
148
150
|
# sources, and large_idx.merge! small_idx is way faster than
|
|
149
151
|
# small_idx.merge! large_idx.
|
|
150
152
|
index = @allow_remote ? remote_specs.dup : Index.new
|
|
153
|
+
|
|
154
|
+
# Snapshot per-version `created_at` from the remote info before installed
|
|
155
|
+
# / cached specs overwrite the EndpointSpecification objects that carry
|
|
156
|
+
# it. The cooldown filter consults `created_at` on every candidate, so
|
|
157
|
+
# local stubs need the published date back-filled to participate.
|
|
158
|
+
remote_created_at = collect_remote_created_at(index)
|
|
159
|
+
|
|
151
160
|
index.merge!(cached_specs) if @allow_cached
|
|
152
161
|
index.merge!(installed_specs) if @allow_local
|
|
153
162
|
|
|
@@ -161,6 +170,8 @@ module Bundler
|
|
|
161
170
|
end
|
|
162
171
|
end
|
|
163
172
|
|
|
173
|
+
backfill_created_at(index, remote_created_at) unless remote_created_at.empty?
|
|
174
|
+
|
|
164
175
|
index
|
|
165
176
|
end
|
|
166
177
|
end
|
|
@@ -243,9 +254,14 @@ module Bundler
|
|
|
243
254
|
cached_path
|
|
244
255
|
end
|
|
245
256
|
|
|
246
|
-
def add_remote(source)
|
|
257
|
+
def add_remote(source, cooldown: nil)
|
|
247
258
|
uri = normalize_uri(source)
|
|
248
259
|
@remotes.unshift(uri) unless @remotes.include?(uri)
|
|
260
|
+
@remote_cooldowns[uri] = cooldown if cooldown
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def cooldown_for(uri)
|
|
264
|
+
@remote_cooldowns[uri]
|
|
249
265
|
end
|
|
250
266
|
|
|
251
267
|
def spec_names
|
|
@@ -266,7 +282,7 @@ module Bundler
|
|
|
266
282
|
|
|
267
283
|
def remote_fetchers
|
|
268
284
|
@remote_fetchers ||= remotes.to_h do |uri|
|
|
269
|
-
remote = Source::Rubygems::Remote.new(uri)
|
|
285
|
+
remote = Source::Rubygems::Remote.new(uri, cooldown: cooldown_for(uri))
|
|
270
286
|
[remote, Bundler::Fetcher.new(remote)]
|
|
271
287
|
end.freeze
|
|
272
288
|
end
|
|
@@ -314,6 +330,13 @@ module Bundler
|
|
|
314
330
|
@allow_remote && api_fetchers.any?
|
|
315
331
|
end
|
|
316
332
|
|
|
333
|
+
def clear_cache
|
|
334
|
+
@specs = nil
|
|
335
|
+
@installed_specs = nil
|
|
336
|
+
@default_specs = nil
|
|
337
|
+
@cached_specs = nil
|
|
338
|
+
end
|
|
339
|
+
|
|
317
340
|
protected
|
|
318
341
|
|
|
319
342
|
def remote_names
|
|
@@ -456,6 +479,31 @@ module Bundler
|
|
|
456
479
|
|
|
457
480
|
private
|
|
458
481
|
|
|
482
|
+
def collect_remote_created_at(index)
|
|
483
|
+
return {} unless @allow_remote
|
|
484
|
+
|
|
485
|
+
snapshot = {}
|
|
486
|
+
index.each do |spec|
|
|
487
|
+
next unless spec.respond_to?(:created_at) && spec.created_at
|
|
488
|
+
# Remember the remote that supplied the date too: when a source has
|
|
489
|
+
# several remotes with different per-URI cooldown settings we must
|
|
490
|
+
# restore the same one during backfill so `effective_cooldown` agrees.
|
|
491
|
+
snapshot[[spec.name, spec.version]] = [spec.created_at, spec.remote]
|
|
492
|
+
end
|
|
493
|
+
snapshot
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def backfill_created_at(index, snapshot)
|
|
497
|
+
index.each do |spec|
|
|
498
|
+
next unless spec.respond_to?(:created_at=)
|
|
499
|
+
next if spec.created_at
|
|
500
|
+
remote_created_at, remote = snapshot[[spec.name, spec.version]]
|
|
501
|
+
next unless remote_created_at
|
|
502
|
+
spec.created_at = remote_created_at
|
|
503
|
+
spec.remote ||= remote if remote && spec.respond_to?(:remote=)
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
459
507
|
def lockfile_remotes
|
|
460
508
|
@lockfile_remotes || credless_remotes
|
|
461
509
|
end
|
data/lib/bundler/source_list.rb
CHANGED
|
@@ -59,8 +59,8 @@ module Bundler
|
|
|
59
59
|
add_source_to_list Plugin.source(source).new(options), @plugin_sources
|
|
60
60
|
end
|
|
61
61
|
|
|
62
|
-
def add_global_rubygems_remote(uri)
|
|
63
|
-
global_rubygems_source.add_remote(uri)
|
|
62
|
+
def add_global_rubygems_remote(uri, cooldown: nil)
|
|
63
|
+
global_rubygems_source.add_remote(uri, cooldown: cooldown)
|
|
64
64
|
global_rubygems_source
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -136,6 +136,10 @@ module Bundler
|
|
|
136
136
|
all_sources.each(&:remote!)
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
+
def clear_cache
|
|
140
|
+
rubygems_sources.each(&:clear_cache)
|
|
141
|
+
end
|
|
142
|
+
|
|
139
143
|
private
|
|
140
144
|
|
|
141
145
|
def map_sources(replacement_sources)
|
data/lib/bundler/version.rb
CHANGED