bundler 2.5.23 → 2.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -0
- data/bundler.gemspec +2 -2
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/cli/console.rb +0 -4
- data/lib/bundler/cli/doctor.rb +4 -4
- data/lib/bundler/cli/exec.rb +1 -0
- data/lib/bundler/cli/gem.rb +1 -1
- data/lib/bundler/cli/info.rb +2 -2
- data/lib/bundler/cli/inject.rb +1 -1
- data/lib/bundler/cli/install.rb +4 -0
- data/lib/bundler/cli/lock.rb +20 -1
- data/lib/bundler/cli/pristine.rb +1 -1
- data/lib/bundler/cli/show.rb +2 -2
- data/lib/bundler/cli.rb +22 -53
- data/lib/bundler/compact_index_client/cache_file.rb +0 -5
- data/lib/bundler/compact_index_client/updater.rb +0 -11
- data/lib/bundler/definition.rb +155 -74
- data/lib/bundler/dependency.rb +1 -1
- data/lib/bundler/dsl.rb +2 -13
- data/lib/bundler/endpoint_specification.rb +10 -1
- data/lib/bundler/errors.rb +10 -0
- data/lib/bundler/feature_flag.rb +1 -0
- data/lib/bundler/fetcher/compact_index.rb +1 -1
- data/lib/bundler/fetcher.rb +10 -3
- data/lib/bundler/gem_helpers.rb +21 -5
- data/lib/bundler/injector.rb +2 -2
- data/lib/bundler/installer/standalone.rb +2 -2
- data/lib/bundler/installer.rb +4 -38
- data/lib/bundler/lazy_specification.rb +65 -24
- data/lib/bundler/lockfile_parser.rb +9 -1
- data/lib/bundler/man/bundle-add.1 +13 -10
- data/lib/bundler/man/bundle-add.1.ronn +12 -9
- data/lib/bundler/man/bundle-binstubs.1 +7 -4
- data/lib/bundler/man/bundle-binstubs.1.ronn +6 -3
- data/lib/bundler/man/bundle-cache.1 +30 -2
- data/lib/bundler/man/bundle-cache.1.ronn +31 -2
- data/lib/bundler/man/bundle-check.1 +3 -3
- data/lib/bundler/man/bundle-check.1.ronn +4 -2
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +3 -1
- data/lib/bundler/man/bundle-config.1.ronn +2 -0
- data/lib/bundler/man/bundle-console.1 +2 -4
- data/lib/bundler/man/bundle-console.1.ronn +2 -7
- data/lib/bundler/man/bundle-doctor.1 +2 -2
- data/lib/bundler/man/bundle-doctor.1.ronn +1 -1
- data/lib/bundler/man/bundle-env.1 +9 -0
- data/lib/bundler/man/bundle-env.1.ronn +10 -0
- data/lib/bundler/man/bundle-exec.1 +5 -2
- data/lib/bundler/man/bundle-exec.1.ronn +4 -1
- data/lib/bundler/man/bundle-fund.1 +22 -0
- data/lib/bundler/man/bundle-fund.1.ronn +25 -0
- data/lib/bundler/man/bundle-gem.1 +17 -5
- data/lib/bundler/man/bundle-gem.1.ronn +27 -6
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +5 -2
- data/lib/bundler/man/bundle-info.1.ronn +6 -2
- data/lib/bundler/man/bundle-init.1 +3 -3
- data/lib/bundler/man/bundle-init.1.ronn +3 -2
- data/lib/bundler/man/bundle-inject.1 +10 -2
- data/lib/bundler/man/bundle-inject.1.ronn +9 -1
- data/lib/bundler/man/bundle-install.1 +14 -11
- data/lib/bundler/man/bundle-install.1.ronn +21 -16
- data/lib/bundler/man/bundle-issue.1 +45 -0
- data/lib/bundler/man/bundle-issue.1.ronn +37 -0
- data/lib/bundler/man/bundle-licenses.1 +9 -0
- data/lib/bundler/man/bundle-licenses.1.ronn +10 -0
- data/lib/bundler/man/bundle-list.1 +1 -1
- data/lib/bundler/man/bundle-list.1.ronn +4 -1
- data/lib/bundler/man/bundle-lock.1 +21 -6
- data/lib/bundler/man/bundle-lock.1.ronn +25 -4
- data/lib/bundler/man/bundle-open.1 +2 -2
- data/lib/bundler/man/bundle-open.1.ronn +2 -1
- data/lib/bundler/man/bundle-outdated.1 +8 -5
- data/lib/bundler/man/bundle-outdated.1.ronn +8 -4
- data/lib/bundler/man/bundle-platform.1 +1 -1
- data/lib/bundler/man/bundle-plugin.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-pristine.1.ronn +1 -1
- data/lib/bundler/man/bundle-remove.1 +1 -1
- data/lib/bundler/man/bundle-remove.1.ronn +1 -1
- data/lib/bundler/man/bundle-show.1 +5 -2
- data/lib/bundler/man/bundle-show.1.ronn +4 -0
- data/lib/bundler/man/bundle-update.1 +13 -7
- data/lib/bundler/man/bundle-update.1.ronn +14 -6
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle-viz.1 +4 -4
- data/lib/bundler/man/bundle-viz.1.ronn +7 -3
- data/lib/bundler/man/bundle.1 +1 -1
- data/lib/bundler/man/gemfile.5 +1 -1
- data/lib/bundler/man/index.txt +4 -0
- data/lib/bundler/materialization.rb +59 -0
- data/lib/bundler/plugin/events.rb +24 -0
- data/lib/bundler/plugin/installer.rb +1 -1
- data/lib/bundler/process_lock.rb +1 -1
- data/lib/bundler/remote_specification.rb +6 -1
- data/lib/bundler/resolver/base.rb +2 -6
- data/lib/bundler/resolver/candidate.rb +2 -2
- data/lib/bundler/resolver/spec_group.rb +4 -3
- data/lib/bundler/resolver.rb +5 -5
- data/lib/bundler/rubygems_ext.rb +28 -28
- data/lib/bundler/rubygems_gem_installer.rb +0 -1
- data/lib/bundler/rubygems_integration.rb +21 -11
- data/lib/bundler/runtime.rb +27 -7
- data/lib/bundler/self_manager.rb +2 -3
- data/lib/bundler/settings.rb +1 -0
- data/lib/bundler/shared_helpers.rb +2 -2
- data/lib/bundler/source/git/git_proxy.rb +0 -6
- data/lib/bundler/source/git.rb +56 -31
- data/lib/bundler/source/path.rb +2 -2
- data/lib/bundler/source_list.rb +1 -1
- data/lib/bundler/spec_set.rb +81 -56
- data/lib/bundler/stub_specification.rb +8 -0
- data/lib/bundler/templates/newgem/README.md.tt +1 -1
- data/lib/bundler/uri_credentials_filter.rb +1 -1
- data/lib/bundler/vendor/fileutils/COPYING +56 -0
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +15 -13
- data/lib/bundler/vendor/securerandom/COPYING +56 -0
- data/lib/bundler/vendor/securerandom/lib/securerandom.rb +11 -5
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +3 -5
- data/lib/bundler/vendor/thor/lib/thor/group.rb +11 -0
- data/lib/bundler/vendor/thor/lib/thor/parser/argument.rb +1 -4
- data/lib/bundler/vendor/thor/lib/thor/parser/option.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +2 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +9 -9
- data/lib/bundler/vendor/thor/lib/thor/shell/html.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/shell/table_printer.rb +5 -21
- 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/thor/lib/thor.rb +11 -0
- data/lib/bundler/vendor/uri/COPYING +56 -0
- data/lib/bundler/vendor/uri/lib/uri/common.rb +37 -16
- data/lib/bundler/vendor/uri/lib/uri/file.rb +3 -3
- data/lib/bundler/vendor/uri/lib/uri/ftp.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +16 -26
- data/lib/bundler/vendor/uri/lib/uri/http.rb +2 -2
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +10 -3
- data/lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb +26 -3
- data/lib/bundler/vendor/uri/lib/uri/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri.rb +9 -9
- data/lib/bundler/vendored_securerandom.rb +0 -2
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler.rb +37 -13
- metadata +18 -12
- data/lib/bundler/vendor/fileutils/LICENSE.txt +0 -22
- data/lib/bundler/vendor/securerandom/LICENSE.txt +0 -22
- data/lib/bundler/vendor/securerandom/lib/random/formatter.rb +0 -373
- data/lib/bundler/vendor/uri/LICENSE.txt +0 -22
data/lib/bundler/definition.rb
CHANGED
@@ -13,13 +13,13 @@ module Bundler
|
|
13
13
|
|
14
14
|
attr_reader(
|
15
15
|
:dependencies,
|
16
|
+
:locked_checksums,
|
16
17
|
:locked_deps,
|
17
18
|
:locked_gems,
|
18
19
|
:platforms,
|
19
20
|
:ruby_version,
|
20
21
|
:lockfile,
|
21
22
|
:gemfiles,
|
22
|
-
:locked_checksums,
|
23
23
|
:sources
|
24
24
|
)
|
25
25
|
|
@@ -89,6 +89,7 @@ module Bundler
|
|
89
89
|
@lockfile_contents = Bundler.read_file(lockfile)
|
90
90
|
@locked_gems = LockfileParser.new(@lockfile_contents)
|
91
91
|
@locked_platforms = @locked_gems.platforms
|
92
|
+
@most_specific_locked_platform = @locked_gems.most_specific_locked_platform
|
92
93
|
@platforms = @locked_platforms.dup
|
93
94
|
@locked_bundler_version = @locked_gems.bundler_version
|
94
95
|
@locked_ruby_version = @locked_gems.ruby_version
|
@@ -108,15 +109,16 @@ module Bundler
|
|
108
109
|
end
|
109
110
|
else
|
110
111
|
@unlock = {}
|
111
|
-
@platforms = []
|
112
112
|
@locked_gems = nil
|
113
|
+
@locked_platforms = []
|
114
|
+
@most_specific_locked_platform = nil
|
115
|
+
@platforms = []
|
113
116
|
@locked_deps = {}
|
114
117
|
@locked_specs = SpecSet.new([])
|
115
118
|
@originally_locked_deps = {}
|
116
119
|
@originally_locked_specs = @locked_specs
|
117
120
|
@locked_sources = []
|
118
|
-
@
|
119
|
-
@locked_checksums = Bundler.feature_flag.bundler_3_mode?
|
121
|
+
@locked_checksums = Bundler.feature_flag.lockfile_checksums?
|
120
122
|
end
|
121
123
|
|
122
124
|
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
@@ -150,7 +152,7 @@ module Bundler
|
|
150
152
|
@gems_to_unlock = @explicit_unlocks.any? ? @explicit_unlocks : @dependencies.map(&:name)
|
151
153
|
else
|
152
154
|
eager_unlock = @explicit_unlocks.map {|name| Dependency.new(name, ">= 0") }
|
153
|
-
@gems_to_unlock = @locked_specs.for(eager_unlock,
|
155
|
+
@gems_to_unlock = @locked_specs.for(eager_unlock, platforms).map(&:name).uniq
|
154
156
|
end
|
155
157
|
|
156
158
|
@dependency_changes = converge_dependencies
|
@@ -175,16 +177,45 @@ module Bundler
|
|
175
177
|
resolve
|
176
178
|
end
|
177
179
|
|
180
|
+
#
|
181
|
+
# Setup sources according to the given options and the state of the
|
182
|
+
# definition.
|
183
|
+
#
|
184
|
+
# @return [Boolean] Whether fetching remote information will be necessary or not
|
185
|
+
#
|
186
|
+
def setup_domain!(options = {})
|
187
|
+
prefer_local! if options[:"prefer-local"]
|
188
|
+
|
189
|
+
if options[:add_checksums] || (!options[:local] && install_needed?)
|
190
|
+
remotely!
|
191
|
+
true
|
192
|
+
else
|
193
|
+
Bundler.settings.set_command_option(:jobs, 1) unless install_needed? # to avoid the overhead of Bundler::Worker
|
194
|
+
with_cache!
|
195
|
+
false
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
178
199
|
def resolve_with_cache!
|
200
|
+
with_cache!
|
201
|
+
|
202
|
+
resolve
|
203
|
+
end
|
204
|
+
|
205
|
+
def with_cache!
|
179
206
|
sources.local!
|
180
207
|
sources.cached!
|
181
|
-
resolve
|
182
208
|
end
|
183
209
|
|
184
210
|
def resolve_remotely!
|
211
|
+
remotely!
|
212
|
+
|
213
|
+
resolve
|
214
|
+
end
|
215
|
+
|
216
|
+
def remotely!
|
185
217
|
sources.cached!
|
186
218
|
sources.remote!
|
187
|
-
resolve
|
188
219
|
end
|
189
220
|
|
190
221
|
def prefer_local!
|
@@ -210,7 +241,7 @@ module Bundler
|
|
210
241
|
end
|
211
242
|
|
212
243
|
def missing_specs
|
213
|
-
resolve.
|
244
|
+
resolve.missing_specs_for(requested_dependencies)
|
214
245
|
end
|
215
246
|
|
216
247
|
def missing_specs?
|
@@ -274,11 +305,7 @@ module Bundler
|
|
274
305
|
groups.map!(&:to_sym)
|
275
306
|
deps = current_dependencies # always returns a new array
|
276
307
|
deps.select! do |d|
|
277
|
-
|
278
|
-
d.groups.intersect?(groups)
|
279
|
-
else
|
280
|
-
!(d.groups & groups).empty?
|
281
|
-
end
|
308
|
+
d.groups.intersect?(groups)
|
282
309
|
end
|
283
310
|
deps
|
284
311
|
end
|
@@ -316,11 +343,11 @@ module Bundler
|
|
316
343
|
end
|
317
344
|
|
318
345
|
def spec_git_paths
|
319
|
-
sources.git_sources.
|
346
|
+
sources.git_sources.filter_map {|s| File.realpath(s.path) if File.exist?(s.path) }
|
320
347
|
end
|
321
348
|
|
322
349
|
def groups
|
323
|
-
dependencies.
|
350
|
+
dependencies.flat_map(&:groups).uniq
|
324
351
|
end
|
325
352
|
|
326
353
|
def lock(file_or_preserve_unknown_sections = false, preserve_unknown_sections_or_unused = false)
|
@@ -465,6 +492,12 @@ module Bundler
|
|
465
492
|
"Add the current platform to the lockfile with\n`bundle lock --add-platform #{local_platform}` and try again."
|
466
493
|
end
|
467
494
|
|
495
|
+
def normalize_platforms
|
496
|
+
@platforms = resolve.normalize_platforms!(current_dependencies, platforms)
|
497
|
+
|
498
|
+
@resolve = SpecSet.new(resolve.for(current_dependencies, @platforms))
|
499
|
+
end
|
500
|
+
|
468
501
|
def add_platform(platform)
|
469
502
|
return if @platforms.include?(platform)
|
470
503
|
|
@@ -479,29 +512,12 @@ module Bundler
|
|
479
512
|
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
|
480
513
|
end
|
481
514
|
|
482
|
-
def most_specific_locked_platform
|
483
|
-
@platforms.min_by do |bundle_platform|
|
484
|
-
platform_specificity_match(bundle_platform, local_platform)
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
515
|
def nothing_changed?
|
489
|
-
|
490
|
-
|
491
|
-
!@source_changes &&
|
492
|
-
!@dependency_changes &&
|
493
|
-
!@current_platform_missing &&
|
494
|
-
@new_platforms.empty? &&
|
495
|
-
!@path_changes &&
|
496
|
-
!@local_changes &&
|
497
|
-
!@missing_lockfile_dep &&
|
498
|
-
!@unlocking_bundler &&
|
499
|
-
!@locked_spec_with_missing_deps &&
|
500
|
-
!@locked_spec_with_invalid_deps
|
516
|
+
!something_changed?
|
501
517
|
end
|
502
518
|
|
503
519
|
def no_resolve_needed?
|
504
|
-
!
|
520
|
+
!resolve_needed?
|
505
521
|
end
|
506
522
|
|
507
523
|
def unlocking?
|
@@ -510,8 +526,39 @@ module Bundler
|
|
510
526
|
|
511
527
|
attr_writer :source_requirements
|
512
528
|
|
529
|
+
def add_checksums
|
530
|
+
@locked_checksums = true
|
531
|
+
|
532
|
+
setup_domain!(add_checksums: true)
|
533
|
+
|
534
|
+
specs # force materialization to real specifications, so that checksums are fetched
|
535
|
+
end
|
536
|
+
|
513
537
|
private
|
514
538
|
|
539
|
+
def install_needed?
|
540
|
+
resolve_needed? || missing_specs?
|
541
|
+
end
|
542
|
+
|
543
|
+
def something_changed?
|
544
|
+
return true unless lockfile_exists?
|
545
|
+
|
546
|
+
@source_changes ||
|
547
|
+
@dependency_changes ||
|
548
|
+
@current_platform_missing ||
|
549
|
+
@new_platforms.any? ||
|
550
|
+
@path_changes ||
|
551
|
+
@local_changes ||
|
552
|
+
@missing_lockfile_dep ||
|
553
|
+
@unlocking_bundler ||
|
554
|
+
@locked_spec_with_missing_deps ||
|
555
|
+
@locked_spec_with_invalid_deps
|
556
|
+
end
|
557
|
+
|
558
|
+
def resolve_needed?
|
559
|
+
unlocking? || something_changed?
|
560
|
+
end
|
561
|
+
|
515
562
|
def should_add_extra_platforms?
|
516
563
|
!lockfile_exists? && generic_local_platform_is_ruby? && !Bundler.settings[:force_ruby_platform]
|
517
564
|
end
|
@@ -555,7 +602,7 @@ module Bundler
|
|
555
602
|
end
|
556
603
|
|
557
604
|
def resolver
|
558
|
-
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
|
605
|
+
@resolver ||= Resolver.new(resolution_packages, gem_version_promoter, @most_specific_locked_platform)
|
559
606
|
end
|
560
607
|
|
561
608
|
def expanded_dependencies
|
@@ -564,7 +611,7 @@ module Bundler
|
|
564
611
|
|
565
612
|
def dependencies_with_bundler
|
566
613
|
return dependencies unless @unlocking_bundler
|
567
|
-
return dependencies if dependencies.
|
614
|
+
return dependencies if dependencies.any? {|d| d.name == "bundler" }
|
568
615
|
|
569
616
|
[Dependency.new("bundler", @unlocking_bundler)] + dependencies
|
570
617
|
end
|
@@ -580,22 +627,46 @@ module Bundler
|
|
580
627
|
end
|
581
628
|
end
|
582
629
|
|
583
|
-
def filter_specs(specs, deps)
|
584
|
-
SpecSet.new(specs).for(deps,
|
630
|
+
def filter_specs(specs, deps, skips: [])
|
631
|
+
SpecSet.new(specs).for(deps, platforms, skips: skips)
|
585
632
|
end
|
586
633
|
|
587
634
|
def materialize(dependencies)
|
588
|
-
|
589
|
-
|
635
|
+
# Tracks potential endless loops trying to re-resolve.
|
636
|
+
# TODO: Remove as dead code if not reports are received in a while
|
637
|
+
incorrect_spec = nil
|
638
|
+
|
639
|
+
specs = begin
|
640
|
+
resolve.materialize(dependencies)
|
641
|
+
rescue IncorrectLockfileDependencies => e
|
642
|
+
spec = e.spec
|
643
|
+
raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec
|
644
|
+
|
645
|
+
incorrect_spec = spec
|
646
|
+
reresolve_without([spec])
|
647
|
+
retry
|
648
|
+
end
|
649
|
+
|
650
|
+
missing_specs = resolve.missing_specs
|
590
651
|
|
591
652
|
if missing_specs.any?
|
592
653
|
missing_specs.each do |s|
|
593
654
|
locked_gem = @locked_specs[s.name].last
|
594
655
|
next if locked_gem.nil? || locked_gem.version != s.version || sources.local_mode?
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
656
|
+
|
657
|
+
message = if sources.implicit_global_source?
|
658
|
+
"Because your Gemfile specifies no global remote source, your bundle is locked to " \
|
659
|
+
"#{locked_gem} from #{locked_gem.source}. However, #{locked_gem} is not installed. You'll " \
|
660
|
+
"need to either add a global remote source to your Gemfile or make sure #{locked_gem} is " \
|
661
|
+
"available locally before rerunning Bundler."
|
662
|
+
else
|
663
|
+
"Your bundle is locked to #{locked_gem} from #{locked_gem.source}, but that version can " \
|
664
|
+
"no longer be found in that source. That means the author of #{locked_gem} has removed it. " \
|
665
|
+
"You'll need to update your bundle to a version other than #{locked_gem} that hasn't been " \
|
666
|
+
"removed in order to install."
|
667
|
+
end
|
668
|
+
|
669
|
+
raise GemNotFound, message
|
599
670
|
end
|
600
671
|
|
601
672
|
missing_specs_list = missing_specs.group_by(&:source).map do |source, missing_specs_for_source|
|
@@ -605,17 +676,24 @@ module Bundler
|
|
605
676
|
raise GemNotFound, "Could not find #{missing_specs_list.join(" nor ")}"
|
606
677
|
end
|
607
678
|
|
608
|
-
|
679
|
+
partially_missing_specs = resolve.partially_missing_specs
|
680
|
+
|
681
|
+
if partially_missing_specs.any? && !sources.local_mode?
|
682
|
+
Bundler.ui.warn "Some locked specs have possibly been yanked (#{partially_missing_specs.map(&:full_name).join(", ")}). Ignoring them..."
|
683
|
+
|
684
|
+
resolve.delete(partially_missing_specs)
|
685
|
+
end
|
686
|
+
|
687
|
+
incomplete_specs = resolve.incomplete_specs
|
609
688
|
loop do
|
610
689
|
break if incomplete_specs.empty?
|
611
690
|
|
612
691
|
Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
|
613
692
|
sources.remote!
|
614
|
-
|
615
|
-
@resolve = start_resolution
|
693
|
+
reresolve_without(incomplete_specs)
|
616
694
|
specs = resolve.materialize(dependencies)
|
617
695
|
|
618
|
-
still_incomplete_specs =
|
696
|
+
still_incomplete_specs = resolve.incomplete_specs
|
619
697
|
|
620
698
|
if still_incomplete_specs == incomplete_specs
|
621
699
|
package = resolution_packages.get_package(incomplete_specs.first.name)
|
@@ -625,12 +703,26 @@ module Bundler
|
|
625
703
|
incomplete_specs = still_incomplete_specs
|
626
704
|
end
|
627
705
|
|
706
|
+
insecurely_materialized_specs = resolve.insecurely_materialized_specs
|
707
|
+
|
708
|
+
if insecurely_materialized_specs.any?
|
709
|
+
Bundler.ui.warn "The following platform specific gems are getting installed, yet the lockfile includes only their generic ruby version:\n" \
|
710
|
+
" * #{insecurely_materialized_specs.map(&:full_name).join("\n * ")}\n" \
|
711
|
+
"Please run `bundle lock --normalize-platforms` and commit the resulting lockfile.\n" \
|
712
|
+
"Alternatively, you may run `bundle lock --add-platform <list-of-platforms-that-you-want-to-support>`"
|
713
|
+
end
|
714
|
+
|
628
715
|
bundler = sources.metadata_source.specs.search(["bundler", Bundler.gem_version]).last
|
629
716
|
specs["bundler"] = bundler
|
630
717
|
|
631
718
|
specs
|
632
719
|
end
|
633
720
|
|
721
|
+
def reresolve_without(incomplete_specs)
|
722
|
+
resolution_packages.delete(incomplete_specs)
|
723
|
+
@resolve = start_resolution
|
724
|
+
end
|
725
|
+
|
634
726
|
def start_resolution
|
635
727
|
local_platform_needed_for_resolvability = @most_specific_non_local_locked_ruby_platform && !@platforms.include?(local_platform)
|
636
728
|
@platforms << local_platform if local_platform_needed_for_resolvability
|
@@ -650,7 +742,7 @@ module Bundler
|
|
650
742
|
|
651
743
|
@platforms = result.add_extra_platforms!(platforms) if should_add_extra_platforms?
|
652
744
|
|
653
|
-
SpecSet.new(result.for(dependencies,
|
745
|
+
SpecSet.new(result.for(dependencies, @platforms))
|
654
746
|
end
|
655
747
|
|
656
748
|
def precompute_source_requirements_for_indirect_dependencies?
|
@@ -676,7 +768,7 @@ module Bundler
|
|
676
768
|
def find_most_specific_locked_ruby_platform
|
677
769
|
return unless generic_local_platform_is_ruby? && current_platform_locked?
|
678
770
|
|
679
|
-
most_specific_locked_platform
|
771
|
+
@most_specific_locked_platform
|
680
772
|
end
|
681
773
|
|
682
774
|
def change_reason
|
@@ -877,7 +969,7 @@ module Bundler
|
|
877
969
|
def converge_locked_specs
|
878
970
|
converged = converge_specs(@locked_specs)
|
879
971
|
|
880
|
-
resolve = SpecSet.new(converged
|
972
|
+
resolve = SpecSet.new(converged)
|
881
973
|
|
882
974
|
diff = nil
|
883
975
|
|
@@ -906,8 +998,7 @@ module Bundler
|
|
906
998
|
if dep
|
907
999
|
gemfile_source = dep.source || default_source
|
908
1000
|
|
909
|
-
deps << dep if !dep.source || lockfile_source.include?(dep.source)
|
910
|
-
@gems_to_unlock << name if lockfile_source.include?(dep.source) && lockfile_source != gemfile_source
|
1001
|
+
deps << dep if !dep.source || lockfile_source.include?(dep.source) || new_deps.include?(dep)
|
911
1002
|
|
912
1003
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
913
1004
|
s.source = gemfile_source
|
@@ -916,25 +1007,14 @@ module Bundler
|
|
916
1007
|
s.source = default_source unless sources.get(lockfile_source)
|
917
1008
|
end
|
918
1009
|
|
919
|
-
|
1010
|
+
source = s.source
|
1011
|
+
next if @sources_to_unlock.include?(source.name)
|
920
1012
|
|
921
1013
|
# Path sources have special logic
|
922
|
-
if
|
923
|
-
|
924
|
-
s.source.specs
|
925
|
-
rescue PathError
|
926
|
-
# if we won't need the source (according to the lockfile),
|
927
|
-
# don't error if the path source isn't available
|
928
|
-
next if specs.
|
929
|
-
for(requested_dependencies, false).
|
930
|
-
none? {|locked_spec| locked_spec.source == s.source }
|
931
|
-
|
932
|
-
raise
|
933
|
-
end
|
934
|
-
|
935
|
-
new_spec = new_specs[s].first
|
1014
|
+
if source.instance_of?(Source::Path) || source.instance_of?(Source::Gemspec) || (source.instance_of?(Source::Git) && !@gems_to_unlock.include?(name) && deps.include?(dep))
|
1015
|
+
new_spec = source.specs[s].first
|
936
1016
|
if new_spec
|
937
|
-
s.
|
1017
|
+
s.runtime_dependencies.replace(new_spec.runtime_dependencies)
|
938
1018
|
else
|
939
1019
|
# If the spec is no longer in the path source, unlock it. This
|
940
1020
|
# commonly happens if the version changed in the gemspec
|
@@ -942,14 +1022,15 @@ module Bundler
|
|
942
1022
|
end
|
943
1023
|
end
|
944
1024
|
|
945
|
-
if dep.nil? && requested_dependencies.find {|d| name == d.name }
|
946
|
-
@gems_to_unlock <<
|
947
|
-
|
948
|
-
converged << s
|
1025
|
+
if dep.nil? && requested_dep = requested_dependencies.find {|d| name == d.name }
|
1026
|
+
@gems_to_unlock << name
|
1027
|
+
deps << requested_dep
|
949
1028
|
end
|
1029
|
+
|
1030
|
+
converged << s
|
950
1031
|
end
|
951
1032
|
|
952
|
-
filter_specs(converged, deps)
|
1033
|
+
filter_specs(converged, deps, skips: @gems_to_unlock)
|
953
1034
|
end
|
954
1035
|
|
955
1036
|
def metadata_dependencies
|
data/lib/bundler/dependency.rb
CHANGED
data/lib/bundler/dsl.rb
CHANGED
@@ -66,7 +66,7 @@ module Bundler
|
|
66
66
|
development_group = opts[:development_group] || :development
|
67
67
|
expanded_path = gemfile_root.join(path)
|
68
68
|
|
69
|
-
gemspecs = Gem::Util.glob_files_in_dir("{,*}.gemspec", expanded_path).
|
69
|
+
gemspecs = Gem::Util.glob_files_in_dir("{,*}.gemspec", expanded_path).filter_map {|g| Bundler.load_gemspec(g) }
|
70
70
|
gemspecs.reject! {|s| s.name != name } if name
|
71
71
|
specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }
|
72
72
|
|
@@ -503,18 +503,7 @@ module Bundler
|
|
503
503
|
end
|
504
504
|
|
505
505
|
def check_rubygems_source_safety
|
506
|
-
if @sources.
|
507
|
-
implicit_global_source_warning
|
508
|
-
elsif @sources.aggregate_global_source?
|
509
|
-
multiple_global_source_warning
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
def implicit_global_source_warning
|
514
|
-
Bundler::SharedHelpers.major_deprecation 2, "This Gemfile does not include an explicit global source. " \
|
515
|
-
"Not using an explicit global source may result in a different lockfile being generated depending on " \
|
516
|
-
"the gems you have installed locally before bundler is run. " \
|
517
|
-
"Instead, define a global source in your Gemfile like this: source \"https://rubygems.org\"."
|
506
|
+
multiple_global_source_warning if @sources.aggregate_global_source?
|
518
507
|
end
|
519
508
|
|
520
509
|
def multiple_global_source_warning
|
@@ -6,7 +6,7 @@ module Bundler
|
|
6
6
|
include MatchRemoteMetadata
|
7
7
|
|
8
8
|
attr_reader :name, :version, :platform, :checksum
|
9
|
-
attr_accessor :
|
9
|
+
attr_accessor :remote, :dependencies, :locked_platform
|
10
10
|
|
11
11
|
def initialize(name, version, platform, spec_fetcher, dependencies, metadata = nil)
|
12
12
|
super()
|
@@ -18,10 +18,15 @@ module Bundler
|
|
18
18
|
|
19
19
|
@loaded_from = nil
|
20
20
|
@remote_specification = nil
|
21
|
+
@locked_platform = nil
|
21
22
|
|
22
23
|
parse_metadata(metadata)
|
23
24
|
end
|
24
25
|
|
26
|
+
def insecurely_materialized?
|
27
|
+
@locked_platform.to_s != @platform.to_s
|
28
|
+
end
|
29
|
+
|
25
30
|
def fetch_platform
|
26
31
|
@platform
|
27
32
|
end
|
@@ -115,6 +120,10 @@ module Bundler
|
|
115
120
|
@remote_specification = spec
|
116
121
|
end
|
117
122
|
|
123
|
+
def inspect
|
124
|
+
"#<#{self.class} @name=\"#{name}\" (#{full_name.delete_prefix("#{name}-")})>"
|
125
|
+
end
|
126
|
+
|
118
127
|
private
|
119
128
|
|
120
129
|
def _remote_specification
|
data/lib/bundler/errors.rb
CHANGED
@@ -246,4 +246,14 @@ module Bundler
|
|
246
246
|
end
|
247
247
|
|
248
248
|
class InvalidArgumentError < BundlerError; status_code(40); end
|
249
|
+
|
250
|
+
class IncorrectLockfileDependencies < BundlerError
|
251
|
+
attr_reader :spec
|
252
|
+
|
253
|
+
def initialize(spec)
|
254
|
+
@spec = spec
|
255
|
+
end
|
256
|
+
|
257
|
+
status_code(41)
|
258
|
+
end
|
249
259
|
end
|
data/lib/bundler/feature_flag.rb
CHANGED
@@ -33,6 +33,7 @@ module Bundler
|
|
33
33
|
settings_flag(:default_install_uses_path) { bundler_3_mode? }
|
34
34
|
settings_flag(:forget_cli_options) { bundler_3_mode? }
|
35
35
|
settings_flag(:global_gem_cache) { bundler_3_mode? }
|
36
|
+
settings_flag(:lockfile_checksums) { bundler_3_mode? }
|
36
37
|
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
|
37
38
|
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
|
38
39
|
settings_flag(:print_only_version_number) { bundler_3_mode? }
|
@@ -10,7 +10,7 @@ module Bundler
|
|
10
10
|
method = instance_method(method_name)
|
11
11
|
undef_method(method_name)
|
12
12
|
define_method(method_name) do |*args, &blk|
|
13
|
-
method.
|
13
|
+
method.bind_call(self, *args, &blk)
|
14
14
|
rescue NetworkDownError, CompactIndexClient::Updater::MismatchedChecksumError => e
|
15
15
|
raise HTTPError, e.message
|
16
16
|
rescue AuthenticationRequiredError, BadAuthenticationError
|
data/lib/bundler/fetcher.rb
CHANGED
@@ -37,8 +37,9 @@ module Bundler
|
|
37
37
|
# This is the error raised when a source is HTTPS and OpenSSL didn't load
|
38
38
|
class SSLError < HTTPError
|
39
39
|
def initialize(msg = nil)
|
40
|
-
super
|
41
|
-
|
40
|
+
super "Could not load OpenSSL.\n" \
|
41
|
+
"You must recompile Ruby with OpenSSL support.\n" \
|
42
|
+
"original error: #{msg}\n"
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -251,7 +252,13 @@ module Bundler
|
|
251
252
|
needs_ssl = remote_uri.scheme == "https" ||
|
252
253
|
Bundler.settings[:ssl_verify_mode] ||
|
253
254
|
Bundler.settings[:ssl_client_cert]
|
254
|
-
|
255
|
+
if needs_ssl
|
256
|
+
begin
|
257
|
+
require "openssl"
|
258
|
+
rescue StandardError, LoadError => e
|
259
|
+
raise SSLError.new(e.message)
|
260
|
+
end
|
261
|
+
end
|
255
262
|
|
256
263
|
con = Gem::Net::HTTP::Persistent.new name: "bundler", proxy: :ENV
|
257
264
|
if gem_proxy = Gem.configuration[:http_proxy]
|
data/lib/bundler/gem_helpers.rb
CHANGED
@@ -46,7 +46,7 @@ module Bundler
|
|
46
46
|
end
|
47
47
|
module_function :platform_specificity_match
|
48
48
|
|
49
|
-
def
|
49
|
+
def select_all_platform_match(specs, platform, force_ruby: false, prefer_locked: false)
|
50
50
|
matching = if force_ruby
|
51
51
|
specs.select {|spec| spec.match_platform(Gem::Platform::RUBY) && spec.force_ruby_platform! }
|
52
52
|
else
|
@@ -58,24 +58,40 @@ module Bundler
|
|
58
58
|
return locked_originally if locked_originally.any?
|
59
59
|
end
|
60
60
|
|
61
|
-
|
61
|
+
matching
|
62
|
+
end
|
63
|
+
module_function :select_all_platform_match
|
64
|
+
|
65
|
+
def select_best_platform_match(specs, platform, force_ruby: false, prefer_locked: false)
|
66
|
+
matching = select_all_platform_match(specs, platform, force_ruby: force_ruby, prefer_locked: prefer_locked)
|
67
|
+
|
68
|
+
sort_and_filter_best_platform_match(matching, platform)
|
62
69
|
end
|
63
70
|
module_function :select_best_platform_match
|
64
71
|
|
65
72
|
def select_best_local_platform_match(specs, force_ruby: false)
|
66
|
-
|
73
|
+
matching = select_all_platform_match(specs, local_platform, force_ruby: force_ruby).filter_map(&:materialized_for_installation)
|
74
|
+
|
75
|
+
sort_best_platform_match(matching, local_platform)
|
67
76
|
end
|
68
77
|
module_function :select_best_local_platform_match
|
69
78
|
|
70
|
-
def
|
79
|
+
def sort_and_filter_best_platform_match(matching, platform)
|
80
|
+
return matching if matching.one?
|
81
|
+
|
71
82
|
exact = matching.select {|spec| spec.platform == platform }
|
72
83
|
return exact if exact.any?
|
73
84
|
|
74
|
-
sorted_matching = matching
|
85
|
+
sorted_matching = sort_best_platform_match(matching, platform)
|
75
86
|
exemplary_spec = sorted_matching.first
|
76
87
|
|
77
88
|
sorted_matching.take_while {|spec| same_specificity(platform, spec, exemplary_spec) && same_deps(spec, exemplary_spec) }
|
78
89
|
end
|
90
|
+
module_function :sort_and_filter_best_platform_match
|
91
|
+
|
92
|
+
def sort_best_platform_match(matching, platform)
|
93
|
+
matching.sort_by {|spec| platform_specificity_match(spec.platform, platform) }
|
94
|
+
end
|
79
95
|
module_function :sort_best_platform_match
|
80
96
|
|
81
97
|
class PlatformMatch
|
data/lib/bundler/injector.rb
CHANGED
@@ -41,7 +41,7 @@ module Bundler
|
|
41
41
|
|
42
42
|
# resolve to see if the new deps broke anything
|
43
43
|
@definition = builder.to_definition(lockfile_path, {})
|
44
|
-
@definition.
|
44
|
+
@definition.remotely!
|
45
45
|
|
46
46
|
# since nothing broke, we can add those gems to the gemfile
|
47
47
|
append_to(gemfile_path, build_gem_lines(@options[:conservative_versioning])) if @deps.any?
|
@@ -184,7 +184,7 @@ module Bundler
|
|
184
184
|
# @param [Array] gems Array of names of gems to be removed.
|
185
185
|
# @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
|
186
186
|
def remove_gems_from_gemfile(gems, gemfile_path)
|
187
|
-
patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2
|
187
|
+
patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2.*\)/
|
188
188
|
new_gemfile = []
|
189
189
|
multiline_removal = false
|
190
190
|
File.readlines(gemfile_path).each do |line|
|
@@ -28,7 +28,7 @@ module Bundler
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def paths
|
31
|
-
@specs.
|
31
|
+
@specs.flat_map do |spec|
|
32
32
|
next if spec.name == "bundler"
|
33
33
|
Array(spec.require_paths).map do |path|
|
34
34
|
gem_path(path, spec).
|
@@ -36,7 +36,7 @@ module Bundler
|
|
36
36
|
sub(extensions_dir, 'extensions/\k<platform>/#{Gem.extension_api_version}')
|
37
37
|
# This is a static string intentionally. It's interpolated at a later time.
|
38
38
|
end
|
39
|
-
end.
|
39
|
+
end.compact
|
40
40
|
end
|
41
41
|
|
42
42
|
def version_dir
|