bundler 2.4.19 → 2.4.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/info.rb +1 -1
- data/lib/bundler/cli/update.rb +1 -0
- data/lib/bundler/fetcher/base.rb +2 -2
- data/lib/bundler/fetcher/compact_index.rb +1 -5
- data/lib/bundler/fetcher/dependency.rb +1 -1
- data/lib/bundler/fetcher.rb +31 -30
- data/lib/bundler/index.rb +62 -31
- data/lib/bundler/installer/standalone.rb +8 -1
- data/lib/bundler/lockfile_parser.rb +3 -15
- data/lib/bundler/man/gemfile.5 +11 -0
- data/lib/bundler/man/gemfile.5.ronn +5 -0
- data/lib/bundler/plugin.rb +1 -1
- data/lib/bundler/resolver.rb +18 -3
- data/lib/bundler/retry.rb +1 -1
- data/lib/bundler/ruby_dsl.rb +23 -2
- data/lib/bundler/self_manager.rb +2 -0
- data/lib/bundler/settings.rb +37 -13
- data/lib/bundler/source/git/git_proxy.rb +14 -2
- data/lib/bundler/source/rubygems.rb +22 -25
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +1 -1
- data/lib/bundler/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6276990d50143a594e7e8625034add1d1168df511587dd82c74f7b93a7e66bdc
|
4
|
+
data.tar.gz: cca71ac6a7840814e8a7178ca795ed379684658b25c320e8bb67f2c022d3f2e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5162fc140937170d6c3a58e7f9097cbffbcda5fa8edc96a22a14fa5c1ed548cebb8d45fc9ae9901078f4dd1ff99e6f9892f832c2b6a1f598cd34f5163e80b282
|
7
|
+
data.tar.gz: 0aea59def565fa9dc8172659891fe2e6ce7b20a033f5197e1679536c91d1102a170a3784d7a05da0255662d6d342b2d1972a437fcad919756f50321b0a6801df
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
# 2.4.20 (September 27, 2023)
|
2
|
+
|
3
|
+
## Enhancements:
|
4
|
+
|
5
|
+
- Bump actions/checkout to v4 in bundler gem template [#6966](https://github.com/rubygems/rubygems/pull/6966)
|
6
|
+
- Add support for the `ruby-3.2.2` format in the `ruby file:` Gemfile directive, and explicitly test the `3.2.2@gemset` format as rejected [#6954](https://github.com/rubygems/rubygems/pull/6954)
|
7
|
+
- Support `ruby file: ".tool-versions"` in Gemfile [#6898](https://github.com/rubygems/rubygems/pull/6898)
|
8
|
+
- Unify LockfileParser loading of SPECS section [#6933](https://github.com/rubygems/rubygems/pull/6933)
|
9
|
+
- Only check circular deps when dependency api is available, not on full index sources [#6919](https://github.com/rubygems/rubygems/pull/6919)
|
10
|
+
|
11
|
+
## Bug fixes:
|
12
|
+
|
13
|
+
- Allow standalone mode to work on a Windows edge case [#6989](https://github.com/rubygems/rubygems/pull/6989)
|
14
|
+
- Fix `bundle outdated` crashing when both `ref` and `branch` specified for a git gem in Gemfile [#6959](https://github.com/rubygems/rubygems/pull/6959)
|
15
|
+
- Fix `bundle update --redownload` [#6924](https://github.com/rubygems/rubygems/pull/6924)
|
16
|
+
- Fixed malformed bundler version in lockfile making Bundler crash [#6920](https://github.com/rubygems/rubygems/pull/6920)
|
17
|
+
- Fix standalone install crashing when using legacy gemfiles with multiple global sources [#6918](https://github.com/rubygems/rubygems/pull/6918)
|
18
|
+
- Resolve ruby version file relative to bundle root [#6892](https://github.com/rubygems/rubygems/pull/6892)
|
19
|
+
|
20
|
+
## Performance:
|
21
|
+
|
22
|
+
- Lazily construct fetcher debug messages [#6973](https://github.com/rubygems/rubygems/pull/6973)
|
23
|
+
- Avoid allocating empty hashes in Index [#6962](https://github.com/rubygems/rubygems/pull/6962)
|
24
|
+
- Stop allocating the same settings keys repeatedly [#6963](https://github.com/rubygems/rubygems/pull/6963)
|
25
|
+
- Improve `Bundler::Index` efficiency by removing unnecessary creation and dups [#6931](https://github.com/rubygems/rubygems/pull/6931)
|
26
|
+
- (Further) Improve Bundler::Settings#[] performance and memory usage [#6923](https://github.com/rubygems/rubygems/pull/6923)
|
27
|
+
- Don't use full indexes unnecessarily on legacy Gemfiles [#6916](https://github.com/rubygems/rubygems/pull/6916)
|
28
|
+
- Improve memory usage in Bundler::Settings, and thus improve boot time [#6884](https://github.com/rubygems/rubygems/pull/6884)
|
29
|
+
|
1
30
|
# 2.4.19 (August 17, 2023)
|
2
31
|
|
3
32
|
## Enhancements:
|
@@ -4,8 +4,8 @@ module Bundler
|
|
4
4
|
# Represents metadata from when the Bundler gem was built.
|
5
5
|
module BuildMetadata
|
6
6
|
# begin ivars
|
7
|
-
@built_at = "2023-
|
8
|
-
@git_commit_sha = "
|
7
|
+
@built_at = "2023-09-27".freeze
|
8
|
+
@git_commit_sha = "de20c7e7b".freeze
|
9
9
|
@release = true
|
10
10
|
# end ivars
|
11
11
|
|
data/lib/bundler/cli/info.rb
CHANGED
@@ -33,7 +33,7 @@ module Bundler
|
|
33
33
|
def default_gem_spec(gem_name)
|
34
34
|
return unless Gem::Specification.respond_to?(:find_all_by_name)
|
35
35
|
gem_spec = Gem::Specification.find_all_by_name(gem_name).last
|
36
|
-
|
36
|
+
gem_spec if gem_spec&.default_gem?
|
37
37
|
end
|
38
38
|
|
39
39
|
def spec_not_found(gem_name)
|
data/lib/bundler/cli/update.rb
CHANGED
data/lib/bundler/fetcher/base.rb
CHANGED
@@ -35,7 +35,7 @@ module Bundler
|
|
35
35
|
remaining_gems = gem_names.dup
|
36
36
|
|
37
37
|
until remaining_gems.empty?
|
38
|
-
log_specs "Looking up gems #{remaining_gems.inspect}"
|
38
|
+
log_specs { "Looking up gems #{remaining_gems.inspect}" }
|
39
39
|
|
40
40
|
deps = begin
|
41
41
|
parallel_compact_index_client.dependencies(remaining_gems)
|
@@ -60,10 +60,6 @@ module Bundler
|
|
60
60
|
Bundler.ui.debug("FIPS mode is enabled, bundler can't use the CompactIndex API")
|
61
61
|
return nil
|
62
62
|
end
|
63
|
-
if fetch_uri.scheme == "file"
|
64
|
-
Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
|
65
|
-
return false
|
66
|
-
end
|
67
63
|
# Read info file checksums out of /versions, so we can know if gems are up to date
|
68
64
|
compact_index_client.update_and_parse_checksums!
|
69
65
|
rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
|
@@ -24,7 +24,7 @@ module Bundler
|
|
24
24
|
def specs(gem_names, full_dependency_list = [], last_spec_list = [])
|
25
25
|
query_list = gem_names.uniq - full_dependency_list
|
26
26
|
|
27
|
-
log_specs "Query List: #{query_list.inspect}"
|
27
|
+
log_specs { "Query List: #{query_list.inspect}" }
|
28
28
|
|
29
29
|
return last_spec_list if query_list.empty?
|
30
30
|
|
data/lib/bundler/fetcher.rb
CHANGED
@@ -9,6 +9,7 @@ require "rubygems/request"
|
|
9
9
|
module Bundler
|
10
10
|
# Handles all the fetching with the rubygems server
|
11
11
|
class Fetcher
|
12
|
+
autoload :Base, File.expand_path("fetcher/base", __dir__)
|
12
13
|
autoload :CompactIndex, File.expand_path("fetcher/compact_index", __dir__)
|
13
14
|
autoload :Downloader, File.expand_path("fetcher/downloader", __dir__)
|
14
15
|
autoload :Dependency, File.expand_path("fetcher/dependency", __dir__)
|
@@ -134,18 +135,7 @@ module Bundler
|
|
134
135
|
def specs(gem_names, source)
|
135
136
|
index = Bundler::Index.new
|
136
137
|
|
137
|
-
|
138
|
-
@use_api = false
|
139
|
-
specs = fetchers.last.specs(gem_names)
|
140
|
-
else
|
141
|
-
specs = []
|
142
|
-
@fetchers = fetchers.drop_while do |f|
|
143
|
-
!f.available? || (f.api_fetcher? && !gem_names) || !specs = f.specs(gem_names)
|
144
|
-
end
|
145
|
-
@use_api = false if fetchers.none?(&:api_fetcher?)
|
146
|
-
end
|
147
|
-
|
148
|
-
specs.each do |name, version, platform, dependencies, metadata|
|
138
|
+
fetch_specs(gem_names).each do |name, version, platform, dependencies, metadata|
|
149
139
|
spec = if dependencies
|
150
140
|
EndpointSpecification.new(name, version, platform, self, dependencies, metadata)
|
151
141
|
else
|
@@ -158,22 +148,10 @@ module Bundler
|
|
158
148
|
|
159
149
|
index
|
160
150
|
rescue CertificateFailureError
|
161
|
-
Bundler.ui.info "" if gem_names &&
|
151
|
+
Bundler.ui.info "" if gem_names && api_fetcher? # newline after dots
|
162
152
|
raise
|
163
153
|
end
|
164
154
|
|
165
|
-
def use_api
|
166
|
-
return @use_api if defined?(@use_api)
|
167
|
-
|
168
|
-
fetchers.shift until fetchers.first.available?
|
169
|
-
|
170
|
-
@use_api = if remote_uri.scheme == "file" || Bundler::Fetcher.disable_endpoint
|
171
|
-
false
|
172
|
-
else
|
173
|
-
fetchers.first.api_fetcher?
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
155
|
def user_agent
|
178
156
|
@user_agent ||= begin
|
179
157
|
ruby = Bundler::RubyVersion.system
|
@@ -209,10 +187,6 @@ module Bundler
|
|
209
187
|
end
|
210
188
|
end
|
211
189
|
|
212
|
-
def fetchers
|
213
|
-
@fetchers ||= FETCHERS.map {|f| f.new(downloader, @remote, uri) }
|
214
|
-
end
|
215
|
-
|
216
190
|
def http_proxy
|
217
191
|
return unless uri = connection.proxy_uri
|
218
192
|
uri.to_s
|
@@ -222,9 +196,36 @@ module Bundler
|
|
222
196
|
"#<#{self.class}:0x#{object_id} uri=#{uri}>"
|
223
197
|
end
|
224
198
|
|
199
|
+
def api_fetcher?
|
200
|
+
fetchers.first.api_fetcher?
|
201
|
+
end
|
202
|
+
|
225
203
|
private
|
226
204
|
|
227
|
-
|
205
|
+
def available_fetchers
|
206
|
+
if Bundler::Fetcher.disable_endpoint
|
207
|
+
[Index]
|
208
|
+
elsif remote_uri.scheme == "file"
|
209
|
+
Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
|
210
|
+
[Index]
|
211
|
+
else
|
212
|
+
[CompactIndex, Dependency, Index]
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def fetchers
|
217
|
+
@fetchers ||= available_fetchers.map {|f| f.new(downloader, @remote, uri) }.drop_while {|f| !f.available? }
|
218
|
+
end
|
219
|
+
|
220
|
+
def fetch_specs(gem_names)
|
221
|
+
fetchers.reject!(&:api_fetcher?) unless gem_names
|
222
|
+
fetchers.reject! do |f|
|
223
|
+
specs = f.specs(gem_names)
|
224
|
+
return specs if specs
|
225
|
+
true
|
226
|
+
end
|
227
|
+
[]
|
228
|
+
end
|
228
229
|
|
229
230
|
def cis
|
230
231
|
env_cis = {
|
data/lib/bundler/index.rb
CHANGED
@@ -10,8 +10,8 @@ module Bundler
|
|
10
10
|
i
|
11
11
|
end
|
12
12
|
|
13
|
-
attr_reader :specs, :
|
14
|
-
protected :specs, :
|
13
|
+
attr_reader :specs, :duplicates, :sources
|
14
|
+
protected :specs, :duplicates
|
15
15
|
|
16
16
|
RUBY = "ruby"
|
17
17
|
NULL = "\0"
|
@@ -19,21 +19,21 @@ module Bundler
|
|
19
19
|
def initialize
|
20
20
|
@sources = []
|
21
21
|
@cache = {}
|
22
|
-
@specs =
|
23
|
-
@
|
22
|
+
@specs = {}
|
23
|
+
@duplicates = {}
|
24
24
|
end
|
25
25
|
|
26
26
|
def initialize_copy(o)
|
27
27
|
@sources = o.sources.dup
|
28
28
|
@cache = {}
|
29
|
-
@specs =
|
30
|
-
@
|
29
|
+
@specs = {}
|
30
|
+
@duplicates = {}
|
31
31
|
|
32
32
|
o.specs.each do |name, hash|
|
33
33
|
@specs[name] = hash.dup
|
34
34
|
end
|
35
|
-
o.
|
36
|
-
@
|
35
|
+
o.duplicates.each do |name, array|
|
36
|
+
@duplicates[name] = array.dup
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -46,12 +46,11 @@ module Bundler
|
|
46
46
|
true
|
47
47
|
end
|
48
48
|
|
49
|
-
def search_all(name)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
all_matches
|
49
|
+
def search_all(name, &blk)
|
50
|
+
return enum_for(:search_all, name) unless blk
|
51
|
+
specs_by_name(name).each(&blk)
|
52
|
+
@duplicates[name]&.each(&blk)
|
53
|
+
@sources.each {|source| source.search_all(name, &blk) }
|
55
54
|
end
|
56
55
|
|
57
56
|
# Search this index's specs, and any source indexes that this index knows
|
@@ -61,11 +60,14 @@ module Bundler
|
|
61
60
|
return results unless @sources.any?
|
62
61
|
|
63
62
|
@sources.each do |source|
|
64
|
-
results
|
63
|
+
results = safe_concat(results, source.search(query))
|
65
64
|
end
|
66
|
-
results.uniq(&:full_name)
|
65
|
+
results.uniq!(&:full_name) unless results.empty? # avoid modifying frozen EMPTY_SEARCH
|
66
|
+
results
|
67
67
|
end
|
68
68
|
|
69
|
+
alias_method :[], :search
|
70
|
+
|
69
71
|
def local_search(query)
|
70
72
|
case query
|
71
73
|
when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query)
|
@@ -76,12 +78,10 @@ module Bundler
|
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
|
80
|
-
|
81
|
-
def <<(spec)
|
82
|
-
@specs[spec.name][spec.full_name] = spec
|
83
|
-
spec
|
81
|
+
def add(spec)
|
82
|
+
(@specs[spec.name] ||= {}).store(spec.full_name, spec)
|
84
83
|
end
|
84
|
+
alias_method :<<, :add
|
85
85
|
|
86
86
|
def each(&blk)
|
87
87
|
return enum_for(:each) unless blk
|
@@ -115,15 +115,25 @@ module Bundler
|
|
115
115
|
names.uniq
|
116
116
|
end
|
117
117
|
|
118
|
-
|
118
|
+
# Combines indexes proritizing existing specs, like `Hash#reverse_merge!`
|
119
|
+
# Duplicate specs found in `other` are stored in `@duplicates`.
|
120
|
+
def use(other)
|
119
121
|
return unless other
|
120
|
-
other.each do |
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
122
|
+
other.each do |spec|
|
123
|
+
exist?(spec) ? add_duplicate(spec) : add(spec)
|
124
|
+
end
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
# Combines indexes proritizing specs from `other`, like `Hash#merge!`
|
129
|
+
# Duplicate specs found in `self` are saved in `@duplicates`.
|
130
|
+
def merge!(other)
|
131
|
+
return unless other
|
132
|
+
other.each do |spec|
|
133
|
+
if existing = find_by_spec(spec)
|
134
|
+
add_duplicate(existing)
|
125
135
|
end
|
126
|
-
|
136
|
+
add spec
|
127
137
|
end
|
128
138
|
self
|
129
139
|
end
|
@@ -157,19 +167,40 @@ module Bundler
|
|
157
167
|
|
158
168
|
private
|
159
169
|
|
170
|
+
def safe_concat(a, b)
|
171
|
+
return a if b.empty?
|
172
|
+
return b if a.empty?
|
173
|
+
a.concat(b)
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_duplicate(spec)
|
177
|
+
(@duplicates[spec.name] ||= []) << spec
|
178
|
+
end
|
179
|
+
|
160
180
|
def specs_by_name_and_version(name, version)
|
161
|
-
|
181
|
+
results = @specs[name]&.values
|
182
|
+
return EMPTY_SEARCH unless results
|
183
|
+
results.select! {|spec| spec.version == version }
|
184
|
+
results
|
162
185
|
end
|
163
186
|
|
164
187
|
def specs_by_name(name)
|
165
|
-
@specs[name]
|
188
|
+
@specs[name]&.values || EMPTY_SEARCH
|
166
189
|
end
|
167
190
|
|
168
191
|
EMPTY_SEARCH = [].freeze
|
169
192
|
|
170
193
|
def search_by_spec(spec)
|
171
|
-
spec =
|
194
|
+
spec = find_by_spec(spec)
|
172
195
|
spec ? [spec] : EMPTY_SEARCH
|
173
196
|
end
|
197
|
+
|
198
|
+
def find_by_spec(spec)
|
199
|
+
@specs[spec.name]&.fetch(spec.full_name, nil)
|
200
|
+
end
|
201
|
+
|
202
|
+
def exist?(spec)
|
203
|
+
@specs[spec.name]&.key?(spec.full_name)
|
204
|
+
end
|
174
205
|
end
|
175
206
|
end
|
@@ -55,13 +55,20 @@ module Bundler
|
|
55
55
|
if spec.source.instance_of?(Source::Path) && spec.source.path.absolute?
|
56
56
|
full_path
|
57
57
|
else
|
58
|
-
|
58
|
+
relative_path_from(Bundler.root.join(bundler_path), :to => full_path) || full_path
|
59
59
|
end
|
60
60
|
rescue TypeError
|
61
61
|
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
|
62
62
|
raise Gem::InvalidSpecificationException.new(error_message)
|
63
63
|
end
|
64
64
|
|
65
|
+
def relative_path_from(source, to:)
|
66
|
+
Pathname.new(to).relative_path_from(source).to_s
|
67
|
+
rescue ArgumentError
|
68
|
+
# on Windows, if source and destination are on different drivers, there's no relative path from one to the other
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
65
72
|
def define_path_helpers
|
66
73
|
<<~'END'
|
67
74
|
unless defined?(Gem)
|
@@ -110,21 +110,9 @@ module Bundler
|
|
110
110
|
def parse_source(line)
|
111
111
|
case line
|
112
112
|
when SPECS
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
@sources << @current_source
|
117
|
-
when GIT
|
118
|
-
@current_source = TYPES[@type].from_lock(@opts)
|
119
|
-
@sources << @current_source
|
120
|
-
when GEM
|
121
|
-
@opts["remotes"] = Array(@opts.delete("remote")).reverse
|
122
|
-
@current_source = TYPES[@type].from_lock(@opts)
|
123
|
-
@sources << @current_source
|
124
|
-
when PLUGIN
|
125
|
-
@current_source = Plugin.source_from_lock(@opts)
|
126
|
-
@sources << @current_source
|
127
|
-
end
|
113
|
+
return unless TYPES.key?(@type)
|
114
|
+
@current_source = TYPES[@type].from_lock(@opts)
|
115
|
+
@sources << @current_source
|
128
116
|
when OPTIONS
|
129
117
|
value = $2
|
130
118
|
value = true if value == "true"
|
data/lib/bundler/man/gemfile.5
CHANGED
@@ -98,6 +98,17 @@ ruby file: "\.ruby\-version"
|
|
98
98
|
.
|
99
99
|
.IP "" 0
|
100
100
|
.
|
101
|
+
.P
|
102
|
+
The version file should conform to any of the following formats:
|
103
|
+
.
|
104
|
+
.IP "\(bu" 4
|
105
|
+
\fB3\.1\.2\fR (\.ruby\-version)
|
106
|
+
.
|
107
|
+
.IP "\(bu" 4
|
108
|
+
\fBruby 3\.1\.2\fR (\.tool\-versions, read: https://asdf\-vm\.com/manage/configuration\.html#tool\-versions)
|
109
|
+
.
|
110
|
+
.IP "" 0
|
111
|
+
.
|
101
112
|
.SS "ENGINE"
|
102
113
|
Each application \fImay\fR specify a Ruby engine\. If an engine is specified, an engine version \fImust\fR also be specified\.
|
103
114
|
.
|
@@ -74,6 +74,11 @@ you can use the `file` option instead.
|
|
74
74
|
|
75
75
|
ruby file: ".ruby-version"
|
76
76
|
|
77
|
+
The version file should conform to any of the following formats:
|
78
|
+
|
79
|
+
- `3.1.2` (.ruby-version)
|
80
|
+
- `ruby 3.1.2` (.tool-versions, read: https://asdf-vm.com/manage/configuration.html#tool-versions)
|
81
|
+
|
77
82
|
### ENGINE
|
78
83
|
|
79
84
|
Each application _may_ specify a Ruby engine. If an engine is specified, an
|
data/lib/bundler/plugin.rb
CHANGED
@@ -197,7 +197,7 @@ module Bundler
|
|
197
197
|
# @param [Hash] The options that are present in the lock file
|
198
198
|
# @return [API::Source] the instance of the class that handles the source
|
199
199
|
# type passed in locked_opts
|
200
|
-
def
|
200
|
+
def from_lock(locked_opts)
|
201
201
|
src = source(locked_opts["type"])
|
202
202
|
|
203
203
|
src.new(locked_opts.merge("uri" => locked_opts["remote"]))
|
data/lib/bundler/resolver.rb
CHANGED
@@ -37,9 +37,17 @@ module Bundler
|
|
37
37
|
root_version = Resolver::Candidate.new(0)
|
38
38
|
|
39
39
|
@all_specs = Hash.new do |specs, name|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
source = source_for(name)
|
41
|
+
matches = source.specs.search(name)
|
42
|
+
|
43
|
+
# Don't bother to check for circular deps when no dependency API are
|
44
|
+
# available, since it's too slow to be usable. That edge case won't work
|
45
|
+
# but resolution other than that should work fine and reasonably fast.
|
46
|
+
if source.respond_to?(:dependency_api_available?) && source.dependency_api_available?
|
47
|
+
matches = filter_invalid_self_dependencies(matches, name)
|
48
|
+
end
|
49
|
+
|
50
|
+
specs[name] = matches.sort_by {|s| [s.version, s.platform.to_s] }
|
43
51
|
end
|
44
52
|
|
45
53
|
@sorted_versions = Hash.new do |candidates, package|
|
@@ -318,6 +326,13 @@ module Bundler
|
|
318
326
|
specs.reject {|s| s.version.prerelease? }
|
319
327
|
end
|
320
328
|
|
329
|
+
# Ignore versions that depend on themselves incorrectly
|
330
|
+
def filter_invalid_self_dependencies(specs, name)
|
331
|
+
specs.reject do |s|
|
332
|
+
s.dependencies.any? {|d| d.name == name && !d.requirement.satisfied_by?(s.version) }
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
321
336
|
def requirement_satisfied_by?(requirement, spec)
|
322
337
|
requirement.satisfied_by?(spec.version) || spec.source.is_a?(Source::Gemspec)
|
323
338
|
end
|
data/lib/bundler/retry.rb
CHANGED
data/lib/bundler/ruby_dsl.rb
CHANGED
@@ -10,8 +10,8 @@ module Bundler
|
|
10
10
|
raise GemfileError, "Please define :engine" if options[:engine_version] && options[:engine].nil?
|
11
11
|
|
12
12
|
if options[:file]
|
13
|
-
raise GemfileError, "
|
14
|
-
ruby_version <<
|
13
|
+
raise GemfileError, "Do not pass version argument when using :file option" unless ruby_version.empty?
|
14
|
+
ruby_version << normalize_ruby_file(options[:file])
|
15
15
|
end
|
16
16
|
|
17
17
|
if options[:engine] == "ruby" && options[:engine_version] &&
|
@@ -20,5 +20,26 @@ module Bundler
|
|
20
20
|
end
|
21
21
|
@ruby_version = RubyVersion.new(ruby_version, options[:patchlevel], options[:engine], options[:engine_version])
|
22
22
|
end
|
23
|
+
|
24
|
+
# Support the various file formats found in .ruby-version files.
|
25
|
+
#
|
26
|
+
# 3.2.2
|
27
|
+
# ruby-3.2.2
|
28
|
+
#
|
29
|
+
# Also supports .tool-versions files for asdf. Lines not starting with "ruby" are ignored.
|
30
|
+
#
|
31
|
+
# ruby 2.5.1 # comment is ignored
|
32
|
+
# ruby 2.5.1# close comment and extra spaces doesn't confuse
|
33
|
+
#
|
34
|
+
# Intentionally does not support `3.2.1@gemset` since rvm recommends using .ruby-gemset instead
|
35
|
+
def normalize_ruby_file(filename)
|
36
|
+
file_content = Bundler.read_file(Bundler.root.join(filename))
|
37
|
+
# match "ruby-3.2.2" or "ruby 3.2.2" capturing version string up to the first space or comment
|
38
|
+
if /^ruby(-|\s+)([^\s#]+)/.match(file_content)
|
39
|
+
$2
|
40
|
+
else
|
41
|
+
file_content.strip
|
42
|
+
end
|
43
|
+
end
|
23
44
|
end
|
24
45
|
end
|
data/lib/bundler/self_manager.rb
CHANGED
data/lib/bundler/settings.rb
CHANGED
@@ -88,14 +88,24 @@ module Bundler
|
|
88
88
|
def initialize(root = nil)
|
89
89
|
@root = root
|
90
90
|
@local_config = load_config(local_config_file)
|
91
|
-
|
91
|
+
|
92
|
+
@env_config = ENV.to_h
|
93
|
+
@env_config.select! {|key, _value| key.start_with?("BUNDLE_") }
|
94
|
+
@env_config.delete("BUNDLE_")
|
95
|
+
|
92
96
|
@global_config = load_config(global_config_file)
|
93
97
|
@temporary = {}
|
94
98
|
end
|
95
99
|
|
96
100
|
def [](name)
|
97
101
|
key = key_for(name)
|
98
|
-
|
102
|
+
|
103
|
+
value = nil
|
104
|
+
configs.each do |_, config|
|
105
|
+
value = config[key]
|
106
|
+
next if value.nil?
|
107
|
+
break
|
108
|
+
end
|
99
109
|
|
100
110
|
converted_value(value, name)
|
101
111
|
end
|
@@ -138,17 +148,22 @@ module Bundler
|
|
138
148
|
end
|
139
149
|
|
140
150
|
def all
|
141
|
-
keys = @temporary.keys
|
151
|
+
keys = @temporary.keys.union(@global_config.keys, @local_config.keys, @env_config.keys)
|
142
152
|
|
143
|
-
keys.map do |key|
|
144
|
-
key
|
145
|
-
|
153
|
+
keys.map! do |key|
|
154
|
+
key = key.delete_prefix("BUNDLE_")
|
155
|
+
key.gsub!("___", "-")
|
156
|
+
key.gsub!("__", ".")
|
157
|
+
key.downcase!
|
158
|
+
key
|
159
|
+
end.sort!
|
160
|
+
keys
|
146
161
|
end
|
147
162
|
|
148
163
|
def local_overrides
|
149
164
|
repos = {}
|
150
165
|
all.each do |k|
|
151
|
-
repos[
|
166
|
+
repos[k.delete_prefix("local.")] = self[k] if k.start_with?("local.")
|
152
167
|
end
|
153
168
|
repos
|
154
169
|
end
|
@@ -301,7 +316,7 @@ module Bundler
|
|
301
316
|
private
|
302
317
|
|
303
318
|
def configs
|
304
|
-
{
|
319
|
+
@configs ||= {
|
305
320
|
:temporary => @temporary,
|
306
321
|
:local => @local_config,
|
307
322
|
:env => @env_config,
|
@@ -327,16 +342,20 @@ module Bundler
|
|
327
342
|
end
|
328
343
|
|
329
344
|
def is_bool(name)
|
330
|
-
|
345
|
+
name = name.to_s
|
346
|
+
BOOL_KEYS.include?(name) || BOOL_KEYS.include?(parent_setting_for(name))
|
331
347
|
end
|
332
348
|
|
333
349
|
def is_string(name)
|
334
|
-
|
350
|
+
name = name.to_s
|
351
|
+
STRING_KEYS.include?(name) || name.start_with?("local.") || name.start_with?("mirror.") || name.start_with?("build.")
|
335
352
|
end
|
336
353
|
|
337
354
|
def to_bool(value)
|
338
355
|
case value
|
339
|
-
when
|
356
|
+
when String
|
357
|
+
value.match?(/\A(false|f|no|n|0|)\z/i) ? false : true
|
358
|
+
when nil, false
|
340
359
|
false
|
341
360
|
else
|
342
361
|
true
|
@@ -392,6 +411,8 @@ module Bundler
|
|
392
411
|
end
|
393
412
|
|
394
413
|
def converted_value(value, key)
|
414
|
+
key = key.to_s
|
415
|
+
|
395
416
|
if is_array(key)
|
396
417
|
to_array(value)
|
397
418
|
elsif value.nil?
|
@@ -482,8 +503,11 @@ module Bundler
|
|
482
503
|
|
483
504
|
def self.key_for(key)
|
484
505
|
key = normalize_uri(key).to_s if key.is_a?(String) && key.start_with?("http", "mirror.http")
|
485
|
-
key = key.to_s.gsub(".", "__")
|
486
|
-
|
506
|
+
key = key.to_s.gsub(".", "__")
|
507
|
+
key.gsub!("-", "___")
|
508
|
+
key.upcase!
|
509
|
+
|
510
|
+
key.prepend("BUNDLE_")
|
487
511
|
end
|
488
512
|
|
489
513
|
# TODO: duplicates Rubygems#normalize_uri
|
@@ -43,6 +43,13 @@ module Bundler
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
class AmbiguousGitReference < GitError
|
47
|
+
def initialize(options)
|
48
|
+
msg = "Specification of branch or ref with tag is ambiguous. You specified #{options.inspect}"
|
49
|
+
super msg
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
46
53
|
# The GitProxy is responsible to interact with git repositories.
|
47
54
|
# All actions required by the Git source is encapsulated in this
|
48
55
|
# object.
|
@@ -53,10 +60,15 @@ module Bundler
|
|
53
60
|
def initialize(path, uri, options = {}, revision = nil, git = nil)
|
54
61
|
@path = path
|
55
62
|
@uri = uri
|
56
|
-
@branch = options["branch"]
|
57
63
|
@tag = options["tag"]
|
64
|
+
@branch = options["branch"]
|
58
65
|
@ref = options["ref"]
|
59
|
-
@
|
66
|
+
if @tag
|
67
|
+
raise AmbiguousGitReference.new(options) if @branch || @ref
|
68
|
+
@explicit_ref = @tag
|
69
|
+
else
|
70
|
+
@explicit_ref = @ref || @branch
|
71
|
+
end
|
60
72
|
@revision = revision
|
61
73
|
@git = git
|
62
74
|
@commit_ref = nil
|
@@ -88,6 +88,7 @@ module Bundler
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def self.from_lock(options)
|
91
|
+
options["remotes"] = Array(options.delete("remote")).reverse
|
91
92
|
new(options)
|
92
93
|
end
|
93
94
|
|
@@ -128,12 +129,12 @@ module Bundler
|
|
128
129
|
def specs
|
129
130
|
@specs ||= begin
|
130
131
|
# remote_specs usually generates a way larger Index than the other
|
131
|
-
# sources, and large_idx.
|
132
|
-
# small_idx.
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
132
|
+
# sources, and large_idx.merge! small_idx is way faster than
|
133
|
+
# small_idx.merge! large_idx.
|
134
|
+
index = @allow_remote ? remote_specs.dup : Index.new
|
135
|
+
index.merge!(cached_specs) if @allow_cached || @allow_remote
|
136
|
+
index.merge!(installed_specs) if @allow_local
|
137
|
+
index
|
137
138
|
end
|
138
139
|
end
|
139
140
|
|
@@ -237,7 +238,7 @@ module Bundler
|
|
237
238
|
end
|
238
239
|
|
239
240
|
def spec_names
|
240
|
-
if
|
241
|
+
if dependency_api_available?
|
241
242
|
remote_specs.spec_names
|
242
243
|
else
|
243
244
|
[]
|
@@ -245,7 +246,7 @@ module Bundler
|
|
245
246
|
end
|
246
247
|
|
247
248
|
def unmet_deps
|
248
|
-
if
|
249
|
+
if dependency_api_available?
|
249
250
|
remote_specs.unmet_dependency_names
|
250
251
|
else
|
251
252
|
[]
|
@@ -260,7 +261,6 @@ module Bundler
|
|
260
261
|
end
|
261
262
|
|
262
263
|
def double_check_for(unmet_dependency_names)
|
263
|
-
return unless @allow_remote
|
264
264
|
return unless dependency_api_available?
|
265
265
|
|
266
266
|
unmet_dependency_names = unmet_dependency_names.call
|
@@ -275,7 +275,9 @@ module Bundler
|
|
275
275
|
|
276
276
|
Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}"
|
277
277
|
|
278
|
-
fetch_names(api_fetchers, unmet_dependency_names,
|
278
|
+
fetch_names(api_fetchers, unmet_dependency_names, remote_specs)
|
279
|
+
|
280
|
+
specs.use remote_specs
|
279
281
|
end
|
280
282
|
|
281
283
|
def dependency_names_to_double_check
|
@@ -379,7 +381,7 @@ module Bundler
|
|
379
381
|
|
380
382
|
def cached_specs
|
381
383
|
@cached_specs ||= begin
|
382
|
-
idx =
|
384
|
+
idx = Index.new
|
383
385
|
|
384
386
|
Dir["#{cache_path}/*.gem"].each do |gemfile|
|
385
387
|
s ||= Bundler.rubygems.spec_from_gem(gemfile)
|
@@ -392,35 +394,30 @@ module Bundler
|
|
392
394
|
end
|
393
395
|
|
394
396
|
def api_fetchers
|
395
|
-
fetchers.select
|
397
|
+
fetchers.select(&:api_fetcher?)
|
396
398
|
end
|
397
399
|
|
398
400
|
def remote_specs
|
399
401
|
@remote_specs ||= Index.build do |idx|
|
400
402
|
index_fetchers = fetchers - api_fetchers
|
401
403
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
# uses the dependency API but others don't. So use full indexes
|
408
|
-
# consistently in that particular case.
|
409
|
-
allow_api = !multiple_remotes?
|
410
|
-
|
411
|
-
fetch_names(api_fetchers, allow_api && dependency_names, idx, false)
|
404
|
+
if index_fetchers.empty?
|
405
|
+
fetch_names(api_fetchers, dependency_names, idx)
|
406
|
+
else
|
407
|
+
fetch_names(fetchers, nil, idx)
|
408
|
+
end
|
412
409
|
end
|
413
410
|
end
|
414
411
|
|
415
|
-
def fetch_names(fetchers, dependency_names, index
|
412
|
+
def fetch_names(fetchers, dependency_names, index)
|
416
413
|
fetchers.each do |f|
|
417
414
|
if dependency_names
|
418
415
|
Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug?
|
419
|
-
index.use f.specs_with_retry(dependency_names, self)
|
416
|
+
index.use f.specs_with_retry(dependency_names, self)
|
420
417
|
Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over
|
421
418
|
else
|
422
419
|
Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}"
|
423
|
-
index.use f.specs_with_retry(nil, self)
|
420
|
+
index.use f.specs_with_retry(nil, self)
|
424
421
|
end
|
425
422
|
end
|
426
423
|
end
|
data/lib/bundler/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- André Arko
|
@@ -22,7 +22,7 @@ authors:
|
|
22
22
|
autorequire:
|
23
23
|
bindir: exe
|
24
24
|
cert_chain: []
|
25
|
-
date: 2023-
|
25
|
+
date: 2023-09-27 00:00:00.000000000 Z
|
26
26
|
dependencies: []
|
27
27
|
description: Bundler manages an application's dependencies through its entire life,
|
28
28
|
across many machines, systematically and repeatably
|
@@ -381,7 +381,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
381
381
|
- !ruby/object:Gem::Version
|
382
382
|
version: 3.0.1
|
383
383
|
requirements: []
|
384
|
-
rubygems_version: 3.4.
|
384
|
+
rubygems_version: 3.4.20
|
385
385
|
signing_key:
|
386
386
|
specification_version: 4
|
387
387
|
summary: The best way to manage your application's dependencies
|