bundler 2.2.24 → 2.3.7
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 +246 -1
- data/README.md +1 -1
- 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/config.rb +10 -1
- data/lib/bundler/cli/doctor.rb +13 -4
- data/lib/bundler/cli/exec.rb +1 -6
- data/lib/bundler/cli/gem.rb +101 -11
- data/lib/bundler/cli/info.rb +26 -5
- data/lib/bundler/cli/install.rb +12 -45
- data/lib/bundler/cli/issue.rb +4 -3
- data/lib/bundler/cli/list.rb +7 -1
- data/lib/bundler/cli/open.rb +1 -2
- data/lib/bundler/cli/platform.rb +1 -1
- data/lib/bundler/cli/remove.rb +1 -2
- data/lib/bundler/cli/update.rb +9 -5
- data/lib/bundler/cli.rb +24 -20
- data/lib/bundler/compact_index_client/cache.rb +0 -9
- data/lib/bundler/compact_index_client/updater.rb +0 -5
- data/lib/bundler/compact_index_client.rb +2 -8
- data/lib/bundler/definition.rb +97 -161
- data/lib/bundler/dependency.rb +5 -7
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +32 -31
- 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/fetcher/compact_index.rb +9 -14
- data/lib/bundler/fetcher/index.rb +0 -26
- data/lib/bundler/fetcher.rb +13 -20
- data/lib/bundler/friendly_errors.rb +5 -30
- data/lib/bundler/gem_helper.rb +7 -18
- data/lib/bundler/injector.rb +10 -1
- data/lib/bundler/installer/gem_installer.rb +4 -22
- data/lib/bundler/installer/standalone.rb +13 -8
- data/lib/bundler/installer.rb +1 -5
- data/lib/bundler/lazy_specification.rb +19 -3
- data/lib/bundler/lockfile_generator.rb +1 -1
- data/lib/bundler/lockfile_parser.rb +11 -12
- 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 +5 -5
- data/lib/bundler/man/bundle-config.1.ronn +5 -5
- 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 +2 -2
- data/lib/bundler/man/bundle-update.1.ronn +2 -1
- 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 +1 -0
- data/lib/bundler/plugin/installer.rb +3 -1
- data/lib/bundler/plugin.rb +23 -6
- data/lib/bundler/process_lock.rb +1 -1
- data/lib/bundler/remote_specification.rb +7 -0
- data/lib/bundler/resolver/spec_group.rb +1 -1
- data/lib/bundler/resolver.rb +38 -47
- data/lib/bundler/ruby_version.rb +1 -1
- data/lib/bundler/rubygems_ext.rb +19 -10
- data/lib/bundler/rubygems_gem_installer.rb +25 -5
- data/lib/bundler/rubygems_integration.rb +40 -70
- data/lib/bundler/runtime.rb +17 -8
- data/lib/bundler/self_manager.rb +168 -0
- data/lib/bundler/settings.rb +15 -2
- 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 -1
- data/lib/bundler/source/rubygems.rb +70 -81
- data/lib/bundler/source/rubygems_aggregate.rb +4 -0
- data/lib/bundler/source.rb +4 -0
- data/lib/bundler/source_list.rb +22 -31
- data/lib/bundler/spec_set.rb +14 -36
- 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/Rakefile.tt +15 -2
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +13 -2
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +17 -15
- 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/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 +6 -6
- 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/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 +23 -26
- metadata +25 -10
- data/lib/bundler/gemdeps.rb +0 -29
- data/lib/bundler/psyched_yaml.rb +0 -22
- 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,
|
@@ -73,7 +78,6 @@ module Bundler
|
|
73
78
|
@lockfile_contents = String.new
|
74
79
|
@locked_bundler_version = nil
|
75
80
|
@locked_ruby_version = nil
|
76
|
-
@locked_specs_incomplete_for_platform = false
|
77
81
|
@new_platform = nil
|
78
82
|
|
79
83
|
if lockfile && File.exist?(lockfile)
|
@@ -133,12 +137,14 @@ module Bundler
|
|
133
137
|
@unlock[:gems] ||= @dependencies.map(&:name)
|
134
138
|
else
|
135
139
|
eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
|
136
|
-
@unlock[:gems] = @locked_specs.for(eager_unlock, false, false
|
140
|
+
@unlock[:gems] = @locked_specs.for(eager_unlock, false, false).map(&:name)
|
137
141
|
end
|
138
142
|
|
139
143
|
@dependency_changes = converge_dependencies
|
140
144
|
@local_changes = converge_locals
|
141
145
|
|
146
|
+
@locked_specs_incomplete_for_platform = !@locked_specs.for(requested_dependencies & expand_dependencies(locked_dependencies), true, true)
|
147
|
+
|
142
148
|
@requires = compute_requires
|
143
149
|
end
|
144
150
|
|
@@ -157,10 +163,6 @@ module Bundler
|
|
157
163
|
end
|
158
164
|
end
|
159
165
|
|
160
|
-
def multisource_allowed?
|
161
|
-
@multisource_allowed
|
162
|
-
end
|
163
|
-
|
164
166
|
def resolve_only_locally!
|
165
167
|
@remote = false
|
166
168
|
sources.local_only!
|
@@ -185,15 +187,7 @@ module Bundler
|
|
185
187
|
#
|
186
188
|
# @return [Bundler::SpecSet]
|
187
189
|
def specs
|
188
|
-
@specs ||=
|
189
|
-
rescue GemNotFound => e # Handle yanked gem
|
190
|
-
gem_name, gem_version = extract_gem_info(e)
|
191
|
-
locked_gem = @locked_specs[gem_name].last
|
192
|
-
raise if locked_gem.nil? || locked_gem.version.to_s != gem_version || !@remote
|
193
|
-
raise GemNotFound, "Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
|
194
|
-
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
|
195
|
-
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
|
196
|
-
"removed in order to install."
|
190
|
+
@specs ||= materialize(requested_dependencies)
|
197
191
|
end
|
198
192
|
|
199
193
|
def new_specs
|
@@ -205,9 +199,7 @@ module Bundler
|
|
205
199
|
end
|
206
200
|
|
207
201
|
def missing_specs
|
208
|
-
|
209
|
-
resolve.materialize(requested_dependencies, missing)
|
210
|
-
missing
|
202
|
+
resolve.materialize(requested_dependencies).missing_specs
|
211
203
|
end
|
212
204
|
|
213
205
|
def missing_specs?
|
@@ -238,17 +230,22 @@ module Bundler
|
|
238
230
|
end
|
239
231
|
end
|
240
232
|
|
233
|
+
def locked_dependencies
|
234
|
+
@locked_deps.values
|
235
|
+
end
|
236
|
+
|
241
237
|
def specs_for(groups)
|
242
|
-
|
238
|
+
return specs if groups.empty?
|
243
239
|
deps = dependencies_for(groups)
|
244
|
-
|
240
|
+
materialize(deps)
|
245
241
|
end
|
246
242
|
|
247
243
|
def dependencies_for(groups)
|
248
244
|
groups.map!(&:to_sym)
|
249
|
-
current_dependencies.reject do |d|
|
245
|
+
deps = current_dependencies.reject do |d|
|
250
246
|
(d.groups & groups).empty?
|
251
247
|
end
|
248
|
+
expand_dependencies(deps)
|
252
249
|
end
|
253
250
|
|
254
251
|
# Resolve all the dependencies specified in Gemfile. It ensures that
|
@@ -268,16 +265,12 @@ module Bundler
|
|
268
265
|
else
|
269
266
|
# Run a resolve against the locally available gems
|
270
267
|
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
|
271
|
-
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies,
|
268
|
+
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, true)
|
272
269
|
Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
|
273
270
|
end
|
274
271
|
end
|
275
272
|
end
|
276
273
|
|
277
|
-
def has_rubygems_remotes?
|
278
|
-
sources.rubygems_sources.any? {|s| s.remotes.any? }
|
279
|
-
end
|
280
|
-
|
281
274
|
def spec_git_paths
|
282
275
|
sources.git_sources.map {|s| File.realpath(s.path) if File.exist?(s.path) }.compact
|
283
276
|
end
|
@@ -287,6 +280,8 @@ module Bundler
|
|
287
280
|
end
|
288
281
|
|
289
282
|
def lock(file, preserve_unknown_sections = false)
|
283
|
+
return if Definition.no_lock
|
284
|
+
|
290
285
|
contents = to_lock
|
291
286
|
|
292
287
|
# Convert to \r\n if the existing lock has them
|
@@ -297,10 +292,7 @@ module Bundler
|
|
297
292
|
locked_major = @locked_bundler_version.segments.first
|
298
293
|
current_major = Gem::Version.create(Bundler::VERSION).segments.first
|
299
294
|
|
300
|
-
|
301
|
-
Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
|
302
|
-
"after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
|
303
|
-
end
|
295
|
+
updating_major = locked_major < current_major
|
304
296
|
end
|
305
297
|
|
306
298
|
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
@@ -317,14 +309,6 @@ module Bundler
|
|
317
309
|
end
|
318
310
|
end
|
319
311
|
|
320
|
-
def locked_bundler_version
|
321
|
-
if @locked_bundler_version && @locked_bundler_version < Gem::Version.new(Bundler::VERSION)
|
322
|
-
new_version = Bundler::VERSION
|
323
|
-
end
|
324
|
-
|
325
|
-
new_version || @locked_bundler_version || Bundler::VERSION
|
326
|
-
end
|
327
|
-
|
328
312
|
def locked_ruby_version
|
329
313
|
return unless ruby_version
|
330
314
|
if @unlock[:ruby] || !@locked_ruby_version
|
@@ -376,44 +360,31 @@ module Bundler
|
|
376
360
|
added.concat new_platforms.map {|p| "* platform: #{p}" }
|
377
361
|
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
|
378
362
|
|
379
|
-
|
363
|
+
new_deps = @dependencies - locked_dependencies
|
364
|
+
deleted_deps = locked_dependencies - @dependencies
|
380
365
|
|
381
|
-
|
382
|
-
|
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?
|
383
368
|
|
384
|
-
|
385
|
-
|
369
|
+
both_sources = Hash.new {|h, k| h[k] = [] }
|
370
|
+
@dependencies.each {|d| both_sources[d.name][0] = d }
|
386
371
|
|
387
|
-
|
388
|
-
|
389
|
-
new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
390
|
-
deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
391
|
-
end
|
372
|
+
locked_dependencies.each do |d|
|
373
|
+
next if !Bundler.feature_flag.bundler_3_mode? && @locked_specs[d.name].empty?
|
392
374
|
|
393
|
-
|
394
|
-
if new_sources.any?
|
395
|
-
added.concat new_sources.map {|source| "* source: #{source}" }
|
396
|
-
end
|
397
|
-
|
398
|
-
if deleted_sources.any?
|
399
|
-
deleted.concat deleted_sources.map {|source| "* source: #{source}" }
|
400
|
-
end
|
375
|
+
both_sources[d.name][1] = d
|
401
376
|
end
|
402
377
|
|
403
|
-
|
404
|
-
|
405
|
-
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
|
406
|
-
end
|
378
|
+
both_sources.each do |name, (dep, lock_dep)|
|
379
|
+
next if dep.nil? || lock_dep.nil?
|
407
380
|
|
408
|
-
|
409
|
-
|
410
|
-
|
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)
|
411
384
|
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
lockfile_source_name = lock_source
|
416
|
-
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}`"
|
417
388
|
end
|
418
389
|
|
419
390
|
reason = change_reason
|
@@ -493,7 +464,23 @@ module Bundler
|
|
493
464
|
|
494
465
|
private
|
495
466
|
|
496
|
-
def
|
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
|
+
|
497
484
|
unless specs["bundler"].any?
|
498
485
|
bundler = sources.metadata_source.specs.search(Gem::Dependency.new("bundler", VERSION)).last
|
499
486
|
specs["bundler"] = bundler
|
@@ -503,11 +490,12 @@ module Bundler
|
|
503
490
|
end
|
504
491
|
|
505
492
|
def precompute_source_requirements_for_indirect_dependencies?
|
506
|
-
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
|
493
|
+
@remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
|
507
494
|
end
|
508
495
|
|
509
496
|
def current_ruby_platform_locked?
|
510
497
|
return false unless generic_local_platform == Gem::Platform::RUBY
|
498
|
+
return false if Bundler.settings[:force_ruby_platform] && !@platforms.include?(Gem::Platform::RUBY)
|
511
499
|
|
512
500
|
current_platform_locked?
|
513
501
|
end
|
@@ -558,7 +546,7 @@ module Bundler
|
|
558
546
|
|
559
547
|
def dependencies_for_source_changed?(source, locked_source = source)
|
560
548
|
deps_for_source = @dependencies.select {|s| s.source == source }
|
561
|
-
locked_deps_for_source =
|
549
|
+
locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
|
562
550
|
|
563
551
|
deps_for_source.uniq.sort != locked_deps_for_source.sort
|
564
552
|
end
|
@@ -641,25 +629,14 @@ module Bundler
|
|
641
629
|
end
|
642
630
|
|
643
631
|
def converge_dependencies
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
# after locked_source and sources don't match, we still use locked_source.
|
649
|
-
if frozen && !locked_source.nil? &&
|
650
|
-
locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
|
651
|
-
dep.source = locked_source.source
|
652
|
-
elsif dep.source
|
632
|
+
changes = false
|
633
|
+
|
634
|
+
@dependencies.each do |dep|
|
635
|
+
if dep.source
|
653
636
|
dep.source = sources.get(dep.source)
|
654
637
|
end
|
655
|
-
end
|
656
638
|
|
657
|
-
|
658
|
-
# We want to know if all match, but don't want to check all entries
|
659
|
-
# This means we need to return false if any dependency doesn't match
|
660
|
-
# the lock or doesn't exist in the lock.
|
661
|
-
@dependencies.each do |dependency|
|
662
|
-
unless locked_dep = @locked_deps[dependency.name]
|
639
|
+
unless locked_dep = @locked_deps[dep.name]
|
663
640
|
changes = true
|
664
641
|
next
|
665
642
|
end
|
@@ -670,11 +647,11 @@ module Bundler
|
|
670
647
|
# directive, the lockfile dependencies and resolved dependencies end up
|
671
648
|
# with a mismatch on #type. Work around that by setting the type on the
|
672
649
|
# dep from the lockfile.
|
673
|
-
locked_dep.instance_variable_set(:@type,
|
650
|
+
locked_dep.instance_variable_set(:@type, dep.type)
|
674
651
|
|
675
652
|
# We already know the name matches from the hash lookup
|
676
653
|
# so we only need to check the requirement now
|
677
|
-
changes ||=
|
654
|
+
changes ||= dep.requirement != locked_dep.requirement
|
678
655
|
end
|
679
656
|
|
680
657
|
changes
|
@@ -684,39 +661,36 @@ module Bundler
|
|
684
661
|
# commonly happen if the Gemfile has changed since the lockfile was last
|
685
662
|
# generated
|
686
663
|
def converge_locked_specs
|
687
|
-
|
688
|
-
|
689
|
-
# Build a list of dependencies that are the same in the Gemfile
|
690
|
-
# and Gemfile.lock. If the Gemfile modified a dependency, but
|
691
|
-
# the gem in the Gemfile.lock still satisfies it, this is fine
|
692
|
-
# too.
|
693
|
-
@dependencies.each do |dep|
|
694
|
-
locked_dep = @locked_deps[dep.name]
|
664
|
+
resolve = converge_specs(@locked_specs)
|
695
665
|
|
696
|
-
|
697
|
-
locked_dep = nil unless locked_dep == dep
|
666
|
+
diff = nil
|
698
667
|
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
@locked_specs.each do |s|
|
703
|
-
@unlock[:gems] << s.name if s.source == dep.source
|
704
|
-
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!)
|
705
671
|
|
706
|
-
|
707
|
-
|
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 }
|
708
675
|
end
|
709
676
|
end
|
710
677
|
|
678
|
+
resolve
|
679
|
+
end
|
680
|
+
|
681
|
+
def converge_specs(specs)
|
682
|
+
deps = []
|
711
683
|
converged = []
|
712
|
-
|
684
|
+
specs.each do |s|
|
713
685
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
714
686
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
715
|
-
s.source = (dep && dep.source) || sources.get(s.source)
|
716
687
|
|
717
|
-
|
718
|
-
|
719
|
-
|
688
|
+
if dep && (!dep.source || s.source.include?(dep.source))
|
689
|
+
deps << dep
|
690
|
+
end
|
691
|
+
|
692
|
+
s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source unless Bundler.frozen_bundle?
|
693
|
+
|
720
694
|
next if @unlock[:sources].include?(s.source.name)
|
721
695
|
|
722
696
|
# If the spec is from a path source and it doesn't exist anymore
|
@@ -729,8 +703,8 @@ module Bundler
|
|
729
703
|
rescue PathError, GitError
|
730
704
|
# if we won't need the source (according to the lockfile),
|
731
705
|
# don't error if the path/git source isn't available
|
732
|
-
next if
|
733
|
-
for(requested_dependencies, false, true
|
706
|
+
next if specs.
|
707
|
+
for(requested_dependencies, false, true).
|
734
708
|
none? {|locked_spec| locked_spec.source == s.source }
|
735
709
|
|
736
710
|
raise
|
@@ -745,36 +719,15 @@ module Bundler
|
|
745
719
|
s.dependencies.replace(new_spec.dependencies)
|
746
720
|
end
|
747
721
|
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
|
753
|
-
resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
|
754
|
-
diff = nil
|
755
|
-
|
756
|
-
# Now, we unlock any sources that do not have anymore gems pinned to it
|
757
|
-
sources.all_sources.each do |source|
|
758
|
-
next unless source.respond_to?(:unlock!)
|
759
|
-
|
760
|
-
unless resolve.any? {|s| s.source == source }
|
761
|
-
diff ||= @locked_specs.to_a - resolve.to_a
|
762
|
-
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
|
763
726
|
end
|
764
727
|
end
|
765
728
|
|
766
|
-
resolve
|
767
|
-
|
768
|
-
|
769
|
-
def in_locked_deps?(dep, locked_dep)
|
770
|
-
# Because the lockfile can't link a dep to a specific remote, we need to
|
771
|
-
# treat sources as equivalent anytime the locked dep has all the remotes
|
772
|
-
# that the Gemfile dep does.
|
773
|
-
locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
|
774
|
-
end
|
775
|
-
|
776
|
-
def satisfies_locked_spec?(dep)
|
777
|
-
@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) })
|
778
731
|
end
|
779
732
|
|
780
733
|
def metadata_dependencies
|
@@ -854,12 +807,6 @@ module Bundler
|
|
854
807
|
current == proposed
|
855
808
|
end
|
856
809
|
|
857
|
-
def extract_gem_info(error)
|
858
|
-
# This method will extract the error message like "Could not find foo-1.2.3 in any of the sources"
|
859
|
-
# to an array. The first element will be the gem name (e.g. foo), the second will be the version number.
|
860
|
-
error.message.scan(/Could not find (\w+)-(\d+(?:\.\d+)+)/).flatten
|
861
|
-
end
|
862
|
-
|
863
810
|
def compute_requires
|
864
811
|
dependencies.reduce({}) do |requires, dep|
|
865
812
|
next requires unless dep.should_include?
|
@@ -873,22 +820,11 @@ module Bundler
|
|
873
820
|
|
874
821
|
def additional_base_requirements_for_resolve
|
875
822
|
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
|
876
|
-
|
877
|
-
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
823
|
+
converge_specs(@locked_gems.specs).map do |locked_spec|
|
878
824
|
name = locked_spec.name
|
879
|
-
dependency = dependencies_by_name[name]
|
880
|
-
next requirements if @locked_gems.dependencies[name] != dependency
|
881
|
-
next requirements if dependency && dependency.source.is_a?(Source::Path)
|
882
825
|
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
883
|
-
|
884
|
-
|
885
|
-
end.values
|
886
|
-
end
|
887
|
-
|
888
|
-
def equivalent_rubygems_remotes?(source)
|
889
|
-
return false unless source.is_a?(Source::Rubygems)
|
890
|
-
|
891
|
-
Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
|
826
|
+
DepProxy.get_proxy(dep, locked_spec.platform)
|
827
|
+
end
|
892
828
|
end
|
893
829
|
|
894
830
|
def source_map
|
data/lib/bundler/dependency.rb
CHANGED
@@ -7,7 +7,7 @@ require_relative "rubygems_ext"
|
|
7
7
|
module Bundler
|
8
8
|
class Dependency < Gem::Dependency
|
9
9
|
attr_reader :autorequire
|
10
|
-
attr_reader :groups, :platforms, :gemfile, :git, :branch
|
10
|
+
attr_reader :groups, :platforms, :gemfile, :git, :github, :branch, :ref
|
11
11
|
|
12
12
|
PLATFORM_MAP = {
|
13
13
|
:ruby => Gem::Platform::RUBY,
|
@@ -82,7 +82,9 @@ module Bundler
|
|
82
82
|
@groups = Array(options["group"] || :default).map(&:to_sym)
|
83
83
|
@source = options["source"]
|
84
84
|
@git = options["git"]
|
85
|
+
@github = options["github"]
|
85
86
|
@branch = options["branch"]
|
87
|
+
@ref = options["ref"]
|
86
88
|
@platforms = Array(options["platforms"])
|
87
89
|
@env = options["env"]
|
88
90
|
@should_include = options.fetch("should_include", true)
|
@@ -96,15 +98,11 @@ module Bundler
|
|
96
98
|
def gem_platforms(valid_platforms)
|
97
99
|
return valid_platforms if @platforms.empty?
|
98
100
|
|
99
|
-
|
100
|
-
@gem_platforms ||= expanded_platforms.compact.uniq
|
101
|
-
|
102
|
-
filtered_generic_platforms = valid_generic_platforms.values & @gem_platforms
|
103
|
-
valid_generic_platforms.select {|_, v| filtered_generic_platforms.include?(v) }.keys
|
101
|
+
valid_platforms.select {|p| expanded_platforms.include?(GemHelpers.generic(p)) }
|
104
102
|
end
|
105
103
|
|
106
104
|
def expanded_platforms
|
107
|
-
@platforms.map {|pl| PLATFORM_MAP[pl] }
|
105
|
+
@expanded_platforms ||= @platforms.map {|pl| PLATFORM_MAP[pl] }.compact.uniq
|
108
106
|
end
|
109
107
|
|
110
108
|
def should_include?
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This code was extracted from https://github.com/Solistra/ruby-digest which is under public domain
|
4
|
+
module Bundler
|
5
|
+
module Digest
|
6
|
+
# The initial constant values for the 32-bit constant words A, B, C, D, and
|
7
|
+
# E, respectively.
|
8
|
+
SHA1_WORDS = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0].freeze
|
9
|
+
|
10
|
+
# The 8-bit field used for bitwise `AND` masking. Defaults to `0xFFFFFFFF`.
|
11
|
+
SHA1_MASK = 0xFFFFFFFF
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def sha1(string)
|
15
|
+
unless string.is_a?(String)
|
16
|
+
raise TypeError, "can't convert #{string.class.inspect} into String"
|
17
|
+
end
|
18
|
+
|
19
|
+
buffer = string.b
|
20
|
+
|
21
|
+
words = SHA1_WORDS.dup
|
22
|
+
generate_split_buffer(buffer) do |chunk|
|
23
|
+
w = []
|
24
|
+
chunk.each_slice(4) do |a, b, c, d|
|
25
|
+
w << (((a << 8 | b) << 8 | c) << 8 | d)
|
26
|
+
end
|
27
|
+
a, b, c, d, e = *words
|
28
|
+
(16..79).each do |i|
|
29
|
+
w[i] = SHA1_MASK & rotate((w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]), 1)
|
30
|
+
end
|
31
|
+
0.upto(79) do |i|
|
32
|
+
case i
|
33
|
+
when 0..19
|
34
|
+
f = ((b & c) | (~b & d))
|
35
|
+
k = 0x5A827999
|
36
|
+
when 20..39
|
37
|
+
f = (b ^ c ^ d)
|
38
|
+
k = 0x6ED9EBA1
|
39
|
+
when 40..59
|
40
|
+
f = ((b & c) | (b & d) | (c & d))
|
41
|
+
k = 0x8F1BBCDC
|
42
|
+
when 60..79
|
43
|
+
f = (b ^ c ^ d)
|
44
|
+
k = 0xCA62C1D6
|
45
|
+
end
|
46
|
+
t = SHA1_MASK & (SHA1_MASK & rotate(a, 5) + f + e + k + w[i])
|
47
|
+
a, b, c, d, e = t, a, SHA1_MASK & rotate(b, 30), c, d # rubocop:disable Style/ParallelAssignment
|
48
|
+
end
|
49
|
+
mutated = [a, b, c, d, e]
|
50
|
+
words.map!.with_index {|word, index| SHA1_MASK & (word + mutated[index]) }
|
51
|
+
end
|
52
|
+
|
53
|
+
words.pack("N*").unpack("H*").first
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def generate_split_buffer(string, &block)
|
59
|
+
size = string.bytesize * 8
|
60
|
+
buffer = string.bytes << 128
|
61
|
+
buffer << 0 while buffer.size % 64 != 56
|
62
|
+
buffer.concat([size].pack("Q>").bytes)
|
63
|
+
buffer.each_slice(64, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
def rotate(value, spaces)
|
67
|
+
value << spaces | value >> (32 - spaces)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/bundler/dsl.rb
CHANGED
@@ -18,6 +18,8 @@ module Bundler
|
|
18
18
|
VALID_KEYS = %w[group groups git path glob name branch ref tag require submodules
|
19
19
|
platform platforms type source install_if gemfile].freeze
|
20
20
|
|
21
|
+
GITHUB_PULL_REQUEST_URL = %r{\Ahttps://github\.com/([A-Za-z0-9_\-\.]+/[A-Za-z0-9_\-\.]+)/pull/(\d+)\z}.freeze
|
22
|
+
|
21
23
|
attr_reader :gemspecs
|
22
24
|
attr_accessor :dependencies
|
23
25
|
|
@@ -275,26 +277,24 @@ module Bundler
|
|
275
277
|
|
276
278
|
def add_git_sources
|
277
279
|
git_source(:github) do |repo_name|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
280
|
+
if repo_name =~ GITHUB_PULL_REQUEST_URL
|
281
|
+
{
|
282
|
+
"git" => "https://github.com/#{$1}.git",
|
283
|
+
"branch" => "refs/pull/#{$2}/head",
|
284
|
+
"ref" => nil,
|
285
|
+
"tag" => nil,
|
286
|
+
}
|
287
|
+
else
|
288
|
+
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
|
289
|
+
"https://github.com/#{repo_name}.git"
|
290
|
+
end
|
283
291
|
end
|
284
292
|
|
285
293
|
git_source(:gist) do |repo_name|
|
286
|
-
warn_deprecated_git_source(:gist, '"https://gist.github.com/#{repo_name}.git"')
|
287
|
-
|
288
294
|
"https://gist.github.com/#{repo_name}.git"
|
289
295
|
end
|
290
296
|
|
291
297
|
git_source(:bitbucket) do |repo_name|
|
292
|
-
warn_deprecated_git_source(:bitbucket, <<-'RUBY'.strip)
|
293
|
-
user_name, repo_name = repo_name.split("/")
|
294
|
-
repo_name ||= user_name
|
295
|
-
"https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
|
296
|
-
RUBY
|
297
|
-
|
298
298
|
user_name, repo_name = repo_name.split("/")
|
299
299
|
repo_name ||= user_name
|
300
300
|
"https://#{user_name}@bitbucket.org/#{user_name}/#{repo_name}.git"
|
@@ -365,7 +365,11 @@ repo_name ||= user_name
|
|
365
365
|
|
366
366
|
git_name = (git_names & opts.keys).last
|
367
367
|
if @git_sources[git_name]
|
368
|
-
|
368
|
+
git_opts = @git_sources[git_name].call(opts[git_name])
|
369
|
+
git_opts = { "git" => git_opts } if git_opts.is_a?(String)
|
370
|
+
opts.merge!(git_opts) do |key, _gemfile_value, _git_source_value|
|
371
|
+
raise GemfileError, %(The :#{key} option can't be used with `#{git_name}: #{opts[git_name].inspect}`)
|
372
|
+
end
|
369
373
|
end
|
370
374
|
|
371
375
|
%w[git path].each do |type|
|
@@ -447,8 +451,21 @@ repo_name ||= user_name
|
|
447
451
|
end
|
448
452
|
|
449
453
|
def check_rubygems_source_safety
|
450
|
-
|
454
|
+
if @sources.implicit_global_source?
|
455
|
+
implicit_global_source_warning
|
456
|
+
elsif @sources.aggregate_global_source?
|
457
|
+
multiple_global_source_warning
|
458
|
+
end
|
459
|
+
end
|
451
460
|
|
461
|
+
def implicit_global_source_warning
|
462
|
+
Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
|
463
|
+
"Not using an explicit global source may result in a different lockfile being generated depending on " \
|
464
|
+
"the gems you have installed locally before bundler is run. " \
|
465
|
+
"Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
|
466
|
+
end
|
467
|
+
|
468
|
+
def multiple_global_source_warning
|
452
469
|
if Bundler.feature_flag.bundler_3_mode?
|
453
470
|
msg = "This Gemfile contains multiple primary sources. " \
|
454
471
|
"Each source after the first must include a block to indicate which gems " \
|
@@ -462,22 +479,6 @@ repo_name ||= user_name
|
|
462
479
|
end
|
463
480
|
end
|
464
481
|
|
465
|
-
def warn_deprecated_git_source(name, replacement, additional_message = nil)
|
466
|
-
additional_message &&= " #{additional_message}"
|
467
|
-
replacement = if replacement.count("\n").zero?
|
468
|
-
"{|repo_name| #{replacement} }"
|
469
|
-
else
|
470
|
-
"do |repo_name|\n#{replacement.to_s.gsub(/^/, " ")}\n end"
|
471
|
-
end
|
472
|
-
|
473
|
-
Bundler::SharedHelpers.major_deprecation 3, <<-EOS
|
474
|
-
The :#{name} git source is deprecated, and will be removed in the future.#{additional_message} Add this code to the top of your Gemfile to ensure it continues to work:
|
475
|
-
|
476
|
-
git_source(:#{name}) #{replacement}
|
477
|
-
|
478
|
-
EOS
|
479
|
-
end
|
480
|
-
|
481
482
|
class DSLError < GemfileError
|
482
483
|
# @return [String] the description that should be presented to the user.
|
483
484
|
#
|