rubygems-update 3.2.2 → 3.2.3
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/History.txt +12 -0
- data/Manifest.txt +2 -0
- data/bundler/CHANGELOG.md +9 -0
- data/bundler/lib/bundler.rb +3 -6
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli/update.rb +1 -1
- data/bundler/lib/bundler/compact_index_client/cache.rb +5 -13
- data/bundler/lib/bundler/compact_index_client/gem_parser.rb +28 -0
- data/bundler/lib/bundler/definition.rb +26 -14
- data/bundler/lib/bundler/gem_helpers.rb +30 -24
- data/bundler/lib/bundler/lazy_specification.rb +10 -11
- data/bundler/lib/bundler/resolver/spec_group.rb +14 -16
- data/bundler/lib/bundler/rubygems_integration.rb +0 -5
- data/bundler/lib/bundler/spec_set.rb +5 -8
- data/bundler/lib/bundler/version.rb +1 -1
- data/lib/rubygems.rb +1 -1
- data/lib/rubygems/dependency_installer.rb +1 -0
- data/lib/rubygems/gemcutter_utilities.rb +2 -2
- data/lib/rubygems/installer.rb +0 -23
- data/lib/rubygems/remote_fetcher.rb +1 -1
- data/lib/rubygems/request_set.rb +2 -13
- data/lib/rubygems/resolver.rb +6 -1
- data/lib/rubygems/resolver/api_set.rb +28 -19
- data/lib/rubygems/resolver/api_set/gem_parser.rb +20 -0
- data/lib/rubygems/resolver/api_specification.rb +4 -3
- data/lib/rubygems/resolver/best_set.rb +1 -1
- data/lib/rubygems/resolver/index_specification.rb +15 -0
- data/lib/rubygems/resolver/installer_set.rb +57 -7
- data/lib/rubygems/resolver/spec_specification.rb +14 -0
- data/lib/rubygems/resolver/specification.rb +12 -0
- data/lib/rubygems/source.rb +10 -6
- data/rubygems-update.gemspec +1 -1
- data/test/rubygems/test_gem_commands_install_command.rb +131 -0
- data/test/rubygems/test_gem_installer.rb +6 -60
- data/test/rubygems/test_gem_resolver_api_set.rb +26 -52
- data/test/rubygems/test_gem_resolver_api_specification.rb +3 -3
- data/test/rubygems/test_gem_resolver_best_set.rb +3 -3
- data/test/rubygems/test_gem_source.rb +2 -2
- data/test/rubygems/test_gem_source_subpath_problem.rb +2 -2
- metadata +5 -3
data/lib/rubygems.rb
CHANGED
@@ -286,6 +286,7 @@ class Gem::DependencyInstaller
|
|
286
286
|
|
287
287
|
installer_set = Gem::Resolver::InstallerSet.new @domain
|
288
288
|
installer_set.ignore_installed = (@minimal_deps == false) || @only_install_dir
|
289
|
+
installer_set.force = @force
|
289
290
|
|
290
291
|
if consider_local?
|
291
292
|
if dep_or_name =~ /\.gem$/ and File.file? dep_or_name
|
@@ -260,8 +260,8 @@ module Gem::GemcutterUtilities
|
|
260
260
|
end
|
261
261
|
|
262
262
|
def get_key_name(scope)
|
263
|
-
hostname = Socket.gethostname || "
|
264
|
-
user = ENV["USER"] || ENV["USERNAME"] || "
|
263
|
+
hostname = Socket.gethostname || "unknown-host"
|
264
|
+
user = ENV["USER"] || ENV["USERNAME"] || "unknown-user"
|
265
265
|
ts = Time.now.strftime("%Y%m%d%H%M%S")
|
266
266
|
default_key_name = "#{hostname}-#{user}-#{ts}"
|
267
267
|
|
data/lib/rubygems/installer.rb
CHANGED
@@ -638,27 +638,6 @@ class Gem::Installer
|
|
638
638
|
end
|
639
639
|
end
|
640
640
|
|
641
|
-
def ensure_required_ruby_version_met # :nodoc:
|
642
|
-
if rrv = spec.required_ruby_version
|
643
|
-
ruby_version = Gem.ruby_version
|
644
|
-
unless rrv.satisfied_by? ruby_version
|
645
|
-
raise Gem::RuntimeRequirementNotMetError,
|
646
|
-
"#{spec.name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}."
|
647
|
-
end
|
648
|
-
end
|
649
|
-
end
|
650
|
-
|
651
|
-
def ensure_required_rubygems_version_met # :nodoc:
|
652
|
-
if rrgv = spec.required_rubygems_version
|
653
|
-
unless rrgv.satisfied_by? Gem.rubygems_version
|
654
|
-
rg_version = Gem::VERSION
|
655
|
-
raise Gem::RuntimeRequirementNotMetError,
|
656
|
-
"#{spec.name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
|
657
|
-
"Try 'gem update --system' to update RubyGems itself."
|
658
|
-
end
|
659
|
-
end
|
660
|
-
end
|
661
|
-
|
662
641
|
def ensure_dependencies_met # :nodoc:
|
663
642
|
deps = spec.runtime_dependencies
|
664
643
|
deps |= spec.development_dependencies if @development
|
@@ -914,8 +893,6 @@ TEXT
|
|
914
893
|
|
915
894
|
return true if @force
|
916
895
|
|
917
|
-
ensure_required_ruby_version_met
|
918
|
-
ensure_required_rubygems_version_met
|
919
896
|
ensure_dependencies_met unless @ignore_dependencies
|
920
897
|
|
921
898
|
true
|
@@ -215,7 +215,7 @@ class Gem::RemoteFetcher
|
|
215
215
|
|
216
216
|
case response
|
217
217
|
when Net::HTTPOK, Net::HTTPNotModified then
|
218
|
-
response.uri = uri
|
218
|
+
response.uri = uri
|
219
219
|
head ? response : response.body
|
220
220
|
when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther,
|
221
221
|
Net::HTTPTemporaryRedirect then
|
data/lib/rubygems/request_set.rb
CHANGED
@@ -195,19 +195,8 @@ class Gem::RequestSet
|
|
195
195
|
yield req, installer if block_given?
|
196
196
|
end
|
197
197
|
rescue Gem::RuntimeRequirementNotMetError => e
|
198
|
-
|
199
|
-
|
200
|
-
s.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
|
201
|
-
s.required_rubygems_version.satisfied_by?(Gem.rubygems_version) &&
|
202
|
-
Gem::Platform.installable?(s)
|
203
|
-
end
|
204
|
-
if recent_match
|
205
|
-
suggestion = "The last version of #{req.request} to support your Ruby & RubyGems was #{recent_match.version}. Try installing it with `gem install #{recent_match.name} -v #{recent_match.version}`"
|
206
|
-
suggestion += " and then running the current command again" unless @always_install.include?(req.spec.spec)
|
207
|
-
else
|
208
|
-
suggestion = "There are no versions of #{req.request} compatible with your Ruby & RubyGems"
|
209
|
-
suggestion += ". Maybe try installing an older version of the gem you're looking for?" unless @always_install.include?(req.spec.spec)
|
210
|
-
end
|
198
|
+
suggestion = "There are no versions of #{req.request} compatible with your Ruby & RubyGems"
|
199
|
+
suggestion += ". Maybe try installing an older version of the gem you're looking for?" unless @always_install.include?(req.spec.spec)
|
211
200
|
e.suggestion = suggestion
|
212
201
|
raise
|
213
202
|
end
|
data/lib/rubygems/resolver.rb
CHANGED
@@ -261,7 +261,12 @@ class Gem::Resolver
|
|
261
261
|
end
|
262
262
|
|
263
263
|
def requirement_satisfied_by?(requirement, activated, spec)
|
264
|
-
requirement.matches_spec? spec
|
264
|
+
matches_spec = requirement.matches_spec? spec
|
265
|
+
return matches_spec if @soft_missing
|
266
|
+
|
267
|
+
matches_spec &&
|
268
|
+
spec.spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
|
269
|
+
spec.spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
|
265
270
|
end
|
266
271
|
|
267
272
|
def name_for(dependency)
|
@@ -4,6 +4,8 @@
|
|
4
4
|
# Returns instances of APISpecification.
|
5
5
|
|
6
6
|
class Gem::Resolver::APISet < Gem::Resolver::Set
|
7
|
+
autoload :GemParser, File.expand_path("api_set/gem_parser", __dir__)
|
8
|
+
|
7
9
|
##
|
8
10
|
# The URI for the dependency API this APISet uses.
|
9
11
|
|
@@ -24,13 +26,13 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
|
|
24
26
|
# API URL +dep_uri+ which is described at
|
25
27
|
# https://guides.rubygems.org/rubygems-org-api
|
26
28
|
|
27
|
-
def initialize(dep_uri = 'https://rubygems.org/
|
29
|
+
def initialize(dep_uri = 'https://index.rubygems.org/info/')
|
28
30
|
super()
|
29
31
|
|
30
32
|
dep_uri = URI dep_uri unless URI === dep_uri
|
31
33
|
|
32
34
|
@dep_uri = dep_uri
|
33
|
-
@uri = dep_uri + '
|
35
|
+
@uri = dep_uri + '..'
|
34
36
|
|
35
37
|
@data = Hash.new {|h,k| h[k] = [] }
|
36
38
|
@source = Gem::Source.new @uri
|
@@ -75,20 +77,8 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
|
|
75
77
|
def prefetch_now # :nodoc:
|
76
78
|
needed, @to_fetch = @to_fetch, []
|
77
79
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
loaded = []
|
82
|
-
|
83
|
-
Marshal.load(str).each do |ver|
|
84
|
-
name = ver[:name]
|
85
|
-
|
86
|
-
@data[name] << ver
|
87
|
-
loaded << name
|
88
|
-
end
|
89
|
-
|
90
|
-
(needed - loaded).each do |missing|
|
91
|
-
@data[missing] = []
|
80
|
+
needed.sort.each do |name|
|
81
|
+
versions(name)
|
92
82
|
end
|
93
83
|
end
|
94
84
|
|
@@ -111,13 +101,32 @@ class Gem::Resolver::APISet < Gem::Resolver::Set
|
|
111
101
|
return @data[name]
|
112
102
|
end
|
113
103
|
|
114
|
-
uri = @dep_uri +
|
104
|
+
uri = @dep_uri + name
|
115
105
|
str = Gem::RemoteFetcher.fetcher.fetch_path uri
|
116
106
|
|
117
|
-
|
118
|
-
|
107
|
+
lines(str).each do |ver|
|
108
|
+
number, platform, dependencies, requirements = parse_gem(ver)
|
109
|
+
|
110
|
+
platform ||= "ruby"
|
111
|
+
dependencies = dependencies.map {|dep_name, reqs| [dep_name, reqs.join(", ")] }
|
112
|
+
requirements = requirements.map {|req_name, reqs| [req_name.to_sym, reqs] }.to_h
|
113
|
+
|
114
|
+
@data[name] << { name: name, number: number, platform: platform, dependencies: dependencies, requirements: requirements }
|
119
115
|
end
|
120
116
|
|
121
117
|
@data[name]
|
122
118
|
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def lines(str)
|
123
|
+
lines = str.split("\n")
|
124
|
+
header = lines.index("---")
|
125
|
+
header ? lines[header + 1..-1] : lines
|
126
|
+
end
|
127
|
+
|
128
|
+
def parse_gem(string)
|
129
|
+
@gem_parser ||= GemParser.new
|
130
|
+
@gem_parser.parse(string)
|
131
|
+
end
|
123
132
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Gem::Resolver::APISet::GemParser
|
4
|
+
def parse(line)
|
5
|
+
version_and_platform, rest = line.split(" ", 2)
|
6
|
+
version, platform = version_and_platform.split("-", 2)
|
7
|
+
dependencies, requirements = rest.split("|", 2).map {|s| s.split(",") } if rest
|
8
|
+
dependencies = dependencies ? dependencies.map {|d| parse_dependency(d) } : []
|
9
|
+
requirements = requirements ? requirements.map {|d| parse_dependency(d) } : []
|
10
|
+
[version, platform, dependencies, requirements]
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def parse_dependency(string)
|
16
|
+
dependency = string.split(":")
|
17
|
+
dependency[-1] = dependency[-1].split("&") if dependency.size > 1
|
18
|
+
dependency
|
19
|
+
end
|
20
|
+
end
|
@@ -35,6 +35,8 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
|
|
35
35
|
@dependencies = api_data[:dependencies].map do |name, ver|
|
36
36
|
Gem::Dependency.new(name, ver.split(/\s*,\s*/)).freeze
|
37
37
|
end.freeze
|
38
|
+
@required_ruby_version = Gem::Requirement.new(api_data.dig(:requirements, :ruby)).freeze
|
39
|
+
@required_rubygems_version = Gem::Requirement.new(api_data.dig(:requirements, :rubygems)).freeze
|
38
40
|
end
|
39
41
|
|
40
42
|
def ==(other) # :nodoc:
|
@@ -42,12 +44,11 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification
|
|
42
44
|
@set == other.set and
|
43
45
|
@name == other.name and
|
44
46
|
@version == other.version and
|
45
|
-
@platform == other.platform
|
46
|
-
@dependencies == other.dependencies
|
47
|
+
@platform == other.platform
|
47
48
|
end
|
48
49
|
|
49
50
|
def hash
|
50
|
-
@set.hash ^ @name.hash ^ @version.hash ^ @platform.hash
|
51
|
+
@set.hash ^ @name.hash ^ @version.hash ^ @platform.hash
|
51
52
|
end
|
52
53
|
|
53
54
|
def fetch_development_dependencies # :nodoc:
|
@@ -60,7 +60,7 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet
|
|
60
60
|
def replace_failed_api_set(error) # :nodoc:
|
61
61
|
uri = error.uri
|
62
62
|
uri = URI uri unless URI === uri
|
63
|
-
uri
|
63
|
+
uri = uri + "."
|
64
64
|
|
65
65
|
raise error unless api_set = @sets.find do |set|
|
66
66
|
Gem::Resolver::APISet === set and set.dep_uri == uri
|
@@ -33,6 +33,21 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
|
|
33
33
|
spec.dependencies
|
34
34
|
end
|
35
35
|
|
36
|
+
##
|
37
|
+
# The required_ruby_version constraint for this specification
|
38
|
+
|
39
|
+
def required_ruby_version
|
40
|
+
spec.required_ruby_version
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# The required_rubygems_version constraint for this specification
|
45
|
+
#
|
46
|
+
|
47
|
+
def required_rubygems_version
|
48
|
+
spec.required_rubygems_version
|
49
|
+
end
|
50
|
+
|
36
51
|
def ==(other)
|
37
52
|
self.class === other &&
|
38
53
|
@name == other.name &&
|
@@ -25,6 +25,12 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
|
25
25
|
|
26
26
|
attr_reader :remote_set # :nodoc:
|
27
27
|
|
28
|
+
##
|
29
|
+
# Ignore ruby & rubygems specification constraints.
|
30
|
+
#
|
31
|
+
|
32
|
+
attr_accessor :force # :nodoc:
|
33
|
+
|
28
34
|
##
|
29
35
|
# Creates a new InstallerSet that will look for gems in +domain+.
|
30
36
|
|
@@ -41,6 +47,7 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
|
41
47
|
@local = {}
|
42
48
|
@local_source = Gem::Source::Local.new
|
43
49
|
@remote_set = Gem::Resolver::BestSet.new
|
50
|
+
@force = false
|
44
51
|
@specs = {}
|
45
52
|
end
|
46
53
|
|
@@ -63,15 +70,30 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
|
63
70
|
Gem::Platform.local === s.platform
|
64
71
|
end
|
65
72
|
|
66
|
-
|
67
|
-
|
68
|
-
exc.errors = errors
|
69
|
-
|
70
|
-
raise exc
|
73
|
+
found = found.sort_by do |s|
|
74
|
+
[s.version, s.platform == Gem::Platform::RUBY ? -1 : 1]
|
71
75
|
end
|
72
76
|
|
73
|
-
newest = found.
|
74
|
-
|
77
|
+
newest = found.last
|
78
|
+
|
79
|
+
unless @force
|
80
|
+
found_matching_metadata = found.select do |spec|
|
81
|
+
metadata_satisfied?(spec)
|
82
|
+
end
|
83
|
+
|
84
|
+
if found_matching_metadata.empty?
|
85
|
+
if newest
|
86
|
+
ensure_required_ruby_version_met(newest.spec)
|
87
|
+
ensure_required_rubygems_version_met(newest.spec)
|
88
|
+
else
|
89
|
+
exc = Gem::UnsatisfiableDependencyError.new request
|
90
|
+
exc.errors = errors
|
91
|
+
|
92
|
+
raise exc
|
93
|
+
end
|
94
|
+
else
|
95
|
+
newest = found_matching_metadata.last
|
96
|
+
end
|
75
97
|
end
|
76
98
|
|
77
99
|
@always_install << newest.spec
|
@@ -221,4 +243,32 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set
|
|
221
243
|
@domain = :local unless remote
|
222
244
|
end
|
223
245
|
end
|
246
|
+
|
247
|
+
private
|
248
|
+
|
249
|
+
def metadata_satisfied?(spec)
|
250
|
+
spec.required_ruby_version.satisfied_by?(Gem.ruby_version) &&
|
251
|
+
spec.required_rubygems_version.satisfied_by?(Gem.rubygems_version)
|
252
|
+
end
|
253
|
+
|
254
|
+
def ensure_required_ruby_version_met(spec) # :nodoc:
|
255
|
+
if rrv = spec.required_ruby_version
|
256
|
+
ruby_version = Gem.ruby_version
|
257
|
+
unless rrv.satisfied_by? ruby_version
|
258
|
+
raise Gem::RuntimeRequirementNotMetError,
|
259
|
+
"#{spec.full_name} requires Ruby version #{rrv}. The current ruby version is #{ruby_version}."
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def ensure_required_rubygems_version_met(spec) # :nodoc:
|
265
|
+
if rrgv = spec.required_rubygems_version
|
266
|
+
unless rrgv.satisfied_by? Gem.rubygems_version
|
267
|
+
rg_version = Gem::VERSION
|
268
|
+
raise Gem::RuntimeRequirementNotMetError,
|
269
|
+
"#{spec.full_name} requires RubyGems version #{rrgv}. The current RubyGems version is #{rg_version}. " +
|
270
|
+
"Try 'gem update --system' to update RubyGems itself."
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
224
274
|
end
|
@@ -22,6 +22,20 @@ class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification
|
|
22
22
|
spec.dependencies
|
23
23
|
end
|
24
24
|
|
25
|
+
##
|
26
|
+
# The required_ruby_version constraint for this specification
|
27
|
+
|
28
|
+
def required_ruby_version
|
29
|
+
spec.required_ruby_version
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# The required_rubygems_version constraint for this specification
|
34
|
+
|
35
|
+
def required_rubygems_version
|
36
|
+
spec.required_rubygems_version
|
37
|
+
end
|
38
|
+
|
25
39
|
##
|
26
40
|
# The name and version of the specification.
|
27
41
|
#
|
@@ -43,6 +43,16 @@ class Gem::Resolver::Specification
|
|
43
43
|
|
44
44
|
attr_reader :version
|
45
45
|
|
46
|
+
##
|
47
|
+
# The required_ruby_version constraint for this specification.
|
48
|
+
|
49
|
+
attr_reader :required_ruby_version
|
50
|
+
|
51
|
+
##
|
52
|
+
# The required_ruby_version constraint for this specification.
|
53
|
+
|
54
|
+
attr_reader :required_rubygems_version
|
55
|
+
|
46
56
|
##
|
47
57
|
# Sets default instance variables for the specification.
|
48
58
|
|
@@ -53,6 +63,8 @@ class Gem::Resolver::Specification
|
|
53
63
|
@set = nil
|
54
64
|
@source = nil
|
55
65
|
@version = nil
|
66
|
+
@required_ruby_version = Gem::Requirement.default
|
67
|
+
@required_rubygems_version = Gem::Requirement.default
|
56
68
|
end
|
57
69
|
|
58
70
|
##
|
data/lib/rubygems/source.rb
CHANGED
@@ -79,7 +79,15 @@ class Gem::Source
|
|
79
79
|
def dependency_resolver_set # :nodoc:
|
80
80
|
return Gem::Resolver::IndexSet.new self if 'file' == uri.scheme
|
81
81
|
|
82
|
-
|
82
|
+
fetch_uri = if uri.host == "rubygems.org"
|
83
|
+
index_uri = uri.dup
|
84
|
+
index_uri.host = "index.rubygems.org"
|
85
|
+
index_uri
|
86
|
+
else
|
87
|
+
uri
|
88
|
+
end
|
89
|
+
|
90
|
+
bundler_api_uri = enforce_trailing_slash(fetch_uri)
|
83
91
|
|
84
92
|
begin
|
85
93
|
fetcher = Gem::RemoteFetcher.fetcher
|
@@ -87,11 +95,7 @@ class Gem::Source
|
|
87
95
|
rescue Gem::RemoteFetcher::FetchError
|
88
96
|
Gem::Resolver::IndexSet.new self
|
89
97
|
else
|
90
|
-
|
91
|
-
Gem::Resolver::APISet.new response.uri
|
92
|
-
else
|
93
|
-
Gem::Resolver::APISet.new bundler_api_uri
|
94
|
-
end
|
98
|
+
Gem::Resolver::APISet.new response.uri + "./info/"
|
95
99
|
end
|
96
100
|
end
|
97
101
|
|