rubygems-update 3.5.11 → 3.5.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Manifest.txt +1 -0
- data/bundler/CHANGELOG.md +20 -0
- data/bundler/lib/bundler/build_metadata.rb +2 -2
- data/bundler/lib/bundler/cli.rb +5 -8
- data/bundler/lib/bundler/compact_index_client/cache.rb +47 -81
- data/bundler/lib/bundler/compact_index_client/parser.rb +84 -0
- data/bundler/lib/bundler/compact_index_client.rb +51 -80
- data/bundler/lib/bundler/definition.rb +6 -3
- data/bundler/lib/bundler/fetcher/compact_index.rb +15 -24
- data/bundler/lib/bundler/installer/gem_installer.rb +0 -1
- data/bundler/lib/bundler/man/bundle-config.1 +1 -1
- data/bundler/lib/bundler/man/bundle-config.1.ronn +1 -1
- data/bundler/lib/bundler/rubygems_integration.rb +14 -0
- data/bundler/lib/bundler/self_manager.rb +5 -0
- data/bundler/lib/bundler/settings.rb +12 -8
- data/bundler/lib/bundler/setup.rb +3 -0
- data/bundler/lib/bundler/shared_helpers.rb +2 -2
- data/bundler/lib/bundler/source/git.rb +14 -0
- data/bundler/lib/bundler/source/path.rb +0 -13
- data/bundler/lib/bundler/source/rubygems.rb +29 -13
- data/bundler/lib/bundler/version.rb +1 -1
- data/bundler/lib/bundler/yaml_serializer.rb +1 -8
- data/bundler/lib/bundler.rb +6 -1
- data/lib/rubygems/basic_specification.rb +27 -0
- data/lib/rubygems/commands/pristine_command.rb +3 -3
- data/lib/rubygems/specification.rb +11 -2
- data/lib/rubygems/specification_record.rb +0 -1
- data/lib/rubygems/stub_specification.rb +21 -0
- data/lib/rubygems/uninstaller.rb +12 -11
- data/lib/rubygems/yaml_serializer.rb +1 -8
- data/lib/rubygems.rb +1 -1
- data/rubygems-update.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c35be5895f916b09303ca0a72f0cc908f52df658c8860de916b73d4e0637fb1d
|
4
|
+
data.tar.gz: 5ca038be72e7dd475544a0fe4baa5998dc4ec4fc40169c86bbceaf3004a28993
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '018263fd318b8ff0f135774f71daac0b005472254e524cf93fc9616650ddba36f397a0c0f94ed2c278e276ab8ec6cc5a6323af2375d0a1a220e066d863904142'
|
7
|
+
data.tar.gz: f9713050e6ab501c1777a44c1409c5aa45cb17bdf5795f61113d27bbad2abf502a604a1d6d4930ff59c548349920a61ea7d4bae1a99eeef8e41842b6a9a3af1a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
# 3.5.12 / 2024-06-13
|
2
|
+
|
3
|
+
## Enhancements:
|
4
|
+
|
5
|
+
* Installs bundler 2.5.12 as a default gem.
|
6
|
+
|
7
|
+
## Bug fixes:
|
8
|
+
|
9
|
+
* Fix `gem uninstall` unresolved specifications warning. Pull request
|
10
|
+
[#7667](https://github.com/rubygems/rubygems/pull/7667) by
|
11
|
+
deivid-rodriguez
|
12
|
+
* Fix `gem pristine` sometimes failing to pristine user installed gems.
|
13
|
+
Pull request [#7664](https://github.com/rubygems/rubygems/pull/7664) by
|
14
|
+
deivid-rodriguez
|
15
|
+
|
1
16
|
# 3.5.11 / 2024-05-28
|
2
17
|
|
3
18
|
## Enhancements:
|
data/Manifest.txt
CHANGED
@@ -54,6 +54,7 @@ bundler/lib/bundler/compact_index_client.rb
|
|
54
54
|
bundler/lib/bundler/compact_index_client/cache.rb
|
55
55
|
bundler/lib/bundler/compact_index_client/cache_file.rb
|
56
56
|
bundler/lib/bundler/compact_index_client/gem_parser.rb
|
57
|
+
bundler/lib/bundler/compact_index_client/parser.rb
|
57
58
|
bundler/lib/bundler/compact_index_client/updater.rb
|
58
59
|
bundler/lib/bundler/constants.rb
|
59
60
|
bundler/lib/bundler/current_ruby.rb
|
data/bundler/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
# 2.5.12 (June 13, 2024)
|
2
|
+
|
3
|
+
## Enhancements:
|
4
|
+
|
5
|
+
- Keep credentials in lockfile if they are already there [#7720](https://github.com/rubygems/rubygems/pull/7720)
|
6
|
+
- Auto switch to locked bundler version even when using binstubs [#7719](https://github.com/rubygems/rubygems/pull/7719)
|
7
|
+
- Don't validate local gemspecs twice unnecessarily [#7725](https://github.com/rubygems/rubygems/pull/7725)
|
8
|
+
- Improve default gem handling by treating default gems as any other gem [#7673](https://github.com/rubygems/rubygems/pull/7673)
|
9
|
+
|
10
|
+
## Bug fixes:
|
11
|
+
|
12
|
+
- Fix slow and incorrect resolution when adding `sorbet` to a Gemfile and the lockfile only includes "RUBY" in the platforms section [#7731](https://github.com/rubygems/rubygems/pull/7731)
|
13
|
+
- Fix duplicated config keys generated when `fallback_timeout` uri option is used [#7704](https://github.com/rubygems/rubygems/pull/7704)
|
14
|
+
- Fix `bundle exec` no longer working in truffleruby after explicit `require` of `pathname` was removed [#7703](https://github.com/rubygems/rubygems/pull/7703)
|
15
|
+
- Don't let `bundle config` report a path without a Gemfile as "local app" [#7687](https://github.com/rubygems/rubygems/pull/7687)
|
16
|
+
|
17
|
+
## Documentation:
|
18
|
+
|
19
|
+
- Clarify BUNDLE_USER_CONFIG is a file [#7668](https://github.com/rubygems/rubygems/pull/7668)
|
20
|
+
|
1
21
|
# 2.5.11 (May 28, 2024)
|
2
22
|
|
3
23
|
## Deprecations:
|
@@ -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 = "2024-
|
8
|
-
@git_commit_sha = "
|
7
|
+
@built_at = "2024-06-13".freeze
|
8
|
+
@git_commit_sha = "05dc7d98e5".freeze
|
9
9
|
@release = true
|
10
10
|
# end ivars
|
11
11
|
|
data/bundler/lib/bundler/cli.rb
CHANGED
@@ -65,7 +65,7 @@ module Bundler
|
|
65
65
|
Bundler.reset_settings_and_root!
|
66
66
|
end
|
67
67
|
|
68
|
-
Bundler.
|
68
|
+
Bundler.auto_switch
|
69
69
|
|
70
70
|
Bundler.settings.set_command_option_if_given :retry, options[:retry]
|
71
71
|
|
@@ -767,13 +767,10 @@ module Bundler
|
|
767
767
|
|
768
768
|
return unless SharedHelpers.md5_available?
|
769
769
|
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
dependencies("bundler").
|
775
|
-
map {|d| Gem::Version.new(d.first) }.
|
776
|
-
max
|
770
|
+
require_relative "vendored_uri"
|
771
|
+
remote = Source::Rubygems::Remote.new(Gem::URI("https://rubygems.org"))
|
772
|
+
cache_path = Bundler.user_cache.join("compact_index", remote.cache_slug)
|
773
|
+
latest = Bundler::CompactIndexClient.new(cache_path).latest_version("bundler")
|
777
774
|
return unless latest
|
778
775
|
|
779
776
|
current = Gem::Version.new(VERSION)
|
@@ -7,123 +7,89 @@ module Bundler
|
|
7
7
|
class Cache
|
8
8
|
attr_reader :directory
|
9
9
|
|
10
|
-
def initialize(directory)
|
10
|
+
def initialize(directory, fetcher = nil)
|
11
11
|
@directory = Pathname.new(directory).expand_path
|
12
|
-
|
13
|
-
|
12
|
+
@updater = Updater.new(fetcher) if fetcher
|
13
|
+
@mutex = Thread::Mutex.new
|
14
|
+
@endpoints = Set.new
|
15
|
+
|
16
|
+
@info_root = mkdir("info")
|
17
|
+
@special_characters_info_root = mkdir("info-special-characters")
|
18
|
+
@info_etag_root = mkdir("info-etags")
|
14
19
|
end
|
15
20
|
|
16
21
|
def names
|
17
|
-
|
22
|
+
fetch("names", names_path, names_etag_path)
|
18
23
|
end
|
19
24
|
|
20
|
-
def
|
21
|
-
|
25
|
+
def versions
|
26
|
+
fetch("versions", versions_path, versions_etag_path)
|
22
27
|
end
|
23
28
|
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
29
|
+
def info(name, remote_checksum = nil)
|
30
|
+
path = info_path(name)
|
27
31
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
name, versions_string, info_checksum = line.split(" ", 3)
|
34
|
-
info_checksums_by_name[name] = info_checksum || ""
|
35
|
-
versions_string.split(",") do |version|
|
36
|
-
delete = version.delete_prefix!("-")
|
37
|
-
version = version.split("-", 2).unshift(name)
|
38
|
-
if delete
|
39
|
-
versions_by_name[name].delete(version)
|
40
|
-
else
|
41
|
-
versions_by_name[name] << version
|
42
|
-
end
|
43
|
-
end
|
32
|
+
if remote_checksum && remote_checksum != SharedHelpers.checksum_for_file(path, :MD5)
|
33
|
+
fetch("info/#{name}", path, info_etag_path(name))
|
34
|
+
else
|
35
|
+
Bundler::CompactIndexClient.debug { "update skipped info/#{name} (#{remote_checksum ? "versions index checksum is nil" : "versions index checksum matches local"})" }
|
36
|
+
read(path)
|
44
37
|
end
|
45
|
-
|
46
|
-
[versions_by_name, info_checksums_by_name]
|
47
|
-
end
|
48
|
-
|
49
|
-
def versions_path
|
50
|
-
directory.join("versions")
|
51
38
|
end
|
52
39
|
|
53
|
-
def
|
54
|
-
|
40
|
+
def reset!
|
41
|
+
@mutex.synchronize { @endpoints.clear }
|
55
42
|
end
|
56
43
|
|
57
|
-
|
58
|
-
lines(versions_path).each_with_object({}) do |line, checksums|
|
59
|
-
parse_version_checksum(line, checksums)
|
60
|
-
end
|
61
|
-
end
|
44
|
+
private
|
62
45
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
end
|
46
|
+
def names_path = directory.join("names")
|
47
|
+
def names_etag_path = directory.join("names.etag")
|
48
|
+
def versions_path = directory.join("versions")
|
49
|
+
def versions_etag_path = directory.join("versions.etag")
|
68
50
|
|
69
51
|
def info_path(name)
|
70
52
|
name = name.to_s
|
53
|
+
# TODO: converge this into the info_root by hashing all filenames like info_etag_path
|
71
54
|
if /[^a-z0-9_-]/.match?(name)
|
72
55
|
name += "-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}"
|
73
|
-
|
56
|
+
@special_characters_info_root.join(name)
|
74
57
|
else
|
75
|
-
|
58
|
+
@info_root.join(name)
|
76
59
|
end
|
77
60
|
end
|
78
61
|
|
79
62
|
def info_etag_path(name)
|
80
63
|
name = name.to_s
|
81
|
-
info_etag_root.join("#{name}-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}")
|
64
|
+
@info_etag_root.join("#{name}-#{SharedHelpers.digest(:MD5).hexdigest(name).downcase}")
|
82
65
|
end
|
83
66
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
67
|
+
def mkdir(name)
|
68
|
+
directory.join(name).tap do |dir|
|
69
|
+
SharedHelpers.filesystem_access(dir) do
|
70
|
+
FileUtils.mkdir_p(dir)
|
71
|
+
end
|
89
72
|
end
|
90
73
|
end
|
91
74
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
def parse_gem(line)
|
100
|
-
@dependency_parser ||= GemParser.new
|
101
|
-
@dependency_parser.parse(line)
|
102
|
-
end
|
75
|
+
def fetch(remote_path, path, etag_path)
|
76
|
+
if already_fetched?(remote_path)
|
77
|
+
Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" }
|
78
|
+
else
|
79
|
+
Bundler::CompactIndexClient.debug { "fetching #{remote_path}" }
|
80
|
+
@updater&.update(remote_path, path, etag_path)
|
81
|
+
end
|
103
82
|
|
104
|
-
|
105
|
-
# This method gets called at least once for every gem when parsing versions.
|
106
|
-
def parse_version_checksum(line, checksums)
|
107
|
-
line.freeze # allows slicing into the string to not allocate a copy of the line
|
108
|
-
name_end = line.index(" ")
|
109
|
-
checksum_start = line.index(" ", name_end + 1) + 1
|
110
|
-
checksum_end = line.size - checksum_start
|
111
|
-
# freeze name since it is used as a hash key
|
112
|
-
# pre-freezing means a frozen copy isn't created
|
113
|
-
name = line[0, name_end].freeze
|
114
|
-
checksum = line[checksum_start, checksum_end]
|
115
|
-
checksums[name] = checksum
|
83
|
+
read(path)
|
116
84
|
end
|
117
85
|
|
118
|
-
def
|
119
|
-
|
120
|
-
directory.join("info"),
|
121
|
-
directory.join("info-special-characters"),
|
122
|
-
]
|
86
|
+
def already_fetched?(remote_path)
|
87
|
+
@mutex.synchronize { !@endpoints.add?(remote_path) }
|
123
88
|
end
|
124
89
|
|
125
|
-
def
|
126
|
-
|
90
|
+
def read(path)
|
91
|
+
return unless path.file?
|
92
|
+
SharedHelpers.filesystem_access(path, :read, &:read)
|
127
93
|
end
|
128
94
|
end
|
129
95
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class CompactIndexClient
|
5
|
+
class Parser
|
6
|
+
# `compact_index` - an object responding to #names, #versions, #info(name, checksum),
|
7
|
+
# returning the file contents as a string
|
8
|
+
def initialize(compact_index)
|
9
|
+
@compact_index = compact_index
|
10
|
+
@info_checksums = nil
|
11
|
+
@versions_by_name = nil
|
12
|
+
@available = nil
|
13
|
+
@gem_parser = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def names
|
17
|
+
lines(@compact_index.names)
|
18
|
+
end
|
19
|
+
|
20
|
+
def versions
|
21
|
+
@versions_by_name ||= Hash.new {|hash, key| hash[key] = [] }
|
22
|
+
@info_checksums = {}
|
23
|
+
|
24
|
+
lines(@compact_index.versions).each do |line|
|
25
|
+
name, versions_string, checksum = line.split(" ", 3)
|
26
|
+
@info_checksums[name] = checksum || ""
|
27
|
+
versions_string.split(",") do |version|
|
28
|
+
delete = version.delete_prefix!("-")
|
29
|
+
version = version.split("-", 2).unshift(name)
|
30
|
+
if delete
|
31
|
+
@versions_by_name[name].delete(version)
|
32
|
+
else
|
33
|
+
@versions_by_name[name] << version
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
@versions_by_name
|
39
|
+
end
|
40
|
+
|
41
|
+
def info(name)
|
42
|
+
data = @compact_index.info(name, info_checksums[name])
|
43
|
+
lines(data).map {|line| gem_parser.parse(line).unshift(name) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def available?
|
47
|
+
return @available unless @available.nil?
|
48
|
+
@available = !info_checksums.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def info_checksums
|
54
|
+
@info_checksums ||= lines(@compact_index.versions).each_with_object({}) do |line, checksums|
|
55
|
+
parse_version_checksum(line, checksums)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def lines(data)
|
60
|
+
return [] if data.nil? || data.empty?
|
61
|
+
lines = data.split("\n")
|
62
|
+
header = lines.index("---")
|
63
|
+
header ? lines[header + 1..-1] : lines
|
64
|
+
end
|
65
|
+
|
66
|
+
def gem_parser
|
67
|
+
@gem_parser ||= GemParser.new
|
68
|
+
end
|
69
|
+
|
70
|
+
# This is mostly the same as `split(" ", 3)` but it avoids allocating extra objects.
|
71
|
+
# This method gets called at least once for every gem when parsing versions.
|
72
|
+
def parse_version_checksum(line, checksums)
|
73
|
+
return unless (name_end = line.index(" ")) # Artifactory bug causes blank lines in artifactor index files
|
74
|
+
return unless (checksum_start = line.index(" ", name_end + 1) + 1)
|
75
|
+
checksum_end = line.size - checksum_start
|
76
|
+
|
77
|
+
line.freeze # allows slicing into the string to not allocate a copy of the line
|
78
|
+
name = line[0, name_end]
|
79
|
+
checksum = line[checksum_start, checksum_end]
|
80
|
+
checksums[name.freeze] = checksum # freeze name since it is used as a hash key
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -4,6 +4,29 @@ require "pathname"
|
|
4
4
|
require "set"
|
5
5
|
|
6
6
|
module Bundler
|
7
|
+
# The CompactIndexClient is responsible for fetching and parsing the compact index.
|
8
|
+
#
|
9
|
+
# The compact index is a set of caching optimized files that are used to fetch gem information.
|
10
|
+
# The files are:
|
11
|
+
# - names: a list of all gem names
|
12
|
+
# - versions: a list of all gem versions
|
13
|
+
# - info/[gem]: a list of all versions of a gem
|
14
|
+
#
|
15
|
+
# The client is instantiated with:
|
16
|
+
# - `directory`: the root directory where the cache files are stored.
|
17
|
+
# - `fetcher`: (optional) an object that responds to #call(uri_path, headers) and returns an http response.
|
18
|
+
# If the `fetcher` is not provided, the client will only read cached files from disk.
|
19
|
+
#
|
20
|
+
# The client is organized into:
|
21
|
+
# - `Updater`: updates the cached files on disk using the fetcher.
|
22
|
+
# - `Cache`: calls the updater, caches files, read and return them from disk
|
23
|
+
# - `Parser`: parses the compact index file data
|
24
|
+
# - `CacheFile`: a concurrency safe file reader/writer that verifies checksums
|
25
|
+
#
|
26
|
+
# The client is intended to optimize memory usage and performance.
|
27
|
+
# It is called 100s or 1000s of times, parsing files with hundreds of thousands of lines.
|
28
|
+
# It may be called concurrently without global interpreter lock in some Rubies.
|
29
|
+
# As a result, some methods may look more complex than necessary to save memory or time.
|
7
30
|
class CompactIndexClient
|
8
31
|
# NOTE: MD5 is here not because we expect a server to respond with it, but
|
9
32
|
# because we use it to generate the etag on first request during the upgrade
|
@@ -12,6 +35,13 @@ module Bundler
|
|
12
35
|
SUPPORTED_DIGESTS = { "sha-256" => :SHA256, "md5" => :MD5 }.freeze
|
13
36
|
DEBUG_MUTEX = Thread::Mutex.new
|
14
37
|
|
38
|
+
# info returns an Array of INFO Arrays. Each INFO Array has the following indices:
|
39
|
+
INFO_NAME = 0
|
40
|
+
INFO_VERSION = 1
|
41
|
+
INFO_PLATFORM = 2
|
42
|
+
INFO_DEPS = 3
|
43
|
+
INFO_REQS = 4
|
44
|
+
|
15
45
|
def self.debug
|
16
46
|
return unless ENV["DEBUG_COMPACT_INDEX"]
|
17
47
|
DEBUG_MUTEX.synchronize { warn("[#{self}] #{yield}") }
|
@@ -21,106 +51,47 @@ module Bundler
|
|
21
51
|
|
22
52
|
require_relative "compact_index_client/cache"
|
23
53
|
require_relative "compact_index_client/cache_file"
|
54
|
+
require_relative "compact_index_client/parser"
|
24
55
|
require_relative "compact_index_client/updater"
|
25
56
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@directory = Pathname.new(directory)
|
30
|
-
@updater = Updater.new(fetcher)
|
31
|
-
@cache = Cache.new(@directory)
|
32
|
-
@endpoints = Set.new
|
33
|
-
@info_checksums_by_name = {}
|
34
|
-
@parsed_checksums = false
|
35
|
-
@mutex = Thread::Mutex.new
|
36
|
-
end
|
37
|
-
|
38
|
-
def execution_mode=(block)
|
39
|
-
Bundler::CompactIndexClient.debug { "execution_mode=" }
|
40
|
-
@endpoints = Set.new
|
41
|
-
|
42
|
-
@execution_mode = block
|
43
|
-
end
|
44
|
-
|
45
|
-
# @return [Lambda] A lambda that takes an array of inputs and a block, and
|
46
|
-
# maps the inputs with the block in parallel.
|
47
|
-
#
|
48
|
-
def execution_mode
|
49
|
-
@execution_mode || sequentially
|
50
|
-
end
|
51
|
-
|
52
|
-
def sequential_execution_mode!
|
53
|
-
self.execution_mode = sequentially
|
54
|
-
end
|
55
|
-
|
56
|
-
def sequentially
|
57
|
-
@sequentially ||= lambda do |inputs, &blk|
|
58
|
-
inputs.map(&blk)
|
59
|
-
end
|
57
|
+
def initialize(directory, fetcher = nil)
|
58
|
+
@cache = Cache.new(directory, fetcher)
|
59
|
+
@parser = Parser.new(@cache)
|
60
60
|
end
|
61
61
|
|
62
62
|
def names
|
63
|
-
Bundler::CompactIndexClient.debug { "
|
64
|
-
|
65
|
-
@cache.names
|
63
|
+
Bundler::CompactIndexClient.debug { "names" }
|
64
|
+
@parser.names
|
66
65
|
end
|
67
66
|
|
68
67
|
def versions
|
69
|
-
Bundler::CompactIndexClient.debug { "
|
70
|
-
|
71
|
-
versions, @info_checksums_by_name = @cache.versions
|
72
|
-
versions
|
68
|
+
Bundler::CompactIndexClient.debug { "versions" }
|
69
|
+
@parser.versions
|
73
70
|
end
|
74
71
|
|
75
72
|
def dependencies(names)
|
76
73
|
Bundler::CompactIndexClient.debug { "dependencies(#{names})" }
|
77
|
-
|
78
|
-
update_info(name)
|
79
|
-
@cache.dependencies(name).map {|d| d.unshift(name) }
|
80
|
-
end.flatten(1)
|
74
|
+
names.map {|name| info(name) }
|
81
75
|
end
|
82
76
|
|
83
|
-
def
|
84
|
-
Bundler::CompactIndexClient.debug { "
|
85
|
-
|
86
|
-
update("versions", @cache.versions_path, @cache.versions_etag_path)
|
87
|
-
@info_checksums_by_name = @cache.checksums
|
88
|
-
@parsed_checksums = true
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
|
93
|
-
def update(remote_path, local_path, local_etag_path)
|
94
|
-
Bundler::CompactIndexClient.debug { "update(#{local_path}, #{remote_path})" }
|
95
|
-
unless synchronize { @endpoints.add?(remote_path) }
|
96
|
-
Bundler::CompactIndexClient.debug { "already fetched #{remote_path}" }
|
97
|
-
return
|
98
|
-
end
|
99
|
-
@updater.update(url(remote_path), local_path, local_etag_path)
|
77
|
+
def info(name)
|
78
|
+
Bundler::CompactIndexClient.debug { "info(#{name})" }
|
79
|
+
@parser.info(name)
|
100
80
|
end
|
101
81
|
|
102
|
-
def
|
103
|
-
Bundler::CompactIndexClient.debug { "
|
104
|
-
|
105
|
-
unless existing = @info_checksums_by_name[name]
|
106
|
-
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since it is missing from versions" }
|
107
|
-
return
|
108
|
-
end
|
109
|
-
checksum = SharedHelpers.checksum_for_file(path, :MD5)
|
110
|
-
if checksum == existing
|
111
|
-
Bundler::CompactIndexClient.debug { "skipping updating info for #{name} since the versions checksum matches the local checksum" }
|
112
|
-
return
|
113
|
-
end
|
114
|
-
Bundler::CompactIndexClient.debug { "updating info for #{name} since the versions checksum #{existing} != the local checksum #{checksum}" }
|
115
|
-
update("info/#{name}", path, @cache.info_etag_path(name))
|
82
|
+
def latest_version(name)
|
83
|
+
Bundler::CompactIndexClient.debug { "latest_version(#{name})" }
|
84
|
+
@parser.info(name).map {|d| Gem::Version.new(d[INFO_VERSION]) }.max
|
116
85
|
end
|
117
86
|
|
118
|
-
def
|
119
|
-
|
87
|
+
def available?
|
88
|
+
Bundler::CompactIndexClient.debug { "available?" }
|
89
|
+
@parser.available?
|
120
90
|
end
|
121
91
|
|
122
|
-
def
|
123
|
-
|
92
|
+
def reset!
|
93
|
+
Bundler::CompactIndexClient.debug { "reset!" }
|
94
|
+
@cache.reset!
|
124
95
|
end
|
125
96
|
end
|
126
97
|
end
|
@@ -624,6 +624,11 @@ module Bundler
|
|
624
624
|
result = SpecSet.new(resolver.start)
|
625
625
|
|
626
626
|
@resolved_bundler_version = result.find {|spec| spec.name == "bundler" }&.version
|
627
|
+
|
628
|
+
if @current_ruby_locked_platform && @current_ruby_locked_platform != local_platform
|
629
|
+
@platforms.delete(result.incomplete_for_platform?(dependencies, @current_ruby_locked_platform) ? @current_ruby_locked_platform : local_platform)
|
630
|
+
end
|
631
|
+
|
627
632
|
@platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
|
628
633
|
|
629
634
|
result.complete_platforms!(platforms)
|
@@ -650,7 +655,6 @@ module Bundler
|
|
650
655
|
|
651
656
|
def current_ruby_platform_locked?
|
652
657
|
return false unless generic_local_platform_is_ruby?
|
653
|
-
return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY)
|
654
658
|
|
655
659
|
current_platform_locked?
|
656
660
|
end
|
@@ -662,7 +666,7 @@ module Bundler
|
|
662
666
|
end
|
663
667
|
|
664
668
|
def add_current_platform
|
665
|
-
|
669
|
+
@current_ruby_locked_platform = most_specific_locked_platform if current_ruby_platform_locked?
|
666
670
|
|
667
671
|
add_platform(local_platform)
|
668
672
|
end
|
@@ -1050,7 +1054,6 @@ module Bundler
|
|
1050
1054
|
!@originally_locked_specs.incomplete_for_platform?(dependencies, platform)
|
1051
1055
|
|
1052
1056
|
remove_platform(platform)
|
1053
|
-
add_current_platform if platform == Gem::Platform::RUBY
|
1054
1057
|
end
|
1055
1058
|
end
|
1056
1059
|
|
@@ -4,8 +4,6 @@ require_relative "base"
|
|
4
4
|
require_relative "../worker"
|
5
5
|
|
6
6
|
module Bundler
|
7
|
-
autoload :CompactIndexClient, File.expand_path("../compact_index_client", __dir__)
|
8
|
-
|
9
7
|
class Fetcher
|
10
8
|
class CompactIndex < Base
|
11
9
|
def self.compact_index_request(method_name)
|
@@ -36,15 +34,8 @@ module Bundler
|
|
36
34
|
|
37
35
|
until remaining_gems.empty?
|
38
36
|
log_specs { "Looking up gems #{remaining_gems.inspect}" }
|
39
|
-
|
40
|
-
|
41
|
-
parallel_compact_index_client.dependencies(remaining_gems)
|
42
|
-
rescue TooManyRequestsError
|
43
|
-
@bundle_worker&.stop
|
44
|
-
@bundle_worker = nil # reset it. Not sure if necessary
|
45
|
-
serial_compact_index_client.dependencies(remaining_gems)
|
46
|
-
end
|
47
|
-
next_gems = deps.flat_map {|d| d[3].flat_map(&:first) }.uniq
|
37
|
+
deps = fetch_gem_infos(remaining_gems).flatten(1)
|
38
|
+
next_gems = deps.flat_map {|d| d[CompactIndexClient::INFO_DEPS].flat_map(&:first) }.uniq
|
48
39
|
deps.each {|dep| gem_info << dep }
|
49
40
|
complete_gems.concat(deps.map(&:first)).uniq!
|
50
41
|
remaining_gems = next_gems - complete_gems
|
@@ -61,7 +52,7 @@ module Bundler
|
|
61
52
|
return nil
|
62
53
|
end
|
63
54
|
# Read info file checksums out of /versions, so we can know if gems are up to date
|
64
|
-
compact_index_client.
|
55
|
+
compact_index_client.available?
|
65
56
|
rescue CompactIndexClient::Updater::MismatchedChecksumError => e
|
66
57
|
Bundler.ui.debug(e.message)
|
67
58
|
nil
|
@@ -81,20 +72,20 @@ module Bundler
|
|
81
72
|
end
|
82
73
|
end
|
83
74
|
|
84
|
-
def
|
85
|
-
compact_index_client.
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
compact_index_client
|
75
|
+
def fetch_gem_infos(names)
|
76
|
+
in_parallel(names) {|name| compact_index_client.info(name) }
|
77
|
+
rescue TooManyRequestsError # rubygems.org is rate limiting us, slow down.
|
78
|
+
@bundle_worker&.stop
|
79
|
+
@bundle_worker = nil # reset it. Not sure if necessary
|
80
|
+
compact_index_client.reset!
|
81
|
+
names.map {|name| compact_index_client.info(name) }
|
93
82
|
end
|
94
83
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
84
|
+
def in_parallel(inputs, &blk)
|
85
|
+
func = lambda {|object, _index| blk.call(object) }
|
86
|
+
worker = bundle_worker(func)
|
87
|
+
inputs.each {|input| worker.enq(input) }
|
88
|
+
inputs.map { worker.deq }
|
98
89
|
end
|
99
90
|
|
100
91
|
def bundle_worker(func = nil)
|
@@ -307,7 +307,7 @@ Any \fB\.\fR characters in a host name are mapped to a double underscore (\fB__\
|
|
307
307
|
.P
|
308
308
|
This means that if you have a gem server named \fBmy\.gem\-host\.com\fR, you'll need to use the \fBBUNDLE_MY__GEM___HOST__COM\fR variable to configure credentials for it through ENV\.
|
309
309
|
.SH "CONFIGURE BUNDLER DIRECTORIES"
|
310
|
-
Bundler's home,
|
310
|
+
Bundler's home, cache and plugin directories and config file can be configured through environment variables\. The default location for Bundler's home directory is \fB~/\.bundle\fR, which all directories inherit from by default\. The following outlines the available environment variables and their default values
|
311
311
|
.IP "" 4
|
312
312
|
.nf
|
313
313
|
BUNDLE_USER_HOME : $HOME/\.bundle
|
@@ -397,7 +397,7 @@ through ENV.
|
|
397
397
|
|
398
398
|
## CONFIGURE BUNDLER DIRECTORIES
|
399
399
|
|
400
|
-
Bundler's home,
|
400
|
+
Bundler's home, cache and plugin directories and config file can be configured
|
401
401
|
through environment variables. The default location for Bundler's home directory is
|
402
402
|
`~/.bundle`, which all directories inherit from by default. The following
|
403
403
|
outlines the available environment variables and their default values
|