bundler 2.2.26 → 2.3.4
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 +166 -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/check.rb +1 -1
- data/lib/bundler/cli/doctor.rb +3 -2
- data/lib/bundler/cli/gem.rb +88 -9
- data/lib/bundler/cli/info.rb +16 -4
- data/lib/bundler/cli/install.rb +2 -3
- data/lib/bundler/cli/issue.rb +4 -3
- data/lib/bundler/cli/remove.rb +1 -2
- data/lib/bundler/cli/update.rb +2 -2
- data/lib/bundler/cli.rb +10 -1
- data/lib/bundler/compact_index_client/updater.rb +0 -5
- data/lib/bundler/compact_index_client.rb +2 -2
- data/lib/bundler/definition.rb +77 -124
- data/lib/bundler/dependency.rb +5 -7
- data/lib/bundler/digest.rb +71 -0
- data/lib/bundler/dsl.rb +18 -30
- data/lib/bundler/endpoint_specification.rb +0 -8
- data/lib/bundler/environment_preserver.rb +4 -1
- data/lib/bundler/errors.rb +18 -2
- data/lib/bundler/fetcher/compact_index.rb +9 -4
- data/lib/bundler/fetcher.rb +4 -6
- data/lib/bundler/friendly_errors.rb +5 -30
- data/lib/bundler/gem_helper.rb +6 -17
- data/lib/bundler/injector.rb +10 -1
- data/lib/bundler/installer/gem_installer.rb +1 -6
- data/lib/bundler/installer.rb +1 -5
- data/lib/bundler/lazy_specification.rb +17 -1
- data/lib/bundler/lockfile_parser.rb +10 -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/psyched_yaml.rb +1 -13
- data/lib/bundler/resolver.rb +34 -31
- data/lib/bundler/ruby_version.rb +1 -1
- data/lib/bundler/rubygems_ext.rb +6 -0
- data/lib/bundler/rubygems_gem_installer.rb +21 -5
- data/lib/bundler/rubygems_integration.rb +39 -57
- data/lib/bundler/runtime.rb +2 -2
- data/lib/bundler/self_manager.rb +94 -0
- data/lib/bundler/settings.rb +10 -1
- data/lib/bundler/shared_helpers.rb +4 -12
- data/lib/bundler/source/git/git_proxy.rb +7 -4
- data/lib/bundler/source/git.rb +22 -4
- data/lib/bundler/source/metadata.rb +1 -1
- data/lib/bundler/source/rubygems.rb +60 -85
- data/lib/bundler/source/rubygems_aggregate.rb +1 -1
- data/lib/bundler/source.rb +3 -1
- data/lib/bundler/source_list.rb +11 -29
- data/lib/bundler/spec_set.rb +2 -2
- data/lib/bundler/templates/Executable.bundler +1 -1
- 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 +4 -3
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +14 -14
- data/lib/bundler/templates/newgem/sig/newgem.rbs.tt +8 -0
- data/lib/bundler/templates/newgem/standard.yml.tt +2 -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 +5 -3
- 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/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 +2 -2
- data/lib/bundler.rb +22 -21
- metadata +25 -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,
|
|
@@ -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)
|
|
@@ -139,6 +143,8 @@ module Bundler
|
|
|
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,8 +163,10 @@ module Bundler
|
|
|
157
163
|
end
|
|
158
164
|
end
|
|
159
165
|
|
|
160
|
-
def
|
|
161
|
-
@
|
|
166
|
+
def resolve_only_locally!
|
|
167
|
+
@remote = false
|
|
168
|
+
sources.local_only!
|
|
169
|
+
resolve
|
|
162
170
|
end
|
|
163
171
|
|
|
164
172
|
def resolve_with_cache!
|
|
@@ -222,17 +230,22 @@ module Bundler
|
|
|
222
230
|
end
|
|
223
231
|
end
|
|
224
232
|
|
|
233
|
+
def locked_dependencies
|
|
234
|
+
@locked_deps.values
|
|
235
|
+
end
|
|
236
|
+
|
|
225
237
|
def specs_for(groups)
|
|
226
|
-
|
|
238
|
+
return specs if groups.empty?
|
|
227
239
|
deps = dependencies_for(groups)
|
|
228
|
-
materialize(
|
|
240
|
+
materialize(deps)
|
|
229
241
|
end
|
|
230
242
|
|
|
231
243
|
def dependencies_for(groups)
|
|
232
244
|
groups.map!(&:to_sym)
|
|
233
|
-
current_dependencies.reject do |d|
|
|
245
|
+
deps = current_dependencies.reject do |d|
|
|
234
246
|
(d.groups & groups).empty?
|
|
235
247
|
end
|
|
248
|
+
expand_dependencies(deps)
|
|
236
249
|
end
|
|
237
250
|
|
|
238
251
|
# Resolve all the dependencies specified in Gemfile. It ensures that
|
|
@@ -267,6 +280,8 @@ module Bundler
|
|
|
267
280
|
end
|
|
268
281
|
|
|
269
282
|
def lock(file, preserve_unknown_sections = false)
|
|
283
|
+
return if Definition.no_lock
|
|
284
|
+
|
|
270
285
|
contents = to_lock
|
|
271
286
|
|
|
272
287
|
# Convert to \r\n if the existing lock has them
|
|
@@ -277,10 +292,7 @@ module Bundler
|
|
|
277
292
|
locked_major = @locked_bundler_version.segments.first
|
|
278
293
|
current_major = Gem::Version.create(Bundler::VERSION).segments.first
|
|
279
294
|
|
|
280
|
-
|
|
281
|
-
Bundler.ui.warn "Warning: the lockfile is being updated to Bundler #{current_major}, " \
|
|
282
|
-
"after which you will be unable to return to Bundler #{@locked_bundler_version.segments.first}."
|
|
283
|
-
end
|
|
295
|
+
updating_major = locked_major < current_major
|
|
284
296
|
end
|
|
285
297
|
|
|
286
298
|
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
|
@@ -356,44 +368,31 @@ module Bundler
|
|
|
356
368
|
added.concat new_platforms.map {|p| "* platform: #{p}" }
|
|
357
369
|
deleted.concat deleted_platforms.map {|p| "* platform: #{p}" }
|
|
358
370
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
new_sources = gemfile_sources - @locked_sources
|
|
362
|
-
deleted_sources = @locked_sources - gemfile_sources
|
|
371
|
+
new_deps = @dependencies - locked_dependencies
|
|
372
|
+
deleted_deps = locked_dependencies - @dependencies
|
|
363
373
|
|
|
364
|
-
new_deps
|
|
365
|
-
deleted_deps
|
|
374
|
+
added.concat new_deps.map {|d| "* #{pretty_dep(d)}" } if new_deps.any?
|
|
375
|
+
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" } if deleted_deps.any?
|
|
366
376
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
new_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
|
370
|
-
deleted_sources.reject! {|source| (source.path? && source.path.exist?) || equivalent_rubygems_remotes?(source) }
|
|
371
|
-
end
|
|
377
|
+
both_sources = Hash.new {|h, k| h[k] = [] }
|
|
378
|
+
@dependencies.each {|d| both_sources[d.name][0] = d }
|
|
372
379
|
|
|
373
|
-
|
|
374
|
-
if
|
|
375
|
-
added.concat new_sources.map {|source| "* source: #{source}" }
|
|
376
|
-
end
|
|
380
|
+
locked_dependencies.each do |d|
|
|
381
|
+
next if !Bundler.feature_flag.bundler_3_mode? && @locked_specs[d.name].empty?
|
|
377
382
|
|
|
378
|
-
|
|
379
|
-
deleted.concat deleted_sources.map {|source| "* source: #{source}" }
|
|
380
|
-
end
|
|
383
|
+
both_sources[d.name][1] = d
|
|
381
384
|
end
|
|
382
385
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
deleted.concat deleted_deps.map {|d| "* #{pretty_dep(d)}" }
|
|
386
|
-
end
|
|
386
|
+
both_sources.each do |name, (dep, lock_dep)|
|
|
387
|
+
next if dep.nil? || lock_dep.nil?
|
|
387
388
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
389
|
+
gemfile_source = dep.source || sources.default_source
|
|
390
|
+
lock_source = lock_dep.source || sources.default_source
|
|
391
|
+
next if lock_source.include?(gemfile_source)
|
|
391
392
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
lockfile_source_name = lock_source
|
|
396
|
-
changed << "* #{name} from `#{gemfile_source_name}` to `#{lockfile_source_name}`"
|
|
393
|
+
gemfile_source_name = dep.source ? gemfile_source.identifier : "no specified source"
|
|
394
|
+
lockfile_source_name = lock_dep.source ? lock_source.identifier : "no specified source"
|
|
395
|
+
changed << "* #{name} from `#{lockfile_source_name}` to `#{gemfile_source_name}`"
|
|
397
396
|
end
|
|
398
397
|
|
|
399
398
|
reason = change_reason
|
|
@@ -554,7 +553,7 @@ module Bundler
|
|
|
554
553
|
|
|
555
554
|
def dependencies_for_source_changed?(source, locked_source = source)
|
|
556
555
|
deps_for_source = @dependencies.select {|s| s.source == source }
|
|
557
|
-
locked_deps_for_source =
|
|
556
|
+
locked_deps_for_source = locked_dependencies.select {|dep| dep.source == locked_source }
|
|
558
557
|
|
|
559
558
|
deps_for_source.uniq.sort != locked_deps_for_source.sort
|
|
560
559
|
end
|
|
@@ -637,25 +636,14 @@ module Bundler
|
|
|
637
636
|
end
|
|
638
637
|
|
|
639
638
|
def converge_dependencies
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
# after locked_source and sources don't match, we still use locked_source.
|
|
645
|
-
if frozen && !locked_source.nil? &&
|
|
646
|
-
locked_source.respond_to?(:source) && locked_source.source.instance_of?(Source::Path) && locked_source.source.path.exist?
|
|
647
|
-
dep.source = locked_source.source
|
|
648
|
-
elsif dep.source
|
|
639
|
+
changes = false
|
|
640
|
+
|
|
641
|
+
@dependencies.each do |dep|
|
|
642
|
+
if dep.source
|
|
649
643
|
dep.source = sources.get(dep.source)
|
|
650
644
|
end
|
|
651
|
-
end
|
|
652
645
|
|
|
653
|
-
|
|
654
|
-
# We want to know if all match, but don't want to check all entries
|
|
655
|
-
# This means we need to return false if any dependency doesn't match
|
|
656
|
-
# the lock or doesn't exist in the lock.
|
|
657
|
-
@dependencies.each do |dependency|
|
|
658
|
-
unless locked_dep = @locked_deps[dependency.name]
|
|
646
|
+
unless locked_dep = @locked_deps[dep.name]
|
|
659
647
|
changes = true
|
|
660
648
|
next
|
|
661
649
|
end
|
|
@@ -666,11 +654,11 @@ module Bundler
|
|
|
666
654
|
# directive, the lockfile dependencies and resolved dependencies end up
|
|
667
655
|
# with a mismatch on #type. Work around that by setting the type on the
|
|
668
656
|
# dep from the lockfile.
|
|
669
|
-
locked_dep.instance_variable_set(:@type,
|
|
657
|
+
locked_dep.instance_variable_set(:@type, dep.type)
|
|
670
658
|
|
|
671
659
|
# We already know the name matches from the hash lookup
|
|
672
660
|
# so we only need to check the requirement now
|
|
673
|
-
changes ||=
|
|
661
|
+
changes ||= dep.requirement != locked_dep.requirement
|
|
674
662
|
end
|
|
675
663
|
|
|
676
664
|
changes
|
|
@@ -680,39 +668,36 @@ module Bundler
|
|
|
680
668
|
# commonly happen if the Gemfile has changed since the lockfile was last
|
|
681
669
|
# generated
|
|
682
670
|
def converge_locked_specs
|
|
683
|
-
|
|
671
|
+
resolve = converge_specs(@locked_specs)
|
|
684
672
|
|
|
685
|
-
|
|
686
|
-
# and Gemfile.lock. If the Gemfile modified a dependency, but
|
|
687
|
-
# the gem in the Gemfile.lock still satisfies it, this is fine
|
|
688
|
-
# too.
|
|
689
|
-
@dependencies.each do |dep|
|
|
690
|
-
locked_dep = @locked_deps[dep.name]
|
|
691
|
-
|
|
692
|
-
# If the locked_dep doesn't match the dependency we're looking for then we ignore the locked_dep
|
|
693
|
-
locked_dep = nil unless locked_dep == dep
|
|
673
|
+
diff = nil
|
|
694
674
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
@locked_specs.each do |s|
|
|
699
|
-
@unlock[:gems] << s.name if s.source == dep.source
|
|
700
|
-
end
|
|
675
|
+
# Now, we unlock any sources that do not have anymore gems pinned to it
|
|
676
|
+
sources.all_sources.each do |source|
|
|
677
|
+
next unless source.respond_to?(:unlock!)
|
|
701
678
|
|
|
702
|
-
|
|
703
|
-
|
|
679
|
+
unless resolve.any? {|s| s.source == source }
|
|
680
|
+
diff ||= @locked_specs.to_a - resolve.to_a
|
|
681
|
+
source.unlock! if diff.any? {|s| s.source == source }
|
|
704
682
|
end
|
|
705
683
|
end
|
|
706
684
|
|
|
685
|
+
resolve
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
def converge_specs(specs)
|
|
689
|
+
deps = []
|
|
707
690
|
converged = []
|
|
708
|
-
|
|
691
|
+
specs.each do |s|
|
|
709
692
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
|
710
693
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
|
711
|
-
s.source = (dep && dep.source) || sources.get(s.source) unless multisource_allowed?
|
|
712
694
|
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
695
|
+
if dep && (!dep.source || s.source.include?(dep.source))
|
|
696
|
+
deps << dep
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
s.source = (dep && dep.source) || sources.get(s.source) || sources.default_source unless Bundler.frozen_bundle?
|
|
700
|
+
|
|
716
701
|
next if @unlock[:sources].include?(s.source.name)
|
|
717
702
|
|
|
718
703
|
# If the spec is from a path source and it doesn't exist anymore
|
|
@@ -725,7 +710,7 @@ module Bundler
|
|
|
725
710
|
rescue PathError, GitError
|
|
726
711
|
# if we won't need the source (according to the lockfile),
|
|
727
712
|
# don't error if the path/git source isn't available
|
|
728
|
-
next if
|
|
713
|
+
next if specs.
|
|
729
714
|
for(requested_dependencies, false, true).
|
|
730
715
|
none? {|locked_spec| locked_spec.source == s.source }
|
|
731
716
|
|
|
@@ -741,36 +726,15 @@ module Bundler
|
|
|
741
726
|
s.dependencies.replace(new_spec.dependencies)
|
|
742
727
|
end
|
|
743
728
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), true, true)
|
|
749
|
-
resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
|
|
750
|
-
diff = nil
|
|
751
|
-
|
|
752
|
-
# Now, we unlock any sources that do not have anymore gems pinned to it
|
|
753
|
-
sources.all_sources.each do |source|
|
|
754
|
-
next unless source.respond_to?(:unlock!)
|
|
755
|
-
|
|
756
|
-
unless resolve.any? {|s| s.source == source }
|
|
757
|
-
diff ||= @locked_specs.to_a - resolve.to_a
|
|
758
|
-
source.unlock! if diff.any? {|s| s.source == source }
|
|
729
|
+
if dep.nil? && requested_dependencies.find {|d| s.name == d.name }
|
|
730
|
+
@unlock[:gems] << s.name
|
|
731
|
+
else
|
|
732
|
+
converged << s
|
|
759
733
|
end
|
|
760
734
|
end
|
|
761
735
|
|
|
762
|
-
resolve
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
def in_locked_deps?(dep, locked_dep)
|
|
766
|
-
# Because the lockfile can't link a dep to a specific remote, we need to
|
|
767
|
-
# treat sources as equivalent anytime the locked dep has all the remotes
|
|
768
|
-
# that the Gemfile dep does.
|
|
769
|
-
locked_dep && locked_dep.source && dep.source && locked_dep.source.include?(dep.source)
|
|
770
|
-
end
|
|
771
|
-
|
|
772
|
-
def satisfies_locked_spec?(dep)
|
|
773
|
-
@locked_specs[dep].any? {|s| s.satisfies?(dep) && (!dep.source || s.source.include?(dep.source)) }
|
|
736
|
+
resolve = SpecSet.new(converged)
|
|
737
|
+
SpecSet.new(resolve.for(expand_dependencies(deps, true), false, false).reject{|s| @unlock[:gems].include?(s.name) })
|
|
774
738
|
end
|
|
775
739
|
|
|
776
740
|
def metadata_dependencies
|
|
@@ -863,22 +827,11 @@ module Bundler
|
|
|
863
827
|
|
|
864
828
|
def additional_base_requirements_for_resolve
|
|
865
829
|
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
|
|
866
|
-
|
|
867
|
-
@locked_gems.specs.reduce({}) do |requirements, locked_spec|
|
|
830
|
+
converge_specs(@locked_gems.specs).map do |locked_spec|
|
|
868
831
|
name = locked_spec.name
|
|
869
|
-
dependency = dependencies_by_name[name]
|
|
870
|
-
next requirements if @locked_gems.dependencies[name] != dependency
|
|
871
|
-
next requirements if dependency && dependency.source.is_a?(Source::Path)
|
|
872
832
|
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
end.values
|
|
876
|
-
end
|
|
877
|
-
|
|
878
|
-
def equivalent_rubygems_remotes?(source)
|
|
879
|
-
return false unless source.is_a?(Source::Rubygems)
|
|
880
|
-
|
|
881
|
-
Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
|
|
833
|
+
DepProxy.get_proxy(dep, locked_spec.platform)
|
|
834
|
+
end
|
|
882
835
|
end
|
|
883
836
|
|
|
884
837
|
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|
|
|
@@ -475,22 +479,6 @@ repo_name ||= user_name
|
|
|
475
479
|
end
|
|
476
480
|
end
|
|
477
481
|
|
|
478
|
-
def warn_deprecated_git_source(name, replacement, additional_message = nil)
|
|
479
|
-
additional_message &&= " #{additional_message}"
|
|
480
|
-
replacement = if replacement.count("\n").zero?
|
|
481
|
-
"{|repo_name| #{replacement} }"
|
|
482
|
-
else
|
|
483
|
-
"do |repo_name|\n#{replacement.to_s.gsub(/^/, " ")}\n end"
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
Bundler::SharedHelpers.major_deprecation 3, <<-EOS
|
|
487
|
-
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:
|
|
488
|
-
|
|
489
|
-
git_source(:#{name}) #{replacement}
|
|
490
|
-
|
|
491
|
-
EOS
|
|
492
|
-
end
|
|
493
|
-
|
|
494
482
|
class DSLError < GemfileError
|
|
495
483
|
# @return [String] the description that should be presented to the user.
|
|
496
484
|
#
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
module Bundler
|
|
4
4
|
# used for Creating Specifications from the Gemcutter Endpoint
|
|
5
5
|
class EndpointSpecification < Gem::Specification
|
|
6
|
-
ILLFORMED_MESSAGE = 'Ill-formed requirement ["#<YAML::Syck::DefaultKey'.freeze
|
|
7
6
|
include MatchPlatform
|
|
8
7
|
|
|
9
8
|
attr_reader :name, :version, :platform, :required_rubygems_version, :required_ruby_version, :checksum
|
|
@@ -129,13 +128,6 @@ module Bundler
|
|
|
129
128
|
|
|
130
129
|
def build_dependency(name, requirements)
|
|
131
130
|
Gem::Dependency.new(name, requirements)
|
|
132
|
-
rescue ArgumentError => e
|
|
133
|
-
raise unless e.message.include?(ILLFORMED_MESSAGE)
|
|
134
|
-
puts # we shouldn't print the error message on the "fetching info" status line
|
|
135
|
-
raise GemspecError,
|
|
136
|
-
"Unfortunately, the gem #{name} (#{version}) has an invalid " \
|
|
137
|
-
"gemspec.\nPlease ask the gem author to yank the bad version to fix " \
|
|
138
|
-
"this issue. For more information, see http://bit.ly/syck-defaultkey."
|
|
139
131
|
end
|
|
140
132
|
end
|
|
141
133
|
end
|
|
@@ -38,7 +38,10 @@ module Bundler
|
|
|
38
38
|
|
|
39
39
|
# Replaces `ENV` with the bundler environment variables backed up
|
|
40
40
|
def replace_with_backup
|
|
41
|
-
|
|
41
|
+
unless Gem.win_platform?
|
|
42
|
+
ENV.replace(backup)
|
|
43
|
+
return
|
|
44
|
+
end
|
|
42
45
|
|
|
43
46
|
# Fallback logic for Windows below to workaround
|
|
44
47
|
# https://bugs.ruby-lang.org/issues/16798. Can be dropped once all
|
data/lib/bundler/errors.rb
CHANGED
|
@@ -75,10 +75,26 @@ module Bundler
|
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
+
def permission_type
|
|
79
|
+
case @permission_type
|
|
80
|
+
when :create
|
|
81
|
+
"executable permissions for all parent directories and write permissions for `#{parent_folder}`"
|
|
82
|
+
when :delete
|
|
83
|
+
permissions = "executable permissions for all parent directories and write permissions for `#{parent_folder}`"
|
|
84
|
+
permissions += ", and the same thing for all subdirectories inside #{@path}" if File.directory?(@path)
|
|
85
|
+
permissions
|
|
86
|
+
else
|
|
87
|
+
"#{@permission_type} permissions for that path"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def parent_folder
|
|
92
|
+
File.dirname(@path)
|
|
93
|
+
end
|
|
94
|
+
|
|
78
95
|
def message
|
|
79
96
|
"There was an error while trying to #{action} `#{@path}`. " \
|
|
80
|
-
"It is likely that you need to grant #{
|
|
81
|
-
"for that path."
|
|
97
|
+
"It is likely that you need to grant #{permission_type}."
|
|
82
98
|
end
|
|
83
99
|
|
|
84
100
|
status_code(23)
|
|
@@ -68,11 +68,16 @@ module Bundler
|
|
|
68
68
|
compact_index_request :fetch_spec
|
|
69
69
|
|
|
70
70
|
def available?
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
unless SharedHelpers.md5_available?
|
|
72
|
+
Bundler.ui.debug("FIPS mode is enabled, bundler can't use the CompactIndex API")
|
|
73
|
+
return nil
|
|
74
|
+
end
|
|
75
|
+
if fetch_uri.scheme == "file"
|
|
76
|
+
Bundler.ui.debug("Using a local server, bundler won't use the CompactIndex API")
|
|
77
|
+
return false
|
|
78
|
+
end
|
|
74
79
|
# Read info file checksums out of /versions, so we can know if gems are up to date
|
|
75
|
-
|
|
80
|
+
compact_index_client.update_and_parse_checksums!
|
|
76
81
|
rescue CompactIndexClient::Updater::MisMatchedChecksumError => e
|
|
77
82
|
Bundler.ui.debug(e.message)
|
|
78
83
|
nil
|
data/lib/bundler/fetcher.rb
CHANGED
|
@@ -28,7 +28,8 @@ module Bundler
|
|
|
28
28
|
" is a chance you are experiencing a man-in-the-middle attack, but" \
|
|
29
29
|
" most likely your system doesn't have the CA certificates needed" \
|
|
30
30
|
" for verification. For information about OpenSSL certificates, see" \
|
|
31
|
-
"
|
|
31
|
+
" https://railsapps.github.io/openssl-certificate-verify-failed.html." \
|
|
32
|
+
" To connect without using SSL, edit your Gemfile" \
|
|
32
33
|
" sources and change 'https' to 'http'."
|
|
33
34
|
end
|
|
34
35
|
end
|
|
@@ -70,8 +71,8 @@ module Bundler
|
|
|
70
71
|
:HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze
|
|
71
72
|
FAIL_ERRORS = begin
|
|
72
73
|
fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError]
|
|
73
|
-
fail_errors << Gem::Requirement::BadRequirementError
|
|
74
|
-
fail_errors.concat(NET_ERRORS.map {|e|
|
|
74
|
+
fail_errors << Gem::Requirement::BadRequirementError
|
|
75
|
+
fail_errors.concat(NET_ERRORS.map {|e| Net.const_get(e) })
|
|
75
76
|
end.freeze
|
|
76
77
|
|
|
77
78
|
class << self
|
|
@@ -121,7 +122,6 @@ module Bundler
|
|
|
121
122
|
|
|
122
123
|
# return the specs in the bundler format as an index
|
|
123
124
|
def specs(gem_names, source)
|
|
124
|
-
old = Bundler.rubygems.sources
|
|
125
125
|
index = Bundler::Index.new
|
|
126
126
|
|
|
127
127
|
if Bundler::Fetcher.disable_endpoint
|
|
@@ -152,8 +152,6 @@ module Bundler
|
|
|
152
152
|
rescue CertificateFailureError
|
|
153
153
|
Bundler.ui.info "" if gem_names && use_api # newline after dots
|
|
154
154
|
raise
|
|
155
|
-
ensure
|
|
156
|
-
Bundler.rubygems.sources = old
|
|
157
155
|
end
|
|
158
156
|
|
|
159
157
|
def use_api
|