rubygems-update 4.0.8 → 4.0.10
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 +29 -0
- data/bundler/CHANGELOG.md +29 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/pristine.rb +1 -1
- data/bundler/lib/bundler/definition.rb +3 -1
- data/bundler/lib/bundler/fetcher/gem_remote_fetcher.rb +1 -1
- data/bundler/lib/bundler/injector.rb +1 -2
- data/bundler/lib/bundler/installer/gem_installer.rb +14 -0
- data/bundler/lib/bundler/installer/parallel_installer.rb +63 -17
- data/bundler/lib/bundler/installer.rb +1 -9
- data/bundler/lib/bundler/man/bundle-config.1 +1 -1
- data/bundler/lib/bundler/man/bundle-config.1.ronn +2 -2
- data/bundler/lib/bundler/plugin/api/source.rb +8 -0
- data/bundler/lib/bundler/plugin/installer.rb +2 -1
- data/bundler/lib/bundler/resolver/strategy.rb +6 -3
- data/bundler/lib/bundler/resolver.rb +18 -0
- data/bundler/lib/bundler/retry.rb +30 -4
- data/bundler/lib/bundler/self_manager.rb +1 -0
- data/bundler/lib/bundler/settings/validator.rb +7 -0
- data/bundler/lib/bundler/settings.rb +5 -0
- data/bundler/lib/bundler/source/git/git_proxy.rb +49 -15
- data/bundler/lib/bundler/source/rubygems.rb +48 -26
- data/bundler/lib/bundler/source.rb +2 -0
- data/bundler/lib/bundler/stub_specification.rb +1 -0
- data/bundler/lib/bundler/templates/newgem/newgem.gemspec.tt +3 -0
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler/worker.rb +11 -3
- data/doc/MAINTAINERS.txt +6 -0
- data/lib/rubygems/commands/owner_command.rb +2 -1
- data/lib/rubygems/commands/pristine_command.rb +5 -0
- data/lib/rubygems/commands/sources_command.rb +33 -16
- data/lib/rubygems/package.rb +9 -0
- data/lib/rubygems/specification.rb +1 -0
- data/lib/rubygems/stub_specification.rb +1 -0
- data/lib/rubygems/util/licenses.rb +33 -0
- data/lib/rubygems/version.rb +61 -37
- data/lib/rubygems.rb +12 -4
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7a9117477d9e6ddfaa7f3478376ed88b6464d6bd63a554b29441558503083670
|
|
4
|
+
data.tar.gz: d7dba7c5e4583655d714c65b38597795957b7cb9c4e821bb5c112936b6ff2aac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e0a646de842bc30f9c55c6029a413aa192a4059df7aa3fcad9cc3a419315ee32b4d9a615eb9c5c71aa3c8633fa5d342e69b8b7665fdbbab43900a71cb439ee9a
|
|
7
|
+
data.tar.gz: 2697587a8c24d46b27d80c2b65fa01874ef3b20fe22897cb93a2f406c74a941b010de1fd95c008c7f05ad11d93a23fb88cfa3208fec8c5c391fbedcb6264e92b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.10 / 2026-04-08
|
|
4
|
+
|
|
5
|
+
### Enhancements:
|
|
6
|
+
|
|
7
|
+
* Ignore warnings with spec different platforms. Pull request [#8508](https://github.com/ruby/rubygems/pull/8508) by hsbt
|
|
8
|
+
* Better algorithm for sorting gem version. Pull request [#9421](https://github.com/ruby/rubygems/pull/9421) by Edouard-chin
|
|
9
|
+
* Update SPDX license list as of 2026-02-20. Pull request [#9434](https://github.com/ruby/rubygems/pull/9434) by hsbt
|
|
10
|
+
* Installs bundler 4.0.10 as a default gem.
|
|
11
|
+
|
|
12
|
+
### Bug fixes:
|
|
13
|
+
|
|
14
|
+
* Register native extension files in default spec map. Pull request [#9431](https://github.com/ruby/rubygems/pull/9431) by hsbt
|
|
15
|
+
* Fix NoMethodError in Gem.try_activate when activation conflicts occur. Pull request [#9404](https://github.com/ruby/rubygems/pull/9404) by hsbt
|
|
16
|
+
|
|
17
|
+
## 4.0.9 / 2026-03-25
|
|
18
|
+
|
|
19
|
+
### Enhancements:
|
|
20
|
+
|
|
21
|
+
* Fix: include owner role in `gem owner`. Pull request [#9403](https://github.com/ruby/rubygems/pull/9403) by gjtorikian
|
|
22
|
+
* Installs bundler 4.0.9 as a default gem.
|
|
23
|
+
|
|
24
|
+
### Bug fixes:
|
|
25
|
+
|
|
26
|
+
* Fix: Ensure trailing slash is added to source URIs added via gem sources. Pull request [#9055](https://github.com/ruby/rubygems/pull/9055) by zirni
|
|
27
|
+
|
|
28
|
+
### Documentation:
|
|
29
|
+
|
|
30
|
+
* [DOC] Fix link. Pull request [#9409](https://github.com/ruby/rubygems/pull/9409) by BurdetteLamar
|
|
31
|
+
|
|
3
32
|
## 4.0.8 / 2026-03-11
|
|
4
33
|
|
|
5
34
|
### Enhancements:
|
data/bundler/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.10 / 2026-04-08
|
|
4
|
+
|
|
5
|
+
### Enhancements:
|
|
6
|
+
|
|
7
|
+
* Ignore warnings with spec different platforms. Pull request [#8508](https://github.com/ruby/rubygems/pull/8508) by hsbt
|
|
8
|
+
* Improve error message when current platform is not in lockfile. Pull request [#9439](https://github.com/ruby/rubygems/pull/9439) by 55728
|
|
9
|
+
* Cache package version selection. Pull request [#9410](https://github.com/ruby/rubygems/pull/9410) by Edouard-chin
|
|
10
|
+
* Check happy path first when comparing gem version. Pull request [#9417](https://github.com/ruby/rubygems/pull/9417) by Edouard-chin
|
|
11
|
+
* [feature] default_cli_command for config what command bundler runs when no specific command is provided. Pull request [#8886](https://github.com/ruby/rubygems/pull/8886) by jonbarlo
|
|
12
|
+
* Introduce a fast path for comparing Gem::Version. Pull request [#9414](https://github.com/ruby/rubygems/pull/9414) by Edouard-chin
|
|
13
|
+
|
|
14
|
+
### Bug fixes:
|
|
15
|
+
|
|
16
|
+
* Restore rb_sys dependency for Rust. Pull request [#9416](https://github.com/ruby/rubygems/pull/9416) by bangseongbeom
|
|
17
|
+
|
|
18
|
+
## 4.0.9 / 2026-03-25
|
|
19
|
+
|
|
20
|
+
### Enhancements:
|
|
21
|
+
|
|
22
|
+
* Check the git version only **once** per `bundle install`. Pull request [#9406](https://github.com/ruby/rubygems/pull/9406) by Edouard-chin
|
|
23
|
+
* Normalize the number of workers when performing parallel operations. Pull request [#9400](https://github.com/ruby/rubygems/pull/9400) by Edouard-chin
|
|
24
|
+
* Add exponential backoff to bundler retries. Pull request [#9163](https://github.com/ruby/rubygems/pull/9163) by ChrisBr
|
|
25
|
+
* Introduce a priority queue. Pull request [#9389](https://github.com/ruby/rubygems/pull/9389) by Edouard-chin
|
|
26
|
+
* Split the download and install process of a gem. Pull request [#9381](https://github.com/ruby/rubygems/pull/9381) by Edouard-chin
|
|
27
|
+
|
|
28
|
+
### Bug fixes:
|
|
29
|
+
|
|
30
|
+
* Retry git fetch without --depth for dumb HTTP transport. Pull request [#9405](https://github.com/ruby/rubygems/pull/9405) by hsbt
|
|
31
|
+
|
|
3
32
|
## 4.0.8 (2026-03-11)
|
|
4
33
|
|
|
5
34
|
### Enhancements:
|
|
@@ -4,8 +4,8 @@ module Bundler
|
|
|
4
4
|
# Represents metadata from when the Bundler gem was built.
|
|
5
5
|
module BuildMetadata
|
|
6
6
|
# begin ivars
|
|
7
|
-
@built_at =
|
|
8
|
-
@git_commit_sha = "
|
|
7
|
+
@built_at = nil
|
|
8
|
+
@git_commit_sha = "1c1d885018".freeze
|
|
9
9
|
# end ivars
|
|
10
10
|
|
|
11
11
|
# A hash representation of the build metadata.
|
|
@@ -53,7 +53,7 @@ module Bundler
|
|
|
53
53
|
true
|
|
54
54
|
end.map(&:name)
|
|
55
55
|
|
|
56
|
-
jobs =
|
|
56
|
+
jobs = Bundler.settings.installation_parallelization
|
|
57
57
|
pristine_count = definition.specs.count - installed_specs.count
|
|
58
58
|
# allow a pristining a single gem to skip the parallel worker
|
|
59
59
|
jobs = [jobs, pristine_count].min
|
|
@@ -1122,7 +1122,9 @@ module Bundler
|
|
|
1122
1122
|
end
|
|
1123
1123
|
|
|
1124
1124
|
def preload_git_source_worker
|
|
1125
|
-
|
|
1125
|
+
workers = Bundler.settings.installation_parallelization
|
|
1126
|
+
|
|
1127
|
+
@preload_git_source_worker ||= Bundler::Worker.new(workers, "Git source preloading", ->(source, _) { source.specs })
|
|
1126
1128
|
end
|
|
1127
1129
|
|
|
1128
1130
|
def preload_git_sources
|
|
@@ -80,11 +80,10 @@ module Bundler
|
|
|
80
80
|
def conservative_version(spec)
|
|
81
81
|
version = spec.version
|
|
82
82
|
return ">= 0" if version.nil?
|
|
83
|
-
segments = version.segments
|
|
84
83
|
seg_end_index = version >= Gem::Version.new("1.0") ? 1 : 2
|
|
85
84
|
|
|
86
85
|
prerelease_suffix = version.to_s.delete_prefix(version.release.to_s) if version.prerelease?
|
|
87
|
-
"#{version_prefix}#{segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
|
|
86
|
+
"#{version_prefix}#{version.segments[0..seg_end_index].join(".")}#{prerelease_suffix}"
|
|
88
87
|
end
|
|
89
88
|
|
|
90
89
|
def version_prefix
|
|
@@ -25,6 +25,20 @@ module Bundler
|
|
|
25
25
|
[false, specific_failure_message(e)]
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def download
|
|
29
|
+
spec.source.download(
|
|
30
|
+
spec,
|
|
31
|
+
force: force,
|
|
32
|
+
local: local,
|
|
33
|
+
build_args: Array(spec_settings),
|
|
34
|
+
previous_spec: previous_spec,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
[true, nil]
|
|
38
|
+
rescue Bundler::BundlerError => e
|
|
39
|
+
[false, specific_failure_message(e)]
|
|
40
|
+
end
|
|
41
|
+
|
|
28
42
|
private
|
|
29
43
|
|
|
30
44
|
def specific_failure_message(e)
|
|
@@ -24,6 +24,10 @@ module Bundler
|
|
|
24
24
|
state == :enqueued
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def enqueue_with_priority?
|
|
28
|
+
state == :installable && spec.extensions.any?
|
|
29
|
+
end
|
|
30
|
+
|
|
27
31
|
def failed?
|
|
28
32
|
state == :failed
|
|
29
33
|
end
|
|
@@ -32,6 +36,12 @@ module Bundler
|
|
|
32
36
|
state == :none
|
|
33
37
|
end
|
|
34
38
|
|
|
39
|
+
def ready_to_install?(installed_specs)
|
|
40
|
+
return false unless state == :downloaded
|
|
41
|
+
|
|
42
|
+
spec.extensions.none? || dependencies_installed?(installed_specs)
|
|
43
|
+
end
|
|
44
|
+
|
|
35
45
|
def has_post_install_message?
|
|
36
46
|
!post_install_message.empty?
|
|
37
47
|
end
|
|
@@ -84,6 +94,7 @@ module Bundler
|
|
|
84
94
|
|
|
85
95
|
def call
|
|
86
96
|
if @rake
|
|
97
|
+
do_download(@rake, 0)
|
|
87
98
|
do_install(@rake, 0)
|
|
88
99
|
Gem::Specification.reset
|
|
89
100
|
end
|
|
@@ -107,26 +118,54 @@ module Bundler
|
|
|
107
118
|
end
|
|
108
119
|
|
|
109
120
|
def install_with_worker
|
|
110
|
-
|
|
111
|
-
|
|
121
|
+
installed_specs = {}
|
|
122
|
+
enqueue_specs(installed_specs)
|
|
123
|
+
|
|
124
|
+
process_specs(installed_specs) until finished_installing?
|
|
112
125
|
end
|
|
113
126
|
|
|
114
127
|
def install_serially
|
|
115
128
|
until finished_installing?
|
|
116
129
|
raise "failed to find a spec to enqueue while installing serially" unless spec_install = @specs.find(&:ready_to_enqueue?)
|
|
117
130
|
spec_install.state = :enqueued
|
|
131
|
+
do_download(spec_install, 0)
|
|
118
132
|
do_install(spec_install, 0)
|
|
119
133
|
end
|
|
120
134
|
end
|
|
121
135
|
|
|
122
136
|
def worker_pool
|
|
123
137
|
@worker_pool ||= Bundler::Worker.new @size, "Parallel Installer", lambda {|spec_install, worker_num|
|
|
124
|
-
|
|
138
|
+
case spec_install.state
|
|
139
|
+
when :enqueued
|
|
140
|
+
do_download(spec_install, worker_num)
|
|
141
|
+
when :installable
|
|
142
|
+
do_install(spec_install, worker_num)
|
|
143
|
+
else
|
|
144
|
+
spec_install
|
|
145
|
+
end
|
|
125
146
|
}
|
|
126
147
|
end
|
|
127
148
|
|
|
128
|
-
def
|
|
149
|
+
def do_download(spec_install, worker_num)
|
|
129
150
|
Plugin.hook(Plugin::Events::GEM_BEFORE_INSTALL, spec_install)
|
|
151
|
+
|
|
152
|
+
gem_installer = Bundler::GemInstaller.new(
|
|
153
|
+
spec_install.spec, @installer, @standalone, worker_num, @force, @local
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
success, message = gem_installer.download
|
|
157
|
+
|
|
158
|
+
if success
|
|
159
|
+
spec_install.state = :downloaded
|
|
160
|
+
else
|
|
161
|
+
spec_install.error = "#{message}\n\n#{require_tree_for_spec(spec_install.spec)}"
|
|
162
|
+
spec_install.state = :failed
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
spec_install
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def do_install(spec_install, worker_num)
|
|
130
169
|
gem_installer = Bundler::GemInstaller.new(
|
|
131
170
|
spec_install.spec, @installer, @standalone, worker_num, @force, @local
|
|
132
171
|
)
|
|
@@ -147,9 +186,19 @@ module Bundler
|
|
|
147
186
|
# Some specs might've had to wait til this spec was installed to be
|
|
148
187
|
# processed so the call to `enqueue_specs` is important after every
|
|
149
188
|
# dequeue.
|
|
150
|
-
def process_specs
|
|
151
|
-
worker_pool.deq
|
|
152
|
-
|
|
189
|
+
def process_specs(installed_specs)
|
|
190
|
+
spec = worker_pool.deq
|
|
191
|
+
|
|
192
|
+
if spec.installed?
|
|
193
|
+
installed_specs[spec.name] = true
|
|
194
|
+
return
|
|
195
|
+
elsif spec.failed?
|
|
196
|
+
return
|
|
197
|
+
elsif spec.ready_to_install?(installed_specs)
|
|
198
|
+
spec.state = :installable
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
worker_pool.enq(spec, priority: spec.enqueue_with_priority?)
|
|
153
202
|
end
|
|
154
203
|
|
|
155
204
|
def finished_installing?
|
|
@@ -185,18 +234,15 @@ module Bundler
|
|
|
185
234
|
# Later we call this lambda again to install specs that depended on
|
|
186
235
|
# previously installed specifications. We continue until all specs
|
|
187
236
|
# are installed.
|
|
188
|
-
def enqueue_specs
|
|
189
|
-
installed_specs = {}
|
|
190
|
-
@specs.each do |spec|
|
|
191
|
-
next unless spec.installed?
|
|
192
|
-
installed_specs[spec.name] = true
|
|
193
|
-
end
|
|
194
|
-
|
|
237
|
+
def enqueue_specs(installed_specs)
|
|
195
238
|
@specs.each do |spec|
|
|
196
|
-
if spec.
|
|
197
|
-
spec.
|
|
198
|
-
|
|
239
|
+
if spec.installed?
|
|
240
|
+
installed_specs[spec.name] = true
|
|
241
|
+
next
|
|
199
242
|
end
|
|
243
|
+
|
|
244
|
+
spec.state = :enqueued
|
|
245
|
+
worker_pool.enq spec
|
|
200
246
|
end
|
|
201
247
|
end
|
|
202
248
|
end
|
|
@@ -189,21 +189,13 @@ module Bundler
|
|
|
189
189
|
standalone = options[:standalone]
|
|
190
190
|
force = options[:force]
|
|
191
191
|
local = options[:local] || options[:"prefer-local"]
|
|
192
|
-
jobs = installation_parallelization
|
|
192
|
+
jobs = Bundler.settings.installation_parallelization
|
|
193
193
|
spec_installations = ParallelInstaller.call(self, @definition.specs, jobs, standalone, force, local: local)
|
|
194
194
|
spec_installations.each do |installation|
|
|
195
195
|
post_install_messages[installation.name] = installation.post_install_message if installation.has_post_install_message?
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
|
|
199
|
-
def installation_parallelization
|
|
200
|
-
if jobs = Bundler.settings[:jobs]
|
|
201
|
-
return jobs
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
Bundler.settings.processor_count
|
|
205
|
-
end
|
|
206
|
-
|
|
207
199
|
def load_plugins
|
|
208
200
|
Gem.load_plugins
|
|
209
201
|
|
|
@@ -146,7 +146,7 @@ When set, no post install messages will be printed\. To silence a single gem, us
|
|
|
146
146
|
Generate a \fBgems\.rb\fR instead of a \fBGemfile\fR when running \fBbundle init\fR\.
|
|
147
147
|
.TP
|
|
148
148
|
\fBjobs\fR (\fBBUNDLE_JOBS\fR)
|
|
149
|
-
The number of gems Bundler can install in parallel\. Defaults to the number of available processors\.
|
|
149
|
+
The number of gems Bundler can download and install in parallel\. Defaults to the number of available processors\.
|
|
150
150
|
.TP
|
|
151
151
|
\fBlockfile\fR (\fBBUNDLE_LOCKFILE\fR)
|
|
152
152
|
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))\.
|
|
@@ -192,8 +192,8 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
|
|
192
192
|
* `init_gems_rb` (`BUNDLE_INIT_GEMS_RB`):
|
|
193
193
|
Generate a `gems.rb` instead of a `Gemfile` when running `bundle init`.
|
|
194
194
|
* `jobs` (`BUNDLE_JOBS`):
|
|
195
|
-
The number of gems Bundler can install in parallel.
|
|
196
|
-
available processors.
|
|
195
|
+
The number of gems Bundler can download and install in parallel.
|
|
196
|
+
Defaults to the number of available processors.
|
|
197
197
|
* `lockfile` (`BUNDLE_LOCKFILE`):
|
|
198
198
|
The path to the lockfile that bundler should use. By default, Bundler adds
|
|
199
199
|
`.lock` to the end of the `gemfile` entry. Can be set to `false` in the
|
|
@@ -74,6 +74,14 @@ module Bundler
|
|
|
74
74
|
{}
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
+
# Download the gem specified by the spec at appropriate path.
|
|
78
|
+
#
|
|
79
|
+
# A source plugin can implement this method to split the download and the
|
|
80
|
+
# installation of a gem.
|
|
81
|
+
#
|
|
82
|
+
# @return [Boolean] Whether the download of the gem succeeded.
|
|
83
|
+
def download(spec, opts); end
|
|
84
|
+
|
|
77
85
|
# Install the gem specified by the spec at appropriate path.
|
|
78
86
|
# `install_path` provides a sufficient default, if the source can only
|
|
79
87
|
# satisfy one gem, but is not binding.
|
|
@@ -5,6 +5,7 @@ module Bundler
|
|
|
5
5
|
class Strategy
|
|
6
6
|
def initialize(source)
|
|
7
7
|
@source = source
|
|
8
|
+
@package_priority_cache = {}
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
def next_package_and_version(unsatisfied)
|
|
@@ -17,10 +18,12 @@ module Bundler
|
|
|
17
18
|
|
|
18
19
|
def next_term_to_try_from(unsatisfied)
|
|
19
20
|
unsatisfied.min_by do |package, range|
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
@package_priority_cache[[package, range]] ||= begin
|
|
22
|
+
matching_versions = @source.versions_for(package, range)
|
|
23
|
+
higher_versions = @source.versions_for(package, range.upper_invert)
|
|
22
24
|
|
|
23
|
-
|
|
25
|
+
[matching_versions.count <= 1 ? 0 : 1, higher_versions.count]
|
|
26
|
+
end
|
|
24
27
|
end
|
|
25
28
|
end
|
|
26
29
|
|
|
@@ -353,9 +353,27 @@ module Bundler
|
|
|
353
353
|
message << "\n#{other_specs_matching_message(specs, matching_part)}"
|
|
354
354
|
end
|
|
355
355
|
|
|
356
|
+
if specs_matching_requirement.any? && (hint = platform_mismatch_hint)
|
|
357
|
+
message << "\n\n#{hint}"
|
|
358
|
+
end
|
|
359
|
+
|
|
356
360
|
raise GemNotFound, message
|
|
357
361
|
end
|
|
358
362
|
|
|
363
|
+
def platform_mismatch_hint
|
|
364
|
+
locked_platforms = Bundler.locked_gems&.platforms
|
|
365
|
+
return unless locked_platforms
|
|
366
|
+
|
|
367
|
+
local_platform = Bundler.local_platform
|
|
368
|
+
return if locked_platforms.include?(local_platform)
|
|
369
|
+
return if locked_platforms.any? {|p| p == Gem::Platform::RUBY }
|
|
370
|
+
|
|
371
|
+
"Your current platform (#{local_platform}) is not included in the lockfile's platforms (#{locked_platforms.join(", ")}). " \
|
|
372
|
+
"Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again."
|
|
373
|
+
rescue GemfileNotFound
|
|
374
|
+
nil
|
|
375
|
+
end
|
|
376
|
+
|
|
359
377
|
def filtered_versions_for(package)
|
|
360
378
|
@gem_version_promoter.filter_versions(package, @all_versions[package])
|
|
361
379
|
end
|
|
@@ -6,6 +6,8 @@ module Bundler
|
|
|
6
6
|
attr_accessor :name, :total_runs, :current_run
|
|
7
7
|
|
|
8
8
|
class << self
|
|
9
|
+
attr_accessor :default_base_delay
|
|
10
|
+
|
|
9
11
|
def default_attempts
|
|
10
12
|
default_retries + 1
|
|
11
13
|
end
|
|
@@ -16,11 +18,17 @@ module Bundler
|
|
|
16
18
|
end
|
|
17
19
|
end
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
# Set default base delay for exponential backoff
|
|
22
|
+
self.default_base_delay = 1.0
|
|
23
|
+
|
|
24
|
+
def initialize(name, exceptions = nil, retries = self.class.default_retries, opts = {})
|
|
20
25
|
@name = name
|
|
21
26
|
@retries = retries
|
|
22
27
|
@exceptions = Array(exceptions) || []
|
|
23
28
|
@total_runs = @retries + 1 # will run once, then upto attempts.times
|
|
29
|
+
@base_delay = opts[:base_delay] || self.class.default_base_delay
|
|
30
|
+
@max_delay = opts[:max_delay] || 60.0
|
|
31
|
+
@jitter = opts[:jitter] || 0.5
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
def attempt(&block)
|
|
@@ -48,9 +56,27 @@ module Bundler
|
|
|
48
56
|
Bundler.ui.info "" unless Bundler.ui.debug?
|
|
49
57
|
raise e
|
|
50
58
|
end
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
59
|
+
if name
|
|
60
|
+
Bundler.ui.info "" unless Bundler.ui.debug? # Add new line in case dots preceded this
|
|
61
|
+
Bundler.ui.warn "Retrying #{name} due to error (#{current_run.next}/#{total_runs}): #{e.class} #{e.message}", true
|
|
62
|
+
end
|
|
63
|
+
backoff_sleep if @base_delay > 0
|
|
64
|
+
true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def backoff_sleep
|
|
68
|
+
# Exponential backoff: delay = base_delay * 2^(attempt - 1)
|
|
69
|
+
# Add jitter to prevent thundering herd: random value between 0 and jitter seconds
|
|
70
|
+
delay = @base_delay * (2**(@current_run - 1))
|
|
71
|
+
delay = [@max_delay, delay].min
|
|
72
|
+
jitter_amount = rand * @jitter
|
|
73
|
+
total_delay = delay + jitter_amount
|
|
74
|
+
Bundler.ui.debug "Sleeping for #{total_delay.round(2)} seconds before retry"
|
|
75
|
+
sleep(total_delay)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def sleep(duration)
|
|
79
|
+
Kernel.sleep(duration)
|
|
54
80
|
end
|
|
55
81
|
|
|
56
82
|
def keep_trying?
|
|
@@ -74,6 +74,13 @@ module Bundler
|
|
|
74
74
|
fail!(key, value, "`#{other_key}` is current set to #{other_setting.inspect}", "the `#{conflicting.join("`, `")}` groups conflict")
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
|
+
|
|
78
|
+
rule %w[default_cli_command], "default_cli_command must be either 'install' or 'cli_help'" do |key, value, _settings|
|
|
79
|
+
valid_values = %w[install cli_help]
|
|
80
|
+
if !value.nil? && !valid_values.include?(value.to_s)
|
|
81
|
+
fail!(key, value, "must be one of: #{valid_values.join(", ")}")
|
|
82
|
+
end
|
|
83
|
+
end
|
|
77
84
|
end
|
|
78
85
|
end
|
|
79
86
|
end
|
|
@@ -59,6 +59,7 @@ module Bundler
|
|
|
59
59
|
bin
|
|
60
60
|
cache_path
|
|
61
61
|
console
|
|
62
|
+
default_cli_command
|
|
62
63
|
gem.ci
|
|
63
64
|
gem.github_username
|
|
64
65
|
gem.linter
|
|
@@ -303,6 +304,10 @@ module Bundler
|
|
|
303
304
|
@app_cache_path ||= self[:cache_path] || "vendor/cache"
|
|
304
305
|
end
|
|
305
306
|
|
|
307
|
+
def installation_parallelization
|
|
308
|
+
self[:jobs] || processor_count
|
|
309
|
+
end
|
|
310
|
+
|
|
306
311
|
def validate!
|
|
307
312
|
all.each do |raw_key|
|
|
308
313
|
[@local_config, @env_config, @global_config].each do |settings|
|
|
@@ -57,6 +57,29 @@ module Bundler
|
|
|
57
57
|
attr_accessor :path, :uri, :branch, :tag, :ref, :explicit_ref
|
|
58
58
|
attr_writer :revision
|
|
59
59
|
|
|
60
|
+
def self.version
|
|
61
|
+
@version ||= full_version[/((\.?\d+)+).*/, 1]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.full_version
|
|
65
|
+
@full_version ||= begin
|
|
66
|
+
raise GitNotInstalledError.new unless Bundler.git_present?
|
|
67
|
+
|
|
68
|
+
require "open3"
|
|
69
|
+
out, err, status = Open3.capture3("git", "--version")
|
|
70
|
+
|
|
71
|
+
raise GitCommandError.new("--version", SharedHelpers.pwd, err) unless status.success?
|
|
72
|
+
Bundler.ui.warn err unless err.empty?
|
|
73
|
+
|
|
74
|
+
out.sub(/git version\s*/, "").strip
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def self.reset
|
|
79
|
+
@version = nil
|
|
80
|
+
@full_version = nil
|
|
81
|
+
end
|
|
82
|
+
|
|
60
83
|
def initialize(path, uri, options = {}, revision = nil, git = nil)
|
|
61
84
|
@path = path
|
|
62
85
|
@uri = uri
|
|
@@ -92,11 +115,11 @@ module Bundler
|
|
|
92
115
|
end
|
|
93
116
|
|
|
94
117
|
def version
|
|
95
|
-
|
|
118
|
+
self.class.version
|
|
96
119
|
end
|
|
97
120
|
|
|
98
121
|
def full_version
|
|
99
|
-
|
|
122
|
+
self.class.full_version
|
|
100
123
|
end
|
|
101
124
|
|
|
102
125
|
def checkout
|
|
@@ -156,7 +179,7 @@ module Bundler
|
|
|
156
179
|
private
|
|
157
180
|
|
|
158
181
|
def git_remote_fetch(args)
|
|
159
|
-
command =
|
|
182
|
+
command = fetch_command(args)
|
|
160
183
|
command_with_no_credentials = check_allowed(command)
|
|
161
184
|
|
|
162
185
|
Bundler::Retry.new("`#{command_with_no_credentials}` at #{path}", [MissingGitRevisionError]).attempts do
|
|
@@ -166,6 +189,11 @@ module Bundler
|
|
|
166
189
|
if err.include?("couldn't find remote ref") || err.include?("not our ref")
|
|
167
190
|
raise MissingGitRevisionError.new(command_with_no_credentials, path, commit || explicit_ref, credential_filtered_uri)
|
|
168
191
|
else
|
|
192
|
+
if shallow?
|
|
193
|
+
args -= depth_args
|
|
194
|
+
command = fetch_command(args)
|
|
195
|
+
command_with_no_credentials = check_allowed(command)
|
|
196
|
+
end
|
|
169
197
|
raise GitCommandError.new(command_with_no_credentials, path, err)
|
|
170
198
|
end
|
|
171
199
|
end
|
|
@@ -178,7 +206,8 @@ module Bundler
|
|
|
178
206
|
FileUtils.mkdir_p(p)
|
|
179
207
|
end
|
|
180
208
|
|
|
181
|
-
|
|
209
|
+
clone_args = extra_clone_args
|
|
210
|
+
command = clone_command(clone_args)
|
|
182
211
|
command_with_no_credentials = check_allowed(command)
|
|
183
212
|
|
|
184
213
|
Bundler::Retry.new("`#{command_with_no_credentials}`", [MissingGitRevisionError]).attempts do
|
|
@@ -189,13 +218,10 @@ module Bundler
|
|
|
189
218
|
err.include?("Remote branch #{branch_option} not found") # git 2.49 or higher
|
|
190
219
|
raise MissingGitRevisionError.new(command_with_no_credentials, nil, explicit_ref, credential_filtered_uri)
|
|
191
220
|
else
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
command
|
|
195
|
-
command.delete_at(idx)
|
|
221
|
+
if shallow?
|
|
222
|
+
clone_args -= depth_args
|
|
223
|
+
command = clone_command(clone_args)
|
|
196
224
|
command_with_no_credentials = check_allowed(command)
|
|
197
|
-
|
|
198
|
-
err += "Retrying without --depth argument."
|
|
199
225
|
end
|
|
200
226
|
raise GitCommandError.new(command_with_no_credentials, path, err)
|
|
201
227
|
end
|
|
@@ -204,14 +230,14 @@ module Bundler
|
|
|
204
230
|
|
|
205
231
|
def clone_needs_unshallow?
|
|
206
232
|
return false unless path.join("shallow").exist?
|
|
207
|
-
return true
|
|
233
|
+
return true unless shallow?
|
|
208
234
|
|
|
209
235
|
@revision && @revision != head_revision
|
|
210
236
|
end
|
|
211
237
|
|
|
212
238
|
def extra_ref
|
|
213
239
|
return false if not_pinned?
|
|
214
|
-
return true
|
|
240
|
+
return true if shallow?
|
|
215
241
|
|
|
216
242
|
ref.start_with?("refs/")
|
|
217
243
|
end
|
|
@@ -427,8 +453,16 @@ module Bundler
|
|
|
427
453
|
args
|
|
428
454
|
end
|
|
429
455
|
|
|
456
|
+
def fetch_command(args)
|
|
457
|
+
["fetch", "--force", "--quiet", "--no-tags", *args, "--", configured_uri, refspec].compact
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def clone_command(args)
|
|
461
|
+
["clone", "--bare", "--no-hardlinks", "--quiet", *args, "--", configured_uri, path.to_s]
|
|
462
|
+
end
|
|
463
|
+
|
|
430
464
|
def depth_args
|
|
431
|
-
return []
|
|
465
|
+
return [] unless shallow?
|
|
432
466
|
|
|
433
467
|
["--depth", depth.to_s]
|
|
434
468
|
end
|
|
@@ -443,8 +477,8 @@ module Bundler
|
|
|
443
477
|
branch || tag
|
|
444
478
|
end
|
|
445
479
|
|
|
446
|
-
def
|
|
447
|
-
depth.nil?
|
|
480
|
+
def shallow?
|
|
481
|
+
!depth.nil?
|
|
448
482
|
end
|
|
449
483
|
|
|
450
484
|
def needs_allow_any_sha1_in_want?
|