bundler 2.2.11 → 2.3.6
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 +414 -5
- data/README.md +1 -1
- data/bundler.gemspec +2 -3
- data/exe/bundle +7 -8
- data/lib/bundler/.document +1 -0
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/cache.rb +1 -1
- data/lib/bundler/cli/check.rb +4 -2
- data/lib/bundler/cli/common.rb +15 -2
- data/lib/bundler/cli/doctor.rb +24 -5
- data/lib/bundler/cli/exec.rb +1 -6
- data/lib/bundler/cli/gem.rb +130 -26
- data/lib/bundler/cli/info.rb +16 -4
- data/lib/bundler/cli/install.rb +12 -27
- data/lib/bundler/cli/issue.rb +4 -3
- data/lib/bundler/cli/list.rb +7 -1
- data/lib/bundler/cli/lock.rb +5 -1
- data/lib/bundler/cli/open.rb +1 -2
- data/lib/bundler/cli/outdated.rb +10 -11
- data/lib/bundler/cli/platform.rb +1 -1
- data/lib/bundler/cli/remove.rb +1 -2
- data/lib/bundler/cli/update.rb +17 -8
- data/lib/bundler/cli.rb +41 -55
- data/lib/bundler/compact_index_client/cache.rb +0 -9
- data/lib/bundler/compact_index_client/updater.rb +10 -11
- data/lib/bundler/compact_index_client.rb +2 -8
- data/lib/bundler/current_ruby.rb +5 -4
- data/lib/bundler/definition.rb +147 -290
- data/lib/bundler/dependency.rb +5 -7
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +67 -66
- data/lib/bundler/endpoint_specification.rb +21 -11
- data/lib/bundler/env.rb +1 -1
- data/lib/bundler/environment_preserver.rb +4 -1
- data/lib/bundler/errors.rb +19 -3
- data/lib/bundler/feature_flag.rb +0 -4
- data/lib/bundler/fetcher/compact_index.rb +10 -15
- data/lib/bundler/fetcher/downloader.rb +9 -6
- data/lib/bundler/fetcher/index.rb +0 -27
- data/lib/bundler/fetcher.rb +10 -16
- data/lib/bundler/friendly_errors.rb +5 -32
- data/lib/bundler/gem_helper.rb +21 -16
- data/lib/bundler/index.rb +2 -7
- data/lib/bundler/injector.rb +12 -3
- data/lib/bundler/inline.rb +2 -1
- data/lib/bundler/installer/gem_installer.rb +4 -22
- data/lib/bundler/installer/parallel_installer.rb +36 -15
- data/lib/bundler/installer/standalone.rb +14 -9
- data/lib/bundler/installer.rb +8 -17
- data/lib/bundler/lazy_specification.rb +23 -2
- data/lib/bundler/lockfile_generator.rb +1 -1
- data/lib/bundler/lockfile_parser.rb +16 -45
- data/lib/bundler/man/bundle-add.1 +10 -2
- data/lib/bundler/man/bundle-add.1.ronn +7 -1
- data/lib/bundler/man/bundle-binstubs.1 +1 -1
- data/lib/bundler/man/bundle-cache.1 +1 -1
- data/lib/bundler/man/bundle-check.1 +1 -1
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +23 -15
- data/lib/bundler/man/bundle-config.1.ronn +24 -17
- data/lib/bundler/man/bundle-doctor.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +14 -1
- data/lib/bundler/man/bundle-gem.1.ronn +16 -0
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-inject.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +2 -2
- data/lib/bundler/man/bundle-install.1.ronn +2 -2
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-lock.1 +1 -1
- data/lib/bundler/man/bundle-open.1 +1 -1
- data/lib/bundler/man/bundle-outdated.1 +1 -1
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-show.1 +1 -1
- data/lib/bundler/man/bundle-update.1 +5 -5
- data/lib/bundler/man/bundle-update.1.ronn +5 -4
- data/lib/bundler/man/bundle-viz.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +28 -2
- data/lib/bundler/man/gemfile.5.ronn +9 -1
- data/lib/bundler/plugin/api/source.rb +22 -0
- data/lib/bundler/plugin/index.rb +4 -1
- data/lib/bundler/plugin/installer.rb +10 -10
- data/lib/bundler/plugin/source_list.rb +4 -0
- data/lib/bundler/plugin.rb +28 -8
- data/lib/bundler/process_lock.rb +1 -1
- data/lib/bundler/psyched_yaml.rb +1 -13
- data/lib/bundler/remote_specification.rb +7 -0
- data/lib/bundler/resolver/spec_group.rb +1 -25
- data/lib/bundler/resolver.rb +55 -147
- data/lib/bundler/retry.rb +1 -1
- data/lib/bundler/ruby_version.rb +1 -1
- data/lib/bundler/rubygems_ext.rb +30 -8
- data/lib/bundler/rubygems_gem_installer.rb +68 -1
- data/lib/bundler/rubygems_integration.rb +43 -60
- data/lib/bundler/runtime.rb +18 -11
- data/lib/bundler/self_manager.rb +168 -0
- data/lib/bundler/settings.rb +96 -20
- data/lib/bundler/setup.rb +2 -2
- data/lib/bundler/shared_helpers.rb +4 -19
- data/lib/bundler/source/git/git_proxy.rb +8 -6
- data/lib/bundler/source/git.rb +22 -4
- data/lib/bundler/source/metadata.rb +1 -5
- data/lib/bundler/source/path/installer.rb +1 -1
- data/lib/bundler/source/path.rb +3 -1
- data/lib/bundler/source/rubygems.rb +111 -106
- data/lib/bundler/source/rubygems_aggregate.rb +68 -0
- data/lib/bundler/source.rb +21 -0
- data/lib/bundler/source_list.rb +100 -60
- data/lib/bundler/source_map.rb +58 -0
- data/lib/bundler/spec_set.rb +17 -31
- data/lib/bundler/stub_specification.rb +8 -0
- data/lib/bundler/templates/Executable.bundler +7 -7
- data/lib/bundler/templates/Gemfile +0 -2
- data/lib/bundler/templates/gems.rb +0 -3
- data/lib/bundler/templates/newgem/Gemfile.tt +5 -2
- data/lib/bundler/templates/newgem/README.md.tt +5 -3
- data/lib/bundler/templates/newgem/Rakefile.tt +15 -2
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +15 -6
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +18 -16
- data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
- data/lib/bundler/templates/newgem/standard.yml.tt +3 -0
- data/lib/bundler/templates/newgem/test/minitest/{newgem_test.rb.tt → test_newgem.rb.tt} +1 -1
- data/lib/bundler/ui/shell.rb +1 -1
- data/lib/bundler/vendor/.document +1 -0
- data/lib/bundler/vendor/connection_pool/LICENSE +20 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +19 -21
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/wrapper.rb +57 -0
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +39 -74
- data/lib/bundler/vendor/fileutils/LICENSE.txt +22 -0
- data/lib/bundler/vendor/molinillo/LICENSE +9 -0
- data/lib/bundler/vendor/molinillo/lib/molinillo/dependency_graph.rb +2 -2
- data/lib/bundler/vendor/molinillo/lib/molinillo/modules/specification_provider.rb +1 -1
- data/lib/bundler/vendor/net-http-persistent/README.rdoc +82 -0
- data/lib/bundler/vendor/thor/LICENSE.md +20 -0
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +5 -5
- data/lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb +1 -2
- data/lib/bundler/vendor/thor/lib/thor/actions.rb +6 -2
- data/lib/bundler/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +6 -0
- data/lib/bundler/vendor/thor/lib/thor/error.rb +9 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +19 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +22 -4
- data/lib/bundler/vendor/thor/lib/thor/shell.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/util.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/tmpdir/lib/tmpdir.rb +1 -1
- data/lib/bundler/vendor/tsort/LICENSE.txt +22 -0
- data/lib/bundler/vendor/tsort/lib/tsort.rb +453 -0
- data/lib/bundler/vendor/uri/LICENSE.txt +22 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +17 -80
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +5 -6
- data/lib/bundler/vendor/uri/lib/uri/http.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/https.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/ldap.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/mailto.rb +0 -1
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +1 -14
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +1 -12
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/ws.rb +84 -0
- data/lib/bundler/vendor/uri/lib/uri/wss.rb +22 -0
- data/lib/bundler/vendor/uri/lib/uri.rb +0 -1
- data/lib/bundler/vendored_tsort.rb +4 -0
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/worker.rb +19 -4
- data/lib/bundler.rb +28 -31
- metadata +27 -9
- data/lib/bundler/gemdeps.rb +0 -29
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/monotonic_time.rb +0 -66
data/lib/bundler/definition.rb
CHANGED
|
@@ -6,6 +6,11 @@ module Bundler
|
|
|
6
6
|
class Definition
|
|
7
7
|
include GemHelpers
|
|
8
8
|
|
|
9
|
+
class << self
|
|
10
|
+
# Do not create or modify a lockfile (Makes #lock a noop)
|
|
11
|
+
attr_accessor :no_lock
|
|
12
|
+
end
|
|
13
|
+
|
|
9
14
|
attr_reader(
|
|
10
15
|
:dependencies,
|
|
11
16
|
:locked_deps,
|
|
@@ -56,10 +61,8 @@ module Bundler
|
|
|
56
61
|
@unlocking_bundler = false
|
|
57
62
|
@unlocking = unlock
|
|
58
63
|
else
|
|
59
|
-
unlock = unlock.dup
|
|
60
64
|
@unlocking_bundler = unlock.delete(:bundler)
|
|
61
|
-
unlock.
|
|
62
|
-
@unlocking = !unlock.empty?
|
|
65
|
+
@unlocking = unlock.any? {|_k, v| !Array(v).empty? }
|
|
63
66
|
end
|
|
64
67
|
|
|
65
68
|
@dependencies = dependencies
|
|
@@ -75,7 +78,6 @@ module Bundler
|
|
|
75
78
|
@lockfile_contents = String.new
|
|
76
79
|
@locked_bundler_version = nil
|
|
77
80
|
@locked_ruby_version = nil
|
|
78
|
-
@locked_specs_incomplete_for_platform = false
|
|
79
81
|
@new_platform = nil
|
|
80
82
|
|
|
81
83
|
if lockfile && File.exist?(lockfile)
|
|
@@ -106,7 +108,19 @@ module Bundler
|
|
|
106
108
|
@locked_platforms = []
|
|
107
109
|
end
|
|
108
110
|
|
|
109
|
-
@
|
|
111
|
+
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
112
|
+
@multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
|
|
113
|
+
|
|
114
|
+
if @multisource_allowed
|
|
115
|
+
unless sources.aggregate_global_source?
|
|
116
|
+
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
|
|
117
|
+
|
|
118
|
+
Bundler::SharedHelpers.major_deprecation 2, msg
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
@sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
|
|
122
|
+
end
|
|
123
|
+
|
|
110
124
|
@unlock[:sources] ||= []
|
|
111
125
|
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
|
|
112
126
|
@ruby_version.diff(locked_ruby_version_object)
|
|
@@ -119,14 +133,18 @@ module Bundler
|
|
|
119
133
|
@path_changes = converge_paths
|
|
120
134
|
@source_changes = converge_sources
|
|
121
135
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
136
|
+
if @unlock[:conservative]
|
|
137
|
+
@unlock[:gems] ||= @dependencies.map(&:name)
|
|
138
|
+
else
|
|
139
|
+
eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
|
|
140
|
+
@unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name)
|
|
125
141
|
end
|
|
126
142
|
|
|
127
143
|
@dependency_changes = converge_dependencies
|
|
128
144
|
@local_changes = converge_locals
|
|
129
145
|
|
|
146
|
+
@locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true)
|
|
147
|
+
|
|
130
148
|
@requires = compute_requires
|
|
131
149
|
end
|
|
132
150
|
|
|
@@ -145,17 +163,21 @@ module Bundler
|
|
|
145
163
|
end
|
|
146
164
|
end
|
|
147
165
|
|
|
166
|
+
def resolve_only_locally!
|
|
167
|
+
@remote = false
|
|
168
|
+
sources.local_only!
|
|
169
|
+
resolve
|
|
170
|
+
end
|
|
171
|
+
|
|
148
172
|
def resolve_with_cache!
|
|
149
|
-
raise "Specs already loaded" if @specs
|
|
150
173
|
sources.cached!
|
|
151
|
-
|
|
174
|
+
resolve
|
|
152
175
|
end
|
|
153
176
|
|
|
154
177
|
def resolve_remotely!
|
|
155
|
-
return if @specs
|
|
156
178
|
@remote = true
|
|
157
179
|
sources.remote!
|
|
158
|
-
|
|
180
|
+
resolve
|
|
159
181
|
end
|
|
160
182
|
|
|
161
183
|
# For given dependency list returns a SpecSet with Gemspec of all the required
|
|
@@ -165,25 +187,7 @@ module Bundler
|
|
|
165
187
|
#
|
|
166
188
|
# @return [Bundler::SpecSet]
|
|
167
189
|
def specs
|
|
168
|
-
@specs ||=
|
|
169
|
-
begin
|
|
170
|
-
specs = resolve.materialize(requested_dependencies)
|
|
171
|
-
rescue GemNotFound => e # Handle yanked gem
|
|
172
|
-
gem_name, gem_version = extract_gem_info(e)
|
|
173
|
-
locked_gem = @locked_specs[gem_name].last
|
|
174
|
-
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
|
|
175
|
-
raise GemNotFound, "Your bundle is locked to #{locked_gem}, but that version could not " \
|
|
176
|
-
"be found in any of the sources listed in your Gemfile. If you haven't changed sources, " \
|
|
177
|
-
"that means the author of #{locked_gem} has removed it. You'll need to update your bundle " \
|
|
178
|
-
"to a version other than #{locked_gem} that hasn't been removed in order to install."
|
|
179
|
-
end
|
|
180
|
-
unless specs["bundler"].any?
|
|
181
|
-
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
|
182
|
-
specs["bundler"] = bundler
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
specs
|
|
186
|
-
end
|
|
190
|
+
@specs ||= materialize(requested_dependencies)
|
|
187
191
|
end
|
|
188
192
|
|
|
189
193
|
def new_specs
|
|
@@ -195,9 +199,7 @@ module Bundler
|
|
|
195
199
|
end
|
|
196
200
|
|
|
197
201
|
def missing_specs
|
|
198
|
-
|
|
199
|
-
resolve.materialize(requested_dependencies, missing)
|
|
200
|
-
missing
|
|
202
|
+
resolve.materialize(requested_dependencies).missing_specs
|
|
201
203
|
end
|
|
202
204
|
|
|
203
205
|
def missing_specs?
|
|
@@ -206,7 +208,6 @@ module Bundler
|
|
|
206
208
|
Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
|
|
207
209
|
true
|
|
208
210
|
rescue BundlerError => e
|
|
209
|
-
@index = nil
|
|
210
211
|
@resolve = nil
|
|
211
212
|
@specs = nil
|
|
212
213
|
@gem_version_promoter = nil
|
|
@@ -216,17 +217,11 @@ module Bundler
|
|
|
216
217
|
end
|
|
217
218
|
|
|
218
219
|
def requested_specs
|
|
219
|
-
|
|
220
|
-
groups = requested_groups
|
|
221
|
-
groups.map!(&:to_sym)
|
|
222
|
-
specs_for(groups)
|
|
223
|
-
end
|
|
220
|
+
specs_for(requested_groups)
|
|
224
221
|
end
|
|
225
222
|
|
|
226
223
|
def requested_dependencies
|
|
227
|
-
|
|
228
|
-
groups.map!(&:to_sym)
|
|
229
|
-
dependencies_for(groups)
|
|
224
|
+
dependencies_for(requested_groups)
|
|
230
225
|
end
|
|
231
226
|
|
|
232
227
|
def current_dependencies
|
|
@@ -235,15 +230,22 @@ module Bundler
|
|
|
235
230
|
end
|
|
236
231
|
end
|
|
237
232
|
|
|
233
|
+
def locked_dependencies
|
|
234
|
+
@locked_deps.values
|
|
235
|
+
end
|
|
236
|
+
|
|
238
237
|
def specs_for(groups)
|
|
238
|
+
return specs if groups.empty?
|
|
239
239
|
deps = dependencies_for(groups)
|
|
240
|
-
|
|
240
|
+
materialize(deps)
|
|
241
241
|
end
|
|
242
242
|
|
|
243
243
|
def dependencies_for(groups)
|
|
244
|
-
|
|
244
|
+
groups.map!(&:to_sym)
|
|
245
|
+
deps = current_dependencies.reject do |d|
|
|
245
246
|
(d.groups & groups).empty?
|
|
246
247
|
end
|
|
248
|
+
expand_dependencies(deps)
|
|
247
249
|
end
|
|
248
250
|
|
|
249
251
|
# Resolve all the dependencies specified in Gemfile. It ensures that
|
|
@@ -263,60 +265,12 @@ module Bundler
|
|
|
263
265
|
else
|
|
264
266
|
# Run a resolve against the locally available gems
|
|
265
267
|
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
|
|
266
|
-
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies,
|
|
267
|
-
Resolver.resolve(expanded_dependencies,
|
|
268
|
+
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
|
|
269
|
+
Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
|
|
268
270
|
end
|
|
269
271
|
end
|
|
270
272
|
end
|
|
271
273
|
|
|
272
|
-
def index
|
|
273
|
-
@index ||= Index.build do |idx|
|
|
274
|
-
dependency_names = @dependencies.map(&:name)
|
|
275
|
-
|
|
276
|
-
sources.all_sources.each do |source|
|
|
277
|
-
source.dependency_names = dependency_names - pinned_spec_names(source)
|
|
278
|
-
idx.add_source source.specs
|
|
279
|
-
dependency_names.concat(source.unmet_deps).uniq!
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
double_check_for_index(idx, dependency_names)
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
# Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
|
|
287
|
-
# sources A and B. At this point, the API request will have found all the versions of Bar in source A,
|
|
288
|
-
# but will not have found any versions of Bar from source B, which is a problem if the requested version
|
|
289
|
-
# of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
|
|
290
|
-
# each spec we found, we add all possible versions from all sources to the index.
|
|
291
|
-
def double_check_for_index(idx, dependency_names)
|
|
292
|
-
pinned_names = pinned_spec_names
|
|
293
|
-
loop do
|
|
294
|
-
idxcount = idx.size
|
|
295
|
-
|
|
296
|
-
names = :names # do this so we only have to traverse to get dependency_names from the index once
|
|
297
|
-
unmet_dependency_names = lambda do
|
|
298
|
-
return names unless names == :names
|
|
299
|
-
new_names = sources.all_sources.map(&:dependency_names_to_double_check)
|
|
300
|
-
return names = nil if new_names.compact!
|
|
301
|
-
names = new_names.flatten(1).concat(dependency_names)
|
|
302
|
-
names.uniq!
|
|
303
|
-
names -= pinned_names
|
|
304
|
-
names
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
sources.all_sources.each do |source|
|
|
308
|
-
source.double_check_for(unmet_dependency_names)
|
|
309
|
-
end
|
|
310
|
-
|
|
311
|
-
break if idxcount == idx.size
|
|
312
|
-
end
|
|
313
|
-
end
|
|
314
|
-
private :double_check_for_index
|
|
315
|
-
|
|
316
|
-
def has_rubygems_remotes?
|
|
317
|
-
sources.rubygems_sources.any? {|s| s.remotes.any? }
|
|
318
|
-
end
|
|
319
|
-
|
|
320
274
|
def spec_git_paths
|
|
321
275
|
sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
|
|
322
276
|
end
|
|
@@ -326,6 +280,8 @@ module Bundler
|
|
|
326
280
|
end
|
|
327
281
|
|
|
328
282
|
def lock(file, preserve_unknown_sections = false)
|
|
283
|
+
return if Definition.no_lock
|
|
284
|
+
|
|
329
285
|
contents = to_lock
|
|
330
286
|
|
|
331
287
|
# Convert to \r\n if the existing lock has them
|
|
@@ -336,10 +292,7 @@ module Bundler
|
|
|
336
292
|
locked_major = @locked_bundler_version.segments.first
|
|
337
293
|
current_major = Gem::Version.create(Bundler::VERSION).segments.first
|
|
338
294
|
|
|
339
|
-
|
|
340
|
-
Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
|
|
341
|
-
"after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
|
|
342
|
-
end
|
|
295
|
+
updating_major = locked_major < current_major
|
|
343
296
|
end
|
|
344
297
|
|
|
345
298
|
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
|
@@ -356,14 +309,6 @@ module Bundler
|
|
|
356
309
|
end
|
|
357
310
|
end
|
|
358
311
|
|
|
359
|
-
def locked_bundler_version
|
|
360
|
-
if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
|
|
361
|
-
new_version = Bundler::VERSION
|
|
362
|
-
end
|
|
363
|
-
|
|
364
|
-
new_version || @locked_bundler_version || Bundler::VERSION
|
|
365
|
-
end
|
|
366
|
-
|
|
367
312
|
def locked_ruby_version
|
|
368
313
|
return unless ruby_version
|
|
369
314
|
if @unlock[:ruby] || !@locked_ruby_version
|
|
@@ -415,44 +360,31 @@ module Bundler
|
|
|
415
360
|
added.concat new_platforms.map {|p| "* platform: #{p}" }
|
|
416
361
|
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
|
|
417
362
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
new_sources = gemfile_sources - @locked_sources
|
|
421
|
-
deleted_sources = @locked_sources - gemfile_sources
|
|
363
|
+
new_deps = @dependencies - locked_dependencies
|
|
364
|
+
deleted_deps = locked_dependencies - @dependencies
|
|
422
365
|
|
|
423
|
-
new_deps
|
|
424
|
-
deleted_deps
|
|
366
|
+
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
|
367
|
+
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
|
|
425
368
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
|
429
|
-
deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
|
430
|
-
end
|
|
369
|
+
both_sources = Hash.new {|h, k| h[k] = [] }
|
|
370
|
+
@dependencies.each {|d| both_sources[d.name][0] = d }
|
|
431
371
|
|
|
432
|
-
|
|
433
|
-
if
|
|
434
|
-
added.concat new_sources.map {|source| "* source: #{source}" }
|
|
435
|
-
end
|
|
372
|
+
locked_dependencies.each do |d|
|
|
373
|
+
next if !Bundler.feature_flag.bundler_3_mode? && @locked_specs[d.name].empty?
|
|
436
374
|
|
|
437
|
-
|
|
438
|
-
deleted.concat deleted_sources.map {|source| "* source: #{source}" }
|
|
439
|
-
end
|
|
375
|
+
both_sources[d.name][1] = d
|
|
440
376
|
end
|
|
441
377
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
|
|
445
|
-
end
|
|
378
|
+
both_sources.each do |name, (dep, lock_dep)|
|
|
379
|
+
next if dep.nil? || lock_dep.nil?
|
|
446
380
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
381
|
+
gemfile_source = dep.source || sources.default_source
|
|
382
|
+
lock_source = lock_dep.source || sources.default_source
|
|
383
|
+
next if lock_source.include?(gemfile_source)
|
|
450
384
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
lockfile_source_name = lock_source
|
|
455
|
-
changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
|
|
385
|
+
gemfile_source_name = dep.source ? gemfile_source.identifier : "no specified source"
|
|
386
|
+
lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source"
|
|
387
|
+
changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
|
|
456
388
|
end
|
|
457
389
|
|
|
458
390
|
reason = change_reason
|
|
@@ -519,14 +451,6 @@ module Bundler
|
|
|
519
451
|
end
|
|
520
452
|
end
|
|
521
453
|
|
|
522
|
-
def find_resolved_spec(current_spec)
|
|
523
|
-
specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
|
|
524
|
-
end
|
|
525
|
-
|
|
526
|
-
def find_indexed_specs(current_spec)
|
|
527
|
-
index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
|
|
528
|
-
end
|
|
529
|
-
|
|
530
454
|
attr_reader :sources
|
|
531
455
|
private :sources
|
|
532
456
|
|
|
@@ -540,8 +464,38 @@ module Bundler
|
|
|
540
464
|
|
|
541
465
|
private
|
|
542
466
|
|
|
467
|
+
def materialize(dependencies)
|
|
468
|
+
specs = resolve.materialize(dependencies)
|
|
469
|
+
missing_specs = specs.missing_specs
|
|
470
|
+
|
|
471
|
+
if missing_specs.any?
|
|
472
|
+
missing_specs.each do |s|
|
|
473
|
+
locked_gem = @locked_specs[s.name].last
|
|
474
|
+
next if locked_gem.nil? || locked_gem.version != s.version || !@remote
|
|
475
|
+
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
|
|
476
|
+
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
|
|
477
|
+
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
|
|
478
|
+
"removed in order to install."
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
raise GemNotFound, "Could not find #{missing_specs.map(&:full_name).join(", ")} in any of the sources"
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
unless specs["bundler"].any?
|
|
485
|
+
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
|
486
|
+
specs["bundler"] = bundler
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
specs
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def precompute_source_requirements_for_indirect_dependencies?
|
|
493
|
+
@remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
|
|
494
|
+
end
|
|
495
|
+
|
|
543
496
|
def current_ruby_platform_locked?
|
|
544
497
|
return false unless generic_local_platform == Gem::Platform::RUBY
|
|
498
|
+
return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY)
|
|
545
499
|
|
|
546
500
|
current_platform_locked?
|
|
547
501
|
end
|
|
@@ -592,9 +546,9 @@ module Bundler
|
|
|
592
546
|
|
|
593
547
|
def dependencies_for_source_changed?(source, locked_source = source)
|
|
594
548
|
deps_for_source = @dependencies.select {|s| s.source == source }
|
|
595
|
-
locked_deps_for_source =
|
|
549
|
+
locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
|
|
596
550
|
|
|
597
|
-
deps_for_source.sort != locked_deps_for_source.sort
|
|
551
|
+
deps_for_source.uniq.sort != locked_deps_for_source.sort
|
|
598
552
|
end
|
|
599
553
|
|
|
600
554
|
def specs_for_source_changed?(source)
|
|
@@ -653,36 +607,11 @@ module Bundler
|
|
|
653
607
|
end
|
|
654
608
|
end
|
|
655
609
|
|
|
656
|
-
def converge_rubygems_sources
|
|
657
|
-
return false if Bundler.feature_flag.disable_multisource?
|
|
658
|
-
|
|
659
|
-
changes = false
|
|
660
|
-
|
|
661
|
-
# Get the RubyGems sources from the Gemfile.lock
|
|
662
|
-
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
663
|
-
# Get the RubyGems remotes from the Gemfile
|
|
664
|
-
actual_remotes = sources.rubygems_remotes
|
|
665
|
-
|
|
666
|
-
# If there is a RubyGems source in both
|
|
667
|
-
if !locked_gem_sources.empty? && !actual_remotes.empty?
|
|
668
|
-
locked_gem_sources.each do |locked_gem|
|
|
669
|
-
# Merge the remotes from the Gemfile into the Gemfile.lock
|
|
670
|
-
changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
|
|
671
|
-
end
|
|
672
|
-
end
|
|
673
|
-
|
|
674
|
-
changes
|
|
675
|
-
end
|
|
676
|
-
|
|
677
610
|
def converge_sources
|
|
678
|
-
changes = false
|
|
679
|
-
|
|
680
|
-
changes |= converge_rubygems_sources
|
|
681
|
-
|
|
682
611
|
# Replace the sources from the Gemfile with the sources from the Gemfile.lock,
|
|
683
612
|
# if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
|
|
684
613
|
# source in the Gemfile.lock, use the one from the Gemfile.
|
|
685
|
-
changes
|
|
614
|
+
changes = sources.replace_sources!(@locked_sources)
|
|
686
615
|
|
|
687
616
|
sources.all_sources.each do |source|
|
|
688
617
|
# If the source is unlockable and the current command allows an unlock of
|
|
@@ -700,25 +629,14 @@ module Bundler
|
|
|
700
629
|
end
|
|
701
630
|
|
|
702
631
|
def converge_dependencies
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
# after locked_source and sources don't match, we still use locked_source.
|
|
708
|
-
if frozen && !locked_source.nil? &&
|
|
709
|
-
locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
|
|
710
|
-
dep.source = locked_source.source
|
|
711
|
-
elsif dep.source
|
|
632
|
+
changes = false
|
|
633
|
+
|
|
634
|
+
@dependencies.each do |dep|
|
|
635
|
+
if dep.source
|
|
712
636
|
dep.source = sources.get(dep.source)
|
|
713
637
|
end
|
|
714
|
-
end
|
|
715
638
|
|
|
716
|
-
|
|
717
|
-
# We want to know if all match, but don't want to check all entries
|
|
718
|
-
# This means we need to return false if any dependency doesn't match
|
|
719
|
-
# the lock or doesn't exist in the lock.
|
|
720
|
-
@dependencies.each do |dependency|
|
|
721
|
-
unless locked_dep = @locked_deps[dependency.name]
|
|
639
|
+
unless locked_dep = @locked_deps[dep.name]
|
|
722
640
|
changes = true
|
|
723
641
|
next
|
|
724
642
|
end
|
|
@@ -729,11 +647,11 @@ module Bundler
|
|
|
729
647
|
# directive, the lockfile dependencies and resolved dependencies end up
|
|
730
648
|
# with a mismatch on #type. Work around that by setting the type on the
|
|
731
649
|
# dep from the lockfile.
|
|
732
|
-
locked_dep.instance_variable_set(:@type,
|
|
650
|
+
locked_dep.instance_variable_set(:@type, dep.type)
|
|
733
651
|
|
|
734
652
|
# We already know the name matches from the hash lookup
|
|
735
653
|
# so we only need to check the requirement now
|
|
736
|
-
changes ||=
|
|
654
|
+
changes ||= dep.requirement != locked_dep.requirement
|
|
737
655
|
end
|
|
738
656
|
|
|
739
657
|
changes
|
|
@@ -743,47 +661,37 @@ module Bundler
|
|
|
743
661
|
# commonly happen if the Gemfile has changed since the lockfile was last
|
|
744
662
|
# generated
|
|
745
663
|
def converge_locked_specs
|
|
746
|
-
|
|
664
|
+
resolve = converge_specs(@locked_specs)
|
|
747
665
|
|
|
748
|
-
|
|
749
|
-
# and Gemfile.lock. If the Gemfile modified a dependency, but
|
|
750
|
-
# the gem in the Gemfile.lock still satisfies it, this is fine
|
|
751
|
-
# too.
|
|
752
|
-
@dependencies.each do |dep|
|
|
753
|
-
locked_dep = @locked_deps[dep.name]
|
|
666
|
+
diff = nil
|
|
754
667
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
if in_locked_deps?(dep, locked_dep) || satisfies_locked_spec?(dep)
|
|
759
|
-
deps << dep
|
|
760
|
-
elsif dep.source.is_a?(Source::Path) && dep.current_platform? && (!locked_dep || dep.source != locked_dep.source)
|
|
761
|
-
@locked_specs.each do |s|
|
|
762
|
-
@unlock[:gems] << s.name if s.source == dep.source
|
|
763
|
-
end
|
|
668
|
+
# Now, we unlock any sources that do not have anymore gems pinned to it
|
|
669
|
+
sources.all_sources.each do |source|
|
|
670
|
+
next unless source.respond_to?(:unlock!)
|
|
764
671
|
|
|
765
|
-
|
|
766
|
-
|
|
672
|
+
unless resolve.any? {|s| s.source == source }
|
|
673
|
+
diff ||= @locked_specs.to_a - resolve.to_a
|
|
674
|
+
source.unlock! if diff.any? {|s| s.source == source }
|
|
767
675
|
end
|
|
768
676
|
end
|
|
769
677
|
|
|
770
|
-
|
|
678
|
+
resolve
|
|
679
|
+
end
|
|
771
680
|
|
|
681
|
+
def converge_specs(specs)
|
|
682
|
+
deps = []
|
|
772
683
|
converged = []
|
|
773
|
-
|
|
684
|
+
specs.each do |s|
|
|
774
685
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
|
775
686
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
|
776
|
-
s.source = (dep && dep.source) || sources.get(s.source)
|
|
777
687
|
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
next if @unlock[:sources].include?(s.source.name)
|
|
688
|
+
if dep && (!dep.source || s.source.include?(dep.source))
|
|
689
|
+
deps << dep
|
|
690
|
+
end
|
|
782
691
|
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
|
|
692
|
+
s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source unless Bundler.frozen_bundle?
|
|
693
|
+
|
|
694
|
+
next if @unlock[:sources].include?(s.source.name)
|
|
787
695
|
|
|
788
696
|
# If the spec is from a path source and it doesn't exist anymore
|
|
789
697
|
# then we unlock it.
|
|
@@ -795,8 +703,8 @@ module Bundler
|
|
|
795
703
|
rescue PathError, GitError
|
|
796
704
|
# if we won't need the source (according to the lockfile),
|
|
797
705
|
# don't error if the path/git source isn't available
|
|
798
|
-
next if
|
|
799
|
-
for(requested_dependencies,
|
|
706
|
+
next if specs.
|
|
707
|
+
for(requested_dependencies, false, true).
|
|
800
708
|
none? {|locked_spec| locked_spec.source == s.source }
|
|
801
709
|
|
|
802
710
|
raise
|
|
@@ -811,36 +719,15 @@ module Bundler
|
|
|
811
719
|
s.dependencies.replace(new_spec.dependencies)
|
|
812
720
|
end
|
|
813
721
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
|
|
819
|
-
resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems], false, false, false)
|
|
820
|
-
diff = nil
|
|
821
|
-
|
|
822
|
-
# Now, we unlock any sources that do not have anymore gems pinned to it
|
|
823
|
-
sources.all_sources.each do |source|
|
|
824
|
-
next unless source.respond_to?(:unlock!)
|
|
825
|
-
|
|
826
|
-
unless resolve.any? {|s| s.source == source }
|
|
827
|
-
diff ||= @locked_specs.to_a - resolve.to_a
|
|
828
|
-
source.unlock! if diff.any? {|s| s.source == source }
|
|
722
|
+
if dep.nil? && requested_dependencies.find {|d| s.name == d.name }
|
|
723
|
+
@unlock[:gems] << s.name
|
|
724
|
+
else
|
|
725
|
+
converged << s
|
|
829
726
|
end
|
|
830
727
|
end
|
|
831
728
|
|
|
832
|
-
resolve
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
def in_locked_deps?(dep, locked_dep)
|
|
836
|
-
# Because the lockfile can't link a dep to a specific remote, we need to
|
|
837
|
-
# treat sources as equivalent anytime the locked dep has all the remotes
|
|
838
|
-
# that the Gemfile dep does.
|
|
839
|
-
locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
|
|
840
|
-
end
|
|
841
|
-
|
|
842
|
-
def satisfies_locked_spec?(dep)
|
|
843
|
-
@locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
|
729
|
+
resolve = SpecSet.new(converged)
|
|
730
|
+
SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
|
|
844
731
|
end
|
|
845
732
|
|
|
846
733
|
def metadata_dependencies
|
|
@@ -887,38 +774,22 @@ module Bundler
|
|
|
887
774
|
end
|
|
888
775
|
|
|
889
776
|
def source_requirements
|
|
890
|
-
# Load all specs from remote sources
|
|
891
|
-
index
|
|
892
|
-
|
|
893
777
|
# Record the specs available in each gem's source, so that those
|
|
894
778
|
# specs will be available later when the resolver knows where to
|
|
895
779
|
# look for that gemspec (or its dependencies)
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
next unless source = dep.source || default
|
|
901
|
-
source_requirements[dep.name] = source
|
|
780
|
+
source_requirements = if precompute_source_requirements_for_indirect_dependencies?
|
|
781
|
+
{ :default => sources.default_source }.merge(source_map.all_requirements)
|
|
782
|
+
else
|
|
783
|
+
{ :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
|
|
902
784
|
end
|
|
903
785
|
metadata_dependencies.each do |dep|
|
|
904
786
|
source_requirements[dep.name] = sources.metadata_source
|
|
905
787
|
end
|
|
906
|
-
source_requirements[:default_bundler] = source_requirements["bundler"] ||
|
|
788
|
+
source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
|
|
907
789
|
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
|
|
908
790
|
source_requirements
|
|
909
791
|
end
|
|
910
792
|
|
|
911
|
-
def pinned_spec_names(skip = nil)
|
|
912
|
-
pinned_names = []
|
|
913
|
-
default = Bundler.feature_flag.disable_multisource? && sources.default_source
|
|
914
|
-
@dependencies.each do |dep|
|
|
915
|
-
next unless dep_source = dep.source || default
|
|
916
|
-
next if dep_source == skip
|
|
917
|
-
pinned_names << dep.name
|
|
918
|
-
end
|
|
919
|
-
pinned_names
|
|
920
|
-
end
|
|
921
|
-
|
|
922
793
|
def requested_groups
|
|
923
794
|
groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
|
|
924
795
|
end
|
|
@@ -936,12 +807,6 @@ module Bundler
|
|
|
936
807
|
current == proposed
|
|
937
808
|
end
|
|
938
809
|
|
|
939
|
-
def extract_gem_info(error)
|
|
940
|
-
# This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
|
|
941
|
-
# to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
|
|
942
|
-
error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
|
|
943
|
-
end
|
|
944
|
-
|
|
945
810
|
def compute_requires
|
|
946
811
|
dependencies.reduce({}) do |requires, dep|
|
|
947
812
|
next requires unless dep.should_include?
|
|
@@ -954,24 +819,16 @@ module Bundler
|
|
|
954
819
|
end
|
|
955
820
|
|
|
956
821
|
def additional_base_requirements_for_resolve
|
|
957
|
-
return [] unless @locked_gems &&
|
|
958
|
-
|
|
959
|
-
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
|
822
|
+
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
|
|
823
|
+
converge_specs(@locked_gems.specs).map do |locked_spec|
|
|
960
824
|
name = locked_spec.name
|
|
961
|
-
dependency = dependencies_by_name[name]
|
|
962
|
-
next requirements unless dependency
|
|
963
|
-
next requirements if @locked_gems.dependencies[name] != dependency
|
|
964
|
-
next requirements if dependency.source.is_a?(Source::Path)
|
|
965
825
|
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
end.values
|
|
826
|
+
DepProxy.get_proxy(dep, locked_spec.platform)
|
|
827
|
+
end
|
|
969
828
|
end
|
|
970
829
|
|
|
971
|
-
def
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
|
|
830
|
+
def source_map
|
|
831
|
+
@source_map ||= SourceMap.new(sources, dependencies)
|
|
975
832
|
end
|
|
976
833
|
end
|
|
977
834
|
end
|