bundler 2.4.19 → 2.4.20
Sign up to get free protection for your applications and to get access to all the features.
- 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
|