rubygems-update 3.2.2 → 3.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|