rubygems-update 4.0.18 → 4.0.19
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 +15 -0
- data/bundler/CHANGELOG.md +20 -0
- data/bundler/lib/bundler/build_metadata.rb +1 -1
- data/bundler/lib/bundler/cli/common.rb +11 -0
- data/bundler/lib/bundler/cli/install.rb +1 -0
- data/bundler/lib/bundler/cli/lock.rb +7 -2
- data/bundler/lib/bundler/cli/update.rb +1 -0
- data/bundler/lib/bundler/cli.rb +3 -3
- data/bundler/lib/bundler/definition.rb +13 -3
- data/bundler/lib/bundler/endpoint_specification.rb +13 -0
- data/bundler/lib/bundler/installer.rb +6 -0
- data/bundler/lib/bundler/lockfile_generator.rb +16 -0
- data/bundler/lib/bundler/man/bundle-config.1 +2 -2
- data/bundler/lib/bundler/man/bundle-config.1.ronn +5 -5
- data/bundler/lib/bundler/resolver.rb +54 -1
- data/bundler/lib/bundler/source/git/git_proxy.rb +6 -5
- data/bundler/lib/bundler/version.rb +1 -1
- data/lib/rubygems/installer.rb +1 -1
- data/lib/rubygems/safe_marshal/reader.rb +20 -9
- data/lib/rubygems/safe_marshal/visitors/to_ruby.rb +8 -1
- data/lib/rubygems/specification.rb +27 -15
- data/lib/rubygems/uninstaller.rb +2 -1
- data/lib/rubygems.rb +6 -1
- 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: fea8148baa9550b989b52e1b5a5bdd0331ce3f3658acd4e6a8655b4aca669d05
|
|
4
|
+
data.tar.gz: d6873bcf37f0e87a7c35663e446b5a907a833d469270fce61e06e5c384b26b64
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 959ce199999beef457228f6ca8ef0d74f6cd19cb433fe5fdf21ec42961df13b81b98209a21bb2c6c298521b201cf2f64161be7efd5a3ac92d155a6c0c17876d0
|
|
7
|
+
data.tar.gz: eb602763996a439e8f8598b14c08ead139b527a814e11c9acdae89c4c1556ede07fed87cdde079509b124510f5f3844e394ef74e69e3a532c1900b271d684b14
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.19 / 2026-08-20
|
|
4
|
+
|
|
5
|
+
### Enhancements:
|
|
6
|
+
|
|
7
|
+
* Reject SafeMarshal collection lengths longer than the remaining input. Pull request [#9756](https://github.com/ruby/rubygems/pull/9756) by hsbt
|
|
8
|
+
* Installs bundler 4.0.19 as a default gem.
|
|
9
|
+
|
|
10
|
+
### Bug fixes:
|
|
11
|
+
|
|
12
|
+
* Fix gem uninstall --user-install crash when GEM_HOME does not exist. Pull request [#9749](https://github.com/ruby/rubygems/pull/9749) by hsbt
|
|
13
|
+
|
|
14
|
+
### Documentation:
|
|
15
|
+
|
|
16
|
+
* Document SPDX license handling for license= and licenses=. Pull request [#9766](https://github.com/ruby/rubygems/pull/9766) by hsbt
|
|
17
|
+
|
|
3
18
|
## 4.0.18 / 2026-08-05
|
|
4
19
|
|
|
5
20
|
### Enhancements:
|
data/bundler/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.19 / 2026-08-20
|
|
4
|
+
|
|
5
|
+
### Enhancements:
|
|
6
|
+
|
|
7
|
+
* Validate the platform field in Gem::Installer#verify_spec. Pull request [#9780](https://github.com/ruby/rubygems/pull/9780) by hsbt
|
|
8
|
+
* Restrict UserDefined handling to explicit class set for Gem::SafeMashal. Pull request [#9770](https://github.com/ruby/rubygems/pull/9770) by jackorp
|
|
9
|
+
* Filter git command output against the configured URI. Pull request [#9778](https://github.com/ruby/rubygems/pull/9778) by hsbt
|
|
10
|
+
* Summarize cooldown-skipped versions at the end of install, update, and lock. Pull request [#9762](https://github.com/ruby/rubygems/pull/9762) by hsbt
|
|
11
|
+
|
|
12
|
+
### Bug fixes:
|
|
13
|
+
|
|
14
|
+
* Make repeated bundle lock options accumulate. Pull request [#9748](https://github.com/ruby/rubygems/pull/9748) by hsbt
|
|
15
|
+
* Fail instead of warning when frozen mode can't update the lockfile. Pull request [#9750](https://github.com/ruby/rubygems/pull/9750) by hsbt
|
|
16
|
+
* Fix wrong $LOAD_PATH for gems installed in the same process. Pull request [#9784](https://github.com/ruby/rubygems/pull/9784) by hsbt
|
|
17
|
+
|
|
18
|
+
### Documentation:
|
|
19
|
+
|
|
20
|
+
* Fix auto-clean default version in bundle config docs. Pull request [#9783](https://github.com/ruby/rubygems/pull/9783) by hsbt
|
|
21
|
+
* Correct Bundler 5 default path documentation. Pull request [#9771](https://github.com/ruby/rubygems/pull/9771) by alloutflo
|
|
22
|
+
|
|
3
23
|
## 4.0.18 / 2026-08-05
|
|
4
24
|
|
|
5
25
|
### Enhancements:
|
|
@@ -20,6 +20,17 @@ module Bundler
|
|
|
20
20
|
Bundler.ui.info msg
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
def self.output_cooldown_skipped_summary(definition = Bundler.definition)
|
|
24
|
+
skipped = definition.cooldown_skipped
|
|
25
|
+
return if skipped.empty?
|
|
26
|
+
|
|
27
|
+
Bundler.ui.info "The following gem versions were skipped by the cooldown setting:"
|
|
28
|
+
skipped.each do |entry|
|
|
29
|
+
days = entry[:available_in_days]
|
|
30
|
+
Bundler.ui.info " * #{entry[:name]} #{entry[:version]} (available in #{days} #{days == 1 ? "day" : "days"}), resolved #{entry[:resolved]} instead"
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
23
34
|
def self.output_fund_metadata_summary
|
|
24
35
|
return if Bundler.settings["ignore_funding_requests"]
|
|
25
36
|
definition = Bundler.definition
|
|
@@ -26,6 +26,9 @@ module Bundler
|
|
|
26
26
|
Bundler::Fetcher.disable_endpoint = options["full-index"]
|
|
27
27
|
|
|
28
28
|
update = options[:update]
|
|
29
|
+
# --update is repeatable, so it parses as an array with one entry per
|
|
30
|
+
# occurrence, where a bare `--update` produces a `true` entry
|
|
31
|
+
update = update.include?(true) ? true : update.flatten if update.is_a?(Array)
|
|
29
32
|
conservative = options[:conservative]
|
|
30
33
|
bundler = options[:bundler]
|
|
31
34
|
|
|
@@ -44,12 +47,12 @@ module Bundler
|
|
|
44
47
|
|
|
45
48
|
Bundler::CLI::Common.configure_gem_version_promoter(definition, options) if options[:update]
|
|
46
49
|
|
|
47
|
-
options["remove-platform"].each do |platform_string|
|
|
50
|
+
options["remove-platform"].flatten.each do |platform_string|
|
|
48
51
|
platform = Gem::Platform.new(platform_string)
|
|
49
52
|
definition.remove_platform(platform)
|
|
50
53
|
end
|
|
51
54
|
|
|
52
|
-
options["add-platform"].each do |platform_string|
|
|
55
|
+
options["add-platform"].flatten.each do |platform_string|
|
|
53
56
|
platform = Gem::Platform.new(platform_string)
|
|
54
57
|
if platform.to_s == "unknown"
|
|
55
58
|
Bundler.ui.error "The platform `#{platform_string}` is unknown to RubyGems and can't be added to the lockfile."
|
|
@@ -77,6 +80,8 @@ module Bundler
|
|
|
77
80
|
puts "Writing lockfile to #{file}"
|
|
78
81
|
definition.write_lock(file, false)
|
|
79
82
|
end
|
|
83
|
+
|
|
84
|
+
Bundler::CLI::Common.output_cooldown_skipped_summary(definition)
|
|
80
85
|
end
|
|
81
86
|
|
|
82
87
|
Bundler.ui.output_stream = previous_output_stream
|
|
@@ -118,6 +118,7 @@ module Bundler
|
|
|
118
118
|
Bundler.ui.confirm "Bundle updated!"
|
|
119
119
|
Bundler::CLI::Common.output_without_groups_message(:update)
|
|
120
120
|
Bundler::CLI::Common.output_post_install_messages installer.post_install_messages
|
|
121
|
+
Bundler::CLI::Common.output_cooldown_skipped_summary
|
|
121
122
|
|
|
122
123
|
Bundler::CLI::Common.output_fund_metadata_summary
|
|
123
124
|
end
|
data/bundler/lib/bundler/cli.rb
CHANGED
|
@@ -626,15 +626,15 @@ module Bundler
|
|
|
626
626
|
end
|
|
627
627
|
|
|
628
628
|
desc "lock", "Creates a lockfile without installing"
|
|
629
|
-
method_option "update", type: :array, lazy_default: true, banner: "ignore the existing lockfile, update all gems by default, or update list of given gems"
|
|
629
|
+
method_option "update", type: :array, lazy_default: true, repeatable: true, banner: "ignore the existing lockfile, update all gems by default, or update list of given gems"
|
|
630
630
|
method_option "local", type: :boolean, default: false, banner: "do not attempt to fetch remote gemspecs and use the local gem cache only"
|
|
631
631
|
method_option "print", type: :boolean, default: false, banner: "print the lockfile to STDOUT instead of writing to the file system"
|
|
632
632
|
method_option "gemfile", type: :string, banner: "Use the specified gemfile instead of Gemfile"
|
|
633
633
|
method_option "lockfile", type: :string, default: nil, banner: "the path the lockfile should be written to"
|
|
634
634
|
method_option "full-index", type: :boolean, default: false, banner: "Fall back to using the single-file index of all gems"
|
|
635
635
|
method_option "add-checksums", type: :boolean, default: false, banner: "Adds checksums to the lockfile"
|
|
636
|
-
method_option "add-platform", type: :array, default: [], banner: "Add a new platform to the lockfile"
|
|
637
|
-
method_option "remove-platform", type: :array, default: [], banner: "Remove a platform from the lockfile"
|
|
636
|
+
method_option "add-platform", type: :array, default: [], repeatable: true, banner: "Add a new platform to the lockfile"
|
|
637
|
+
method_option "remove-platform", type: :array, default: [], repeatable: true, banner: "Remove a platform from the lockfile"
|
|
638
638
|
method_option "normalize-platforms", type: :boolean, default: false, banner: "Normalize lockfile platforms"
|
|
639
639
|
method_option "patch", type: :boolean, banner: "If updating, prefer updating only to next patch version"
|
|
640
640
|
method_option "minor", type: :boolean, banner: "If updating, prefer updating only to next minor version"
|
|
@@ -366,6 +366,12 @@ module Bundler
|
|
|
366
366
|
sources.git_sources.filter_map {|s| File.realpath(s.path) if File.exist?(s.path) }
|
|
367
367
|
end
|
|
368
368
|
|
|
369
|
+
# Versions excluded by cooldown during the last resolution, one entry per
|
|
370
|
+
# gem with the newest skipped version. Empty when no resolution ran.
|
|
371
|
+
def cooldown_skipped
|
|
372
|
+
@cooldown_skipped || []
|
|
373
|
+
end
|
|
374
|
+
|
|
369
375
|
def groups
|
|
370
376
|
dependencies.flat_map(&:groups).uniq
|
|
371
377
|
end
|
|
@@ -404,7 +410,7 @@ module Bundler
|
|
|
404
410
|
updating_major = locked_major < current_major
|
|
405
411
|
end
|
|
406
412
|
|
|
407
|
-
preserve_unknown_sections ||=
|
|
413
|
+
preserve_unknown_sections ||= Bundler.frozen_bundle? || (!updating_major && !(unlocking? || @unlocking_bundler))
|
|
408
414
|
|
|
409
415
|
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
|
410
416
|
return if Bundler.frozen_bundle?
|
|
@@ -413,8 +419,10 @@ module Bundler
|
|
|
413
419
|
end
|
|
414
420
|
|
|
415
421
|
if Bundler.frozen_bundle?
|
|
416
|
-
|
|
417
|
-
|
|
422
|
+
msg = lockfile_changes_summary("frozen mode is set") ||
|
|
423
|
+
"Your lockfile needs to be updated, but it can't be because frozen mode is set.\n\n" \
|
|
424
|
+
"Run `bundle install` elsewhere and add the updated #{SharedHelpers.relative_lockfile_path} to version control."
|
|
425
|
+
raise ProductionError, msg
|
|
418
426
|
end
|
|
419
427
|
|
|
420
428
|
# Convert to \r\n if the existing lock has them, i.e., Windows with
|
|
@@ -770,6 +778,8 @@ module Bundler
|
|
|
770
778
|
|
|
771
779
|
result = SpecSet.new(resolver.start)
|
|
772
780
|
|
|
781
|
+
@cooldown_skipped = resolver.cooldown_skipped
|
|
782
|
+
|
|
773
783
|
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
|
|
774
784
|
|
|
775
785
|
@new_platforms.each do |platform|
|
|
@@ -50,6 +50,19 @@ module Bundler
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
+
# `require_paths` is overridden above, but `full_require_paths` (and so
|
|
54
|
+
# `load_paths`) is computed from `raw_require_paths`, which would otherwise
|
|
55
|
+
# report the default `lib` for every gem
|
|
56
|
+
def raw_require_paths
|
|
57
|
+
if @remote_specification
|
|
58
|
+
@remote_specification.raw_require_paths
|
|
59
|
+
elsif _local_specification
|
|
60
|
+
_local_specification.raw_require_paths
|
|
61
|
+
else
|
|
62
|
+
super
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
53
66
|
# needed for inline
|
|
54
67
|
def load_paths
|
|
55
68
|
# remote specs aren't installed, and can't have load_paths
|
|
@@ -83,6 +83,12 @@ module Bundler
|
|
|
83
83
|
install(options)
|
|
84
84
|
|
|
85
85
|
Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available
|
|
86
|
+
# Drop the source caches too, since releasing resolution memory dropped
|
|
87
|
+
# the source indexes. A resolution happening after this point would
|
|
88
|
+
# otherwise rebuild them around a snapshot of installed gems taken
|
|
89
|
+
# before the install, and materialize against remote specs that don't
|
|
90
|
+
# know where the gems they stand for ended up.
|
|
91
|
+
@definition.sources.clear_cache
|
|
86
92
|
|
|
87
93
|
lock
|
|
88
94
|
Standalone.new(options[:standalone], @definition).generate if options[:standalone]
|
|
@@ -103,6 +103,11 @@ module Bundler
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def bundler_checksum
|
|
106
|
+
# In frozen mode the lockfile can't change, so reproduce whatever bundler
|
|
107
|
+
# entry is already locked instead of recording one for the running bundler
|
|
108
|
+
# version, which may legitimately differ from the locked one.
|
|
109
|
+
return locked_bundler_checksum if Bundler.frozen_bundle?
|
|
110
|
+
|
|
106
111
|
# `.dev` versions and `SKIP_BUNDLER_CHECKSUM` are deliberate opt-outs (used
|
|
107
112
|
# by Bundler/RubyGems' own development and release tasks): never record a
|
|
108
113
|
# checksum for Bundler itself in those cases.
|
|
@@ -138,5 +143,16 @@ module Bundler
|
|
|
138
143
|
|
|
139
144
|
locked_gems.bundler_version != definition.bundler_version_to_lock
|
|
140
145
|
end
|
|
146
|
+
|
|
147
|
+
def locked_bundler_checksum
|
|
148
|
+
locked_version = definition.locked_gems&.bundler_version
|
|
149
|
+
return [] unless locked_version
|
|
150
|
+
|
|
151
|
+
metadata_source = definition.sources.metadata_source
|
|
152
|
+
locked_spec = LazySpecification.new("bundler", locked_version, Gem::Platform::RUBY, metadata_source)
|
|
153
|
+
return [] if metadata_source.checksum_store.missing?(locked_spec)
|
|
154
|
+
|
|
155
|
+
[metadata_source.checksum_store.to_lock(locked_spec)]
|
|
156
|
+
end
|
|
141
157
|
end
|
|
142
158
|
end
|
|
@@ -82,7 +82,7 @@ The following is a list of all configuration keys and their purpose\. You can le
|
|
|
82
82
|
.IP "\(bu" 4
|
|
83
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
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
|
|
85
|
+
\fBclean\fR (\fBBUNDLE_CLEAN\fR): Whether Bundler should run \fBbundle clean\fR automatically after \fBbundle install\fR\. Defaults to \fBtrue\fR in Bundler 5, as long as \fBpath\fR is not explicitly configured\.
|
|
86
86
|
.IP "\(bu" 4
|
|
87
87
|
\fBconsole\fR (\fBBUNDLE_CONSOLE\fR): The console that \fBbundle console\fR starts\. Defaults to \fBirb\fR\.
|
|
88
88
|
.IP "\(bu" 4
|
|
@@ -147,7 +147,7 @@ Cooldown filtering depends on the gem server providing a per\-version \fBcreated
|
|
|
147
147
|
.IP "\(bu" 4
|
|
148
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
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
|
|
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 5, and to the default system path (\fBGem\.dir\fR) before Bundler 5\. That means that before Bundler 5, 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 5\.
|
|
151
151
|
.IP "\(bu" 4
|
|
152
152
|
\fBpath\.system\fR (\fBBUNDLE_PATH__SYSTEM\fR): Whether Bundler will install gems into the default system path (\fBGem\.dir\fR)\.
|
|
153
153
|
.IP "\(bu" 4
|
|
@@ -133,7 +133,7 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
|
|
133
133
|
Defaults to `vendor/cache`.
|
|
134
134
|
* `clean` (`BUNDLE_CLEAN`):
|
|
135
135
|
Whether Bundler should run `bundle clean` automatically after
|
|
136
|
-
`bundle install`. Defaults to `true` in Bundler
|
|
136
|
+
`bundle install`. Defaults to `true` in Bundler 5, as long as `path` is not
|
|
137
137
|
explicitly configured.
|
|
138
138
|
* `console` (`BUNDLE_CONSOLE`):
|
|
139
139
|
The console that `bundle console` starts. Defaults to `irb`.
|
|
@@ -245,12 +245,12 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
|
|
245
245
|
The location on disk where all gems in your bundle will be located regardless
|
|
246
246
|
of `$GEM_HOME` or `$GEM_PATH` values. Bundle gems not found in this location
|
|
247
247
|
will be installed by `bundle install`. When not set, Bundler install by
|
|
248
|
-
default to a `.bundle` directory relative to repository root in Bundler
|
|
249
|
-
and to the default system path (`Gem.dir`) before Bundler
|
|
250
|
-
before Bundler
|
|
248
|
+
default to a `.bundle` directory relative to repository root in Bundler 5,
|
|
249
|
+
and to the default system path (`Gem.dir`) before Bundler 5. That means that
|
|
250
|
+
before Bundler 5, Bundler shares this location with Rubygems, and `gem
|
|
251
251
|
install ...` will have gems installed in the same location and therefore,
|
|
252
252
|
gems installed without `path` set will show up by calling `gem list`. This
|
|
253
|
-
will not be the case in Bundler
|
|
253
|
+
will not be the case in Bundler 5.
|
|
254
254
|
* `path.system` (`BUNDLE_PATH__SYSTEM`):
|
|
255
255
|
Whether Bundler will install gems into the default system path (`Gem.dir`).
|
|
256
256
|
* `plugins` (`BUNDLE_PLUGINS`):
|
|
@@ -14,11 +14,15 @@ module Bundler
|
|
|
14
14
|
require_relative "resolver/root"
|
|
15
15
|
require_relative "resolver/strategy"
|
|
16
16
|
|
|
17
|
+
attr_reader :cooldown_skipped
|
|
18
|
+
|
|
17
19
|
def initialize(base, gem_version_promoter, most_specific_locked_platform = nil)
|
|
18
20
|
@source_requirements = base.source_requirements
|
|
19
21
|
@base = base
|
|
20
22
|
@gem_version_promoter = gem_version_promoter
|
|
21
23
|
@most_specific_locked_platform = most_specific_locked_platform
|
|
24
|
+
@cooldown_skipped = []
|
|
25
|
+
@cooldown_skipped_specs = {}
|
|
22
26
|
end
|
|
23
27
|
|
|
24
28
|
def start
|
|
@@ -36,6 +40,8 @@ module Bundler
|
|
|
36
40
|
root = Resolver::Root.new(name_for_explicit_dependency_source)
|
|
37
41
|
root_version = Resolver::Candidate.new(0)
|
|
38
42
|
|
|
43
|
+
@cooldown_skipped_specs = {}
|
|
44
|
+
|
|
39
45
|
@all_specs = Hash.new do |specs, name|
|
|
40
46
|
source = source_for(name)
|
|
41
47
|
matches = source.specs.search(name)
|
|
@@ -80,7 +86,9 @@ module Bundler
|
|
|
80
86
|
solver = PubGrub::VersionSolver.new(source: self, root: root, strategy: Strategy.new(self), logger: logger)
|
|
81
87
|
result = solver.solve
|
|
82
88
|
resolved_specs = result.flat_map {|package, version| version.to_specs(package, @most_specific_locked_platform) }
|
|
83
|
-
SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs)
|
|
89
|
+
spec_set = SpecSet.new(resolved_specs).specs_with_additional_variants_from(@base.locked_specs)
|
|
90
|
+
@cooldown_skipped = cooldown_skipped_summary(spec_set)
|
|
91
|
+
spec_set
|
|
84
92
|
rescue PubGrub::SolveFailure => e
|
|
85
93
|
incompatibility = e.incompatibility
|
|
86
94
|
|
|
@@ -424,6 +432,7 @@ module Bundler
|
|
|
424
432
|
specs.each do |spec|
|
|
425
433
|
next unless cooldown_excluded?(spec)
|
|
426
434
|
excluded[[spec.name, spec.version]] = true
|
|
435
|
+
(@cooldown_skipped_specs ||= {})[[spec.name, spec.version]] ||= spec
|
|
427
436
|
end
|
|
428
437
|
excluded
|
|
429
438
|
end
|
|
@@ -466,6 +475,50 @@ module Bundler
|
|
|
466
475
|
@cooldown_now ||= Time.now
|
|
467
476
|
end
|
|
468
477
|
|
|
478
|
+
# Reports, per gem, the newest version that cooldown kept out of a
|
|
479
|
+
# successful resolution. A skipped version is only worth reporting when it
|
|
480
|
+
# is newer than the resolved version and satisfies every requirement the
|
|
481
|
+
# final resolution places on that gem, so we don't claim a version the
|
|
482
|
+
# resolver could never have picked anyway.
|
|
483
|
+
def cooldown_skipped_summary(spec_set)
|
|
484
|
+
return [] if @cooldown_skipped_specs.empty?
|
|
485
|
+
|
|
486
|
+
requirements = Hash.new {|h, name| h[name] = [] }
|
|
487
|
+
@requirements.each {|dep| requirements[dep.name] << dep.requirement }
|
|
488
|
+
spec_set.each do |spec|
|
|
489
|
+
spec.dependencies.each {|dep| requirements[dep.name] << dep.requirement }
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
resolved_versions = {}
|
|
493
|
+
spec_set.each do |spec|
|
|
494
|
+
version = resolved_versions[spec.name]
|
|
495
|
+
resolved_versions[spec.name] = spec.version if version.nil? || spec.version > version
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
newest_skipped = {}
|
|
499
|
+
@cooldown_skipped_specs.each do |(name, version), spec|
|
|
500
|
+
resolved = resolved_versions[name]
|
|
501
|
+
next unless resolved && version > resolved
|
|
502
|
+
next unless requirements[name].all? {|req| req.satisfied_by?(version) }
|
|
503
|
+
newest = newest_skipped[name]
|
|
504
|
+
newest_skipped[name] = spec if newest.nil? || version > newest.version
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
newest_skipped.values.sort_by(&:name).map do |spec|
|
|
508
|
+
{
|
|
509
|
+
name: spec.name,
|
|
510
|
+
version: spec.version,
|
|
511
|
+
resolved: resolved_versions[spec.name],
|
|
512
|
+
available_in_days: remaining_cooldown_days(spec),
|
|
513
|
+
}
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def remaining_cooldown_days(spec)
|
|
518
|
+
remaining = (spec.remote.effective_cooldown * 86_400) - (cooldown_now - spec.created_at)
|
|
519
|
+
[(remaining / 86_400.0).ceil, 1].max
|
|
520
|
+
end
|
|
521
|
+
|
|
469
522
|
def filter_remote_specs(specs, package)
|
|
470
523
|
if package.prefer_local?
|
|
471
524
|
local_specs = specs.select {|s| s.is_a?(StubSpecification) }
|
|
@@ -364,9 +364,10 @@ module Bundler
|
|
|
364
364
|
git("rev-parse", "--verify", reference, dir: path).strip
|
|
365
365
|
end
|
|
366
366
|
|
|
367
|
-
# Adds credentials to the URI
|
|
367
|
+
# Adds credentials to the URI. This is the URI given to git, so it's
|
|
368
|
+
# also the one command output must be filtered against.
|
|
368
369
|
def configured_uri
|
|
369
|
-
if /https?:/.match?(uri)
|
|
370
|
+
@configured_uri ||= if /https?:/.match?(uri)
|
|
370
371
|
remote = Gem::URI(uri)
|
|
371
372
|
config_auth = Bundler.settings[remote.to_s] || Bundler.settings[remote.host]
|
|
372
373
|
remote.userinfo ||= config_auth
|
|
@@ -409,7 +410,7 @@ module Bundler
|
|
|
409
410
|
raise GitNotInstalledError.new unless Bundler.git_present?
|
|
410
411
|
|
|
411
412
|
require "shellwords"
|
|
412
|
-
URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}",
|
|
413
|
+
URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", configured_uri)
|
|
413
414
|
end
|
|
414
415
|
|
|
415
416
|
def run_command(*command, dir: nil)
|
|
@@ -429,10 +430,10 @@ module Bundler
|
|
|
429
430
|
require "open3"
|
|
430
431
|
out, err, status = Open3.capture3(*capture3_args_for(cmd, dir))
|
|
431
432
|
|
|
432
|
-
filtered_out = URICredentialsFilter.credential_filtered_string(out,
|
|
433
|
+
filtered_out = URICredentialsFilter.credential_filtered_string(out, configured_uri)
|
|
433
434
|
return [filtered_out, status] if ignore_err
|
|
434
435
|
|
|
435
|
-
filtered_err = URICredentialsFilter.credential_filtered_string(err,
|
|
436
|
+
filtered_err = URICredentialsFilter.credential_filtered_string(err, configured_uri)
|
|
436
437
|
[filtered_out, filtered_err, status]
|
|
437
438
|
end
|
|
438
439
|
end
|
data/lib/rubygems/installer.rb
CHANGED
|
@@ -692,7 +692,7 @@ class Gem::Installer
|
|
|
692
692
|
raise Gem::InstallError, "#{spec} has an invalid extensions"
|
|
693
693
|
end
|
|
694
694
|
|
|
695
|
-
|
|
695
|
+
unless /\A[\w.-]+\z/.match?(spec.platform.to_s)
|
|
696
696
|
raise Gem::InstallError, "#{spec.platform} is an invalid platform"
|
|
697
697
|
end
|
|
698
698
|
|
|
@@ -26,6 +26,9 @@ module Gem
|
|
|
26
26
|
class NegativeLengthError < Error
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
class LengthTooLongError < Error
|
|
30
|
+
end
|
|
31
|
+
|
|
29
32
|
def initialize(io)
|
|
30
33
|
@io = io
|
|
31
34
|
@object_links = {}
|
|
@@ -93,6 +96,18 @@ module Gem
|
|
|
93
96
|
end
|
|
94
97
|
end
|
|
95
98
|
|
|
99
|
+
# Reads an element count and validates it against the number of bytes
|
|
100
|
+
# remaining in the input, since each element to be read consumes at
|
|
101
|
+
# least one byte. This prevents allocating huge backing stores for
|
|
102
|
+
# maliciously crafted lengths that could never be satisfied.
|
|
103
|
+
def read_count
|
|
104
|
+
count = read_integer
|
|
105
|
+
raise NegativeLengthError if count < 0
|
|
106
|
+
remaining = @io.size - @io.pos
|
|
107
|
+
raise LengthTooLongError, "expected #{count} elements, but only #{remaining} bytes remain" if count > remaining
|
|
108
|
+
count
|
|
109
|
+
end
|
|
110
|
+
|
|
96
111
|
def read_element
|
|
97
112
|
type = read_byte
|
|
98
113
|
case type
|
|
@@ -172,9 +187,8 @@ module Gem
|
|
|
172
187
|
private_constant :EMPTY_ARRAY
|
|
173
188
|
|
|
174
189
|
def read_array
|
|
175
|
-
length =
|
|
190
|
+
length = read_count
|
|
176
191
|
return EMPTY_ARRAY if length == 0
|
|
177
|
-
raise NegativeLengthError if length < 0
|
|
178
192
|
elements = Array.new(length) do
|
|
179
193
|
read_element
|
|
180
194
|
end
|
|
@@ -183,8 +197,7 @@ module Gem
|
|
|
183
197
|
|
|
184
198
|
def read_object_with_ivars
|
|
185
199
|
object = read_element
|
|
186
|
-
length =
|
|
187
|
-
raise NegativeLengthError if length < 0
|
|
200
|
+
length = read_count
|
|
188
201
|
ivars = Array.new(length) do
|
|
189
202
|
[read_element, read_element]
|
|
190
203
|
end
|
|
@@ -211,7 +224,7 @@ module Gem
|
|
|
211
224
|
private_constant :EMPTY_HASH
|
|
212
225
|
|
|
213
226
|
def read_hash
|
|
214
|
-
length =
|
|
227
|
+
length = read_count
|
|
215
228
|
return EMPTY_HASH if length == 0
|
|
216
229
|
pairs = Array.new(length) do
|
|
217
230
|
[read_element, read_element]
|
|
@@ -220,8 +233,7 @@ module Gem
|
|
|
220
233
|
end
|
|
221
234
|
|
|
222
235
|
def read_hash_with_default_value
|
|
223
|
-
length =
|
|
224
|
-
raise NegativeLengthError if length < 0
|
|
236
|
+
length = read_count
|
|
225
237
|
pairs = Array.new(length) do
|
|
226
238
|
[read_element, read_element]
|
|
227
239
|
end
|
|
@@ -232,8 +244,7 @@ module Gem
|
|
|
232
244
|
def read_object
|
|
233
245
|
name = read_element
|
|
234
246
|
object = Elements::Object.new(name)
|
|
235
|
-
length =
|
|
236
|
-
raise NegativeLengthError if length < 0
|
|
247
|
+
length = read_count
|
|
237
248
|
ivars = Array.new(length) do
|
|
238
249
|
[read_element, read_element]
|
|
239
250
|
end
|
|
@@ -183,8 +183,15 @@ module Gem::SafeMarshal
|
|
|
183
183
|
@symbols.fetch(o.offset)
|
|
184
184
|
end
|
|
185
185
|
|
|
186
|
+
SAFE_USER_DEFINED_CLASSES = [::Time, ::Gem::Specification].freeze
|
|
187
|
+
private_constant :SAFE_USER_DEFINED_CLASSES
|
|
188
|
+
|
|
186
189
|
def visit_Gem_SafeMarshal_Elements_UserDefined(o)
|
|
187
|
-
|
|
190
|
+
klass = resolve_class(o.name)
|
|
191
|
+
unless SAFE_USER_DEFINED_CLASSES.include?(klass)
|
|
192
|
+
raise UnsupportedError.new("Unsupported user-defined class #{klass} in marshal stream", stack: formatted_stack)
|
|
193
|
+
end
|
|
194
|
+
register_object(call_method(klass, :_load, o.binary_string))
|
|
188
195
|
end
|
|
189
196
|
|
|
190
197
|
def visit_Gem_SafeMarshal_Elements_UserMarshal(o)
|
|
@@ -327,21 +327,30 @@ class Gem::Specification < Gem::BasicSpecification
|
|
|
327
327
|
##
|
|
328
328
|
# The license for this gem.
|
|
329
329
|
#
|
|
330
|
-
# The license must be no more than 64 characters
|
|
331
|
-
#
|
|
332
|
-
# This should just be the name of your license. The full text of the license
|
|
333
|
-
# should be inside of the gem (at the top level) when you build it.
|
|
334
|
-
#
|
|
335
|
-
# The simplest way is to specify the standard SPDX ID
|
|
336
|
-
# https://spdx.org/licenses/ for the license.
|
|
330
|
+
# The license must be no more than 64 characters, and should be a single
|
|
331
|
+
# SPDX license identifier from https://spdx.org/licenses/.
|
|
337
332
|
# Ideally, you should pick one that is OSI (Open Source Initiative)
|
|
338
333
|
# https://opensource.org/licenses/ approved.
|
|
339
334
|
#
|
|
340
335
|
# The most commonly used OSI-approved licenses are MIT and Apache-2.0.
|
|
341
336
|
# GitHub also provides a license picker at https://choosealicense.com/.
|
|
342
337
|
#
|
|
343
|
-
#
|
|
344
|
-
#
|
|
338
|
+
# The full text of the license should be inside of the gem (at the top
|
|
339
|
+
# level) when you build it.
|
|
340
|
+
#
|
|
341
|
+
# RubyGems validates the license against the SPDX license list when you
|
|
342
|
+
# run <tt>gem build</tt> and warns about unknown or deprecated identifiers.
|
|
343
|
+
# An identifier may carry a trailing <tt>+</tt> (this version or any later
|
|
344
|
+
# version) and a license exception joined with WITH, for example
|
|
345
|
+
# <tt>Apache-2.0 WITH LLVM-exception</tt>.
|
|
346
|
+
#
|
|
347
|
+
# Compound SPDX license expressions such as <tt>MIT OR Apache-2.0</tt> are
|
|
348
|
+
# not currently supported. RubyGems treats the whole string as a single
|
|
349
|
+
# identifier and warns that it is invalid. For a gem available under more
|
|
350
|
+
# than one license, set each license as a separate entry with #licenses=.
|
|
351
|
+
#
|
|
352
|
+
# For a license that has no SPDX identifier, use Nonstandard, or
|
|
353
|
+
# LicenseRef-<idstring> where idstring is the name of the file containing
|
|
345
354
|
# the license text.
|
|
346
355
|
#
|
|
347
356
|
# You should specify a license for your gem so that people know how they are
|
|
@@ -349,8 +358,6 @@ class Gem::Specification < Gem::BasicSpecification
|
|
|
349
358
|
# specifying a license means all rights are reserved; others have no right
|
|
350
359
|
# to use the code for any purpose.
|
|
351
360
|
#
|
|
352
|
-
# You can set multiple licenses with #licenses=
|
|
353
|
-
#
|
|
354
361
|
# Usage:
|
|
355
362
|
# spec.license = 'MIT'
|
|
356
363
|
|
|
@@ -361,15 +368,20 @@ class Gem::Specification < Gem::BasicSpecification
|
|
|
361
368
|
##
|
|
362
369
|
# The license(s) for the library.
|
|
363
370
|
#
|
|
364
|
-
# Each
|
|
371
|
+
# Each entry must be a single SPDX license identifier, no more than 64
|
|
372
|
+
# characters. Entries are validated independently, so a compound expression
|
|
373
|
+
# such as <tt>MIT OR Apache-2.0</tt> is not valid as an entry. Listing the
|
|
374
|
+
# identifiers as separate array elements is currently the only way RubyGems
|
|
375
|
+
# supports declaring a dual- or multi-licensed gem.
|
|
365
376
|
#
|
|
366
|
-
#
|
|
367
|
-
# text of
|
|
377
|
+
# Note that the array itself does not state how the licenses combine.
|
|
378
|
+
# Include the full text of each license in the gem and describe the exact
|
|
379
|
+
# terms there.
|
|
368
380
|
#
|
|
369
381
|
# See #license= for more discussion
|
|
370
382
|
#
|
|
371
383
|
# Usage:
|
|
372
|
-
# spec.licenses = ['MIT', 'GPL-2.0']
|
|
384
|
+
# spec.licenses = ['MIT', 'GPL-2.0-only']
|
|
373
385
|
|
|
374
386
|
def licenses=(licenses)
|
|
375
387
|
@licenses = Array licenses
|
data/lib/rubygems/uninstaller.rb
CHANGED
|
@@ -64,7 +64,8 @@ class Gem::Uninstaller
|
|
|
64
64
|
@gem = gem
|
|
65
65
|
@version = options[:version] || Gem::Requirement.default
|
|
66
66
|
@install_dir = options[:install_dir]
|
|
67
|
-
|
|
67
|
+
gem_home = @install_dir || Gem.dir
|
|
68
|
+
@gem_home = File.exist?(gem_home) ? File.realpath(gem_home) : gem_home
|
|
68
69
|
@user_dir = File.exist?(Gem.user_dir) ? File.realpath(Gem.user_dir) : Gem.user_dir
|
|
69
70
|
@force_executables = options[:executables]
|
|
70
71
|
@force_all = options[:all]
|
data/lib/rubygems.rb
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
require "rbconfig"
|
|
10
10
|
|
|
11
11
|
module Gem
|
|
12
|
-
VERSION = "4.0.
|
|
12
|
+
VERSION = "4.0.19"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
require_relative "rubygems/defaults"
|
|
@@ -1456,4 +1456,9 @@ else
|
|
|
1456
1456
|
end
|
|
1457
1457
|
eval File.read(path), nil, file
|
|
1458
1458
|
|
|
1459
|
+
# bundler/setup has to run before error_highlight, did_you_mean and
|
|
1460
|
+
# syntax_suggest are loaded, so that the Gemfile controls their versions
|
|
1461
|
+
# ([Bug #19089]). Ruby 4.1 autoloads them ([Feature #21951]) and deletes this
|
|
1462
|
+
# variable while loading RubyGems, so this can go once 4.1 is the oldest
|
|
1463
|
+
# supported version.
|
|
1459
1464
|
require ENV["BUNDLER_SETUP"] if ENV["BUNDLER_SETUP"] && !defined?(Bundler)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubygems-update
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.
|
|
4
|
+
version: 4.0.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jim Weirich
|
|
@@ -723,7 +723,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
723
723
|
- !ruby/object:Gem::Version
|
|
724
724
|
version: '0'
|
|
725
725
|
requirements: []
|
|
726
|
-
rubygems_version:
|
|
726
|
+
rubygems_version: 3.6.9
|
|
727
727
|
specification_version: 4
|
|
728
728
|
summary: RubyGems is a package management framework for Ruby. This gem is downloaded
|
|
729
729
|
and installed by `gem update --system`, so that the `gem` CLI can update itself.
|