bundler 2.7.1 → 4.0.0.beta1
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 +1001 -902
- data/README.md +4 -4
- data/bundler.gemspec +3 -3
- data/lib/bundler/build_metadata.rb +2 -2
- data/lib/bundler/capistrano.rb +1 -19
- data/lib/bundler/checksum.rb +6 -0
- data/lib/bundler/cli/cache.rb +1 -12
- data/lib/bundler/cli/common.rb +21 -4
- data/lib/bundler/cli/config.rb +1 -2
- data/lib/bundler/cli/console.rb +5 -0
- data/lib/bundler/cli/exec.rb +29 -4
- data/lib/bundler/cli/gem.rb +19 -33
- data/lib/bundler/cli/install.rb +7 -84
- data/lib/bundler/cli/issue.rb +2 -2
- data/lib/bundler/cli/list.rb +33 -2
- data/lib/bundler/cli/lock.rb +5 -5
- data/lib/bundler/cli/plugin.rb +5 -1
- data/lib/bundler/cli/show.rb +3 -7
- data/lib/bundler/cli/update.rb +3 -3
- data/lib/bundler/cli.rb +97 -95
- data/lib/bundler/compact_index_client.rb +0 -1
- data/lib/bundler/current_ruby.rb +3 -15
- data/lib/bundler/definition.rb +122 -95
- data/lib/bundler/deployment.rb +1 -64
- data/lib/bundler/digest.rb +1 -1
- data/lib/bundler/dsl.rb +14 -36
- data/lib/bundler/endpoint_specification.rb +0 -22
- data/lib/bundler/errors.rb +1 -5
- data/lib/bundler/feature_flag.rb +0 -33
- data/lib/bundler/fetcher/compact_index.rb +1 -1
- data/lib/bundler/friendly_errors.rb +2 -2
- data/lib/bundler/index.rb +0 -7
- data/lib/bundler/inline.rb +1 -1
- data/lib/bundler/installer/gem_installer.rb +0 -11
- data/lib/bundler/installer.rb +0 -6
- data/lib/bundler/lockfile_generator.rb +1 -1
- data/lib/bundler/lockfile_parser.rb +2 -12
- data/lib/bundler/man/bundle-add.1 +1 -1
- data/lib/bundler/man/bundle-binstubs.1 +3 -6
- data/lib/bundler/man/bundle-binstubs.1.ronn +4 -6
- data/lib/bundler/man/bundle-cache.1 +2 -14
- data/lib/bundler/man/bundle-cache.1.ronn +1 -14
- data/lib/bundler/man/bundle-check.1 +2 -5
- data/lib/bundler/man/bundle-check.1.ronn +0 -5
- data/lib/bundler/man/bundle-clean.1 +1 -1
- data/lib/bundler/man/bundle-config.1 +36 -46
- data/lib/bundler/man/bundle-config.1.ronn +69 -75
- data/lib/bundler/man/bundle-console.1 +1 -1
- data/lib/bundler/man/bundle-doctor.1 +4 -4
- data/lib/bundler/man/bundle-doctor.1.ronn +4 -4
- data/lib/bundler/man/bundle-env.1 +1 -1
- data/lib/bundler/man/bundle-exec.1 +2 -5
- data/lib/bundler/man/bundle-exec.1.ronn +1 -5
- data/lib/bundler/man/bundle-fund.1 +1 -1
- data/lib/bundler/man/bundle-gem.1 +3 -6
- data/lib/bundler/man/bundle-gem.1.ronn +2 -5
- data/lib/bundler/man/bundle-help.1 +1 -1
- data/lib/bundler/man/bundle-info.1 +1 -1
- data/lib/bundler/man/bundle-init.1 +1 -1
- data/lib/bundler/man/bundle-install.1 +8 -59
- data/lib/bundler/man/bundle-install.1.ronn +12 -107
- data/lib/bundler/man/bundle-issue.1 +1 -1
- data/lib/bundler/man/bundle-licenses.1 +1 -1
- data/lib/bundler/man/bundle-list.1 +6 -1
- data/lib/bundler/man/bundle-list.1.ronn +5 -0
- 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-plugin.1 +33 -15
- data/lib/bundler/man/bundle-plugin.1.ronn +36 -15
- data/lib/bundler/man/bundle-pristine.1 +1 -1
- data/lib/bundler/man/bundle-remove.1 +2 -8
- data/lib/bundler/man/bundle-remove.1.ronn +1 -8
- data/lib/bundler/man/bundle-show.1 +2 -5
- data/lib/bundler/man/bundle-show.1.ronn +0 -4
- data/lib/bundler/man/bundle-update.1 +1 -1
- data/lib/bundler/man/bundle-version.1 +1 -1
- data/lib/bundler/man/bundle.1 +1 -10
- data/lib/bundler/man/bundle.1.ronn +0 -9
- data/lib/bundler/man/gemfile.5 +1 -1
- data/lib/bundler/man/index.txt +0 -2
- data/lib/bundler/materialization.rb +1 -1
- data/lib/bundler/plugin/installer.rb +0 -10
- data/lib/bundler/plugin/source_list.rb +1 -1
- data/lib/bundler/plugin.rb +1 -1
- data/lib/bundler/resolver/package.rb +1 -0
- data/lib/bundler/resolver.rb +1 -1
- data/lib/bundler/ruby_dsl.rb +2 -0
- data/lib/bundler/ruby_version.rb +1 -3
- data/lib/bundler/rubygems_ext.rb +1 -1
- data/lib/bundler/rubygems_gem_installer.rb +1 -1
- data/lib/bundler/rubygems_integration.rb +1 -5
- data/lib/bundler/self_manager.rb +1 -1
- data/lib/bundler/settings.rb +8 -27
- data/lib/bundler/shared_helpers.rb +8 -20
- data/lib/bundler/source/gemspec.rb +4 -0
- data/lib/bundler/source/git/git_proxy.rb +3 -11
- data/lib/bundler/source/git.rb +2 -3
- data/lib/bundler/source/path.rb +5 -7
- data/lib/bundler/source/rubygems.rb +11 -17
- data/lib/bundler/source.rb +1 -1
- data/lib/bundler/source_list.rb +4 -45
- data/lib/bundler/source_map.rb +2 -5
- data/lib/bundler/spec_set.rb +6 -15
- data/lib/bundler/templates/newgem/CODE_OF_CONDUCT.md.tt +7 -129
- data/lib/bundler/templates/newgem/circleci/config.yml.tt +12 -0
- data/lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt +1 -1
- data/lib/bundler/templates/newgem/ext/newgem/extconf-go.rb.tt +11 -0
- data/lib/bundler/templates/newgem/ext/newgem/go.mod.tt +5 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem-go.c.tt +2 -0
- data/lib/bundler/templates/newgem/ext/newgem/newgem.go.tt +31 -0
- data/lib/bundler/templates/newgem/github/workflows/main.yml.tt +6 -0
- data/lib/bundler/templates/newgem/gitlab-ci.yml.tt +9 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +7 -4
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/timed_stack.rb +26 -23
- data/lib/bundler/vendor/connection_pool/lib/connection_pool/version.rb +1 -1
- data/lib/bundler/vendor/connection_pool/lib/connection_pool.rb +50 -6
- data/lib/bundler/vendor/fileutils/lib/fileutils.rb +57 -52
- data/lib/bundler/vendor/net-http-persistent/lib/net/http/persistent.rb +5 -2
- data/lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb +42 -6
- data/lib/bundler/vendor/thor/lib/thor/parser/options.rb +1 -1
- data/lib/bundler/vendor/thor/lib/thor/runner.rb +2 -2
- data/lib/bundler/vendor/thor/lib/thor/shell/basic.rb +3 -7
- data/lib/bundler/vendor/thor/lib/thor/version.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/common.rb +57 -15
- data/lib/bundler/vendor/uri/lib/uri/file.rb +1 -1
- data/lib/bundler/vendor/uri/lib/uri/generic.rb +34 -21
- data/lib/bundler/vendor/uri/lib/uri/http.rb +12 -0
- data/lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb +9 -8
- data/lib/bundler/vendor/uri/lib/uri/version.rb +2 -2
- data/lib/bundler/version.rb +1 -1
- data/lib/bundler/vlad.rb +1 -14
- data/lib/bundler.rb +6 -28
- metadata +9 -13
- data/lib/bundler/cli/inject.rb +0 -60
- data/lib/bundler/cli/viz.rb +0 -31
- data/lib/bundler/graph.rb +0 -152
- data/lib/bundler/man/bundle-inject.1 +0 -31
- data/lib/bundler/man/bundle-inject.1.ronn +0 -32
- data/lib/bundler/man/bundle-viz.1 +0 -30
- data/lib/bundler/man/bundle-viz.1.ronn +0 -36
- data/lib/bundler/similarity_detector.rb +0 -63
data/lib/bundler/definition.rb
CHANGED
|
@@ -107,6 +107,7 @@ module Bundler
|
|
|
107
107
|
@locked_ruby_version = @locked_gems.ruby_version
|
|
108
108
|
@locked_deps = @locked_gems.dependencies
|
|
109
109
|
@originally_locked_specs = SpecSet.new(@locked_gems.specs)
|
|
110
|
+
@originally_locked_sources = @locked_gems.sources
|
|
110
111
|
@locked_checksums = @locked_gems.checksums
|
|
111
112
|
|
|
112
113
|
if @unlocking_all
|
|
@@ -114,7 +115,16 @@ module Bundler
|
|
|
114
115
|
@locked_sources = []
|
|
115
116
|
else
|
|
116
117
|
@locked_specs = @originally_locked_specs
|
|
117
|
-
@locked_sources = @
|
|
118
|
+
@locked_sources = @originally_locked_sources
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
locked_gem_sources = @originally_locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
122
|
+
multisource_lockfile = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes?
|
|
123
|
+
|
|
124
|
+
if multisource_lockfile
|
|
125
|
+
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
|
|
126
|
+
|
|
127
|
+
Bundler::SharedHelpers.feature_removed! msg
|
|
118
128
|
end
|
|
119
129
|
else
|
|
120
130
|
@locked_gems = nil
|
|
@@ -123,22 +133,10 @@ module Bundler
|
|
|
123
133
|
@platforms = []
|
|
124
134
|
@locked_deps = {}
|
|
125
135
|
@locked_specs = SpecSet.new([])
|
|
126
|
-
@originally_locked_specs = @locked_specs
|
|
127
136
|
@locked_sources = []
|
|
128
|
-
@
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
132
|
-
@multisource_allowed = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes? && Bundler.frozen_bundle?
|
|
133
|
-
|
|
134
|
-
if @multisource_allowed
|
|
135
|
-
unless sources.aggregate_global_source?
|
|
136
|
-
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure."
|
|
137
|
-
|
|
138
|
-
Bundler::SharedHelpers.major_deprecation 2, msg
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
@sources.merged_gem_lockfile_sections!(locked_gem_sources.first)
|
|
137
|
+
@originally_locked_specs = @locked_specs
|
|
138
|
+
@originally_locked_sources = @locked_sources
|
|
139
|
+
@locked_checksums = Bundler.settings[:lockfile_checksums]
|
|
142
140
|
end
|
|
143
141
|
|
|
144
142
|
@unlocking_ruby ||= if @ruby_version && locked_ruby_version_object
|
|
@@ -189,12 +187,14 @@ module Bundler
|
|
|
189
187
|
def setup_domain!(options = {})
|
|
190
188
|
prefer_local! if options[:"prefer-local"]
|
|
191
189
|
|
|
190
|
+
sources.cached!
|
|
191
|
+
|
|
192
192
|
if options[:add_checksums] || (!options[:local] && install_needed?)
|
|
193
|
-
|
|
193
|
+
sources.remote!
|
|
194
194
|
true
|
|
195
195
|
else
|
|
196
196
|
Bundler.settings.set_command_option(:jobs, 1) unless install_needed? # to avoid the overhead of Bundler::Worker
|
|
197
|
-
|
|
197
|
+
sources.local!
|
|
198
198
|
false
|
|
199
199
|
end
|
|
200
200
|
end
|
|
@@ -282,12 +282,17 @@ module Bundler
|
|
|
282
282
|
end
|
|
283
283
|
|
|
284
284
|
def filter_relevant(dependencies)
|
|
285
|
-
platforms_array = [Bundler.generic_local_platform].freeze
|
|
286
285
|
dependencies.select do |d|
|
|
287
|
-
|
|
286
|
+
relevant_deps?(d)
|
|
288
287
|
end
|
|
289
288
|
end
|
|
290
289
|
|
|
290
|
+
def relevant_deps?(dep)
|
|
291
|
+
platforms_array = [Bundler.generic_local_platform].freeze
|
|
292
|
+
|
|
293
|
+
dep.should_include? && !dep.gem_platforms(platforms_array).empty?
|
|
294
|
+
end
|
|
295
|
+
|
|
291
296
|
def locked_dependencies
|
|
292
297
|
@locked_deps.values
|
|
293
298
|
end
|
|
@@ -367,12 +372,50 @@ module Bundler
|
|
|
367
372
|
|
|
368
373
|
msg = "`Definition#lock` was passed a target file argument. #{suggestion}"
|
|
369
374
|
|
|
370
|
-
Bundler::SharedHelpers.
|
|
375
|
+
Bundler::SharedHelpers.feature_removed! msg
|
|
371
376
|
end
|
|
372
377
|
|
|
373
378
|
write_lock(target_lockfile, preserve_unknown_sections)
|
|
374
379
|
end
|
|
375
380
|
|
|
381
|
+
def write_lock(file, preserve_unknown_sections)
|
|
382
|
+
return if Definition.no_lock || file.nil?
|
|
383
|
+
|
|
384
|
+
contents = to_lock
|
|
385
|
+
|
|
386
|
+
# Convert to \r\n if the existing lock has them
|
|
387
|
+
# i.e., Windows with `git config core.autocrlf=true`
|
|
388
|
+
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
|
|
389
|
+
|
|
390
|
+
if @locked_bundler_version
|
|
391
|
+
locked_major = @locked_bundler_version.segments.first
|
|
392
|
+
current_major = bundler_version_to_lock.segments.first
|
|
393
|
+
|
|
394
|
+
updating_major = locked_major < current_major
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
|
398
|
+
|
|
399
|
+
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
|
400
|
+
return if Bundler.frozen_bundle?
|
|
401
|
+
SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
|
|
402
|
+
return
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
if Bundler.frozen_bundle?
|
|
406
|
+
Bundler.ui.error "Cannot write a changed lockfile while frozen."
|
|
407
|
+
return
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
begin
|
|
411
|
+
SharedHelpers.filesystem_access(file) do |p|
|
|
412
|
+
File.open(p, "wb") {|f| f.puts(contents) }
|
|
413
|
+
end
|
|
414
|
+
rescue ReadOnlyFileSystemError
|
|
415
|
+
raise ProductionError, lockfile_changes_summary("file system is read-only")
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
376
419
|
def locked_ruby_version
|
|
377
420
|
return unless ruby_version
|
|
378
421
|
if @unlocking_ruby || !@locked_ruby_version
|
|
@@ -492,14 +535,23 @@ module Bundler
|
|
|
492
535
|
@unlocking
|
|
493
536
|
end
|
|
494
537
|
|
|
495
|
-
attr_writer :source_requirements
|
|
496
|
-
|
|
497
538
|
def add_checksums
|
|
498
539
|
@locked_checksums = true
|
|
499
540
|
|
|
500
541
|
setup_domain!(add_checksums: true)
|
|
501
542
|
|
|
502
|
-
|
|
543
|
+
# force materialization to real specifications, so that checksums are fetched
|
|
544
|
+
specs.each do |spec|
|
|
545
|
+
next unless spec.source.is_a?(Bundler::Source::Rubygems)
|
|
546
|
+
# Checksum was fetched from the compact index API.
|
|
547
|
+
next if !spec.source.checksum_store.missing?(spec) && !spec.source.checksum_store.empty?(spec)
|
|
548
|
+
# The gem isn't installed, can't compute the checksum.
|
|
549
|
+
next unless spec.loaded_from
|
|
550
|
+
|
|
551
|
+
package = Gem::Package.new(spec.source.cached_built_in_gem(spec))
|
|
552
|
+
checksum = Checksum.from_gem_package(package)
|
|
553
|
+
spec.source.checksum_store.register(spec, checksum)
|
|
554
|
+
end
|
|
503
555
|
end
|
|
504
556
|
|
|
505
557
|
private
|
|
@@ -533,7 +585,7 @@ module Bundler
|
|
|
533
585
|
|
|
534
586
|
return unless added.any? || deleted.any? || changed.any? || resolve_needed?
|
|
535
587
|
|
|
536
|
-
msg = String.new("#{change_reason.
|
|
588
|
+
msg = String.new("#{change_reason[0].upcase}#{change_reason[1..-1].strip}, but ")
|
|
537
589
|
msg << "the lockfile " unless msg.start_with?("Your lockfile")
|
|
538
590
|
msg << "can't be updated because #{update_refused_reason}"
|
|
539
591
|
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
|
@@ -559,6 +611,7 @@ module Bundler
|
|
|
559
611
|
@missing_lockfile_dep ||
|
|
560
612
|
@unlocking_bundler ||
|
|
561
613
|
@locked_spec_with_missing_checksums ||
|
|
614
|
+
@locked_spec_with_empty_checksums ||
|
|
562
615
|
@locked_spec_with_missing_deps ||
|
|
563
616
|
@locked_spec_with_invalid_deps
|
|
564
617
|
end
|
|
@@ -575,46 +628,8 @@ module Bundler
|
|
|
575
628
|
lockfile && File.exist?(lockfile)
|
|
576
629
|
end
|
|
577
630
|
|
|
578
|
-
def write_lock(file, preserve_unknown_sections)
|
|
579
|
-
return if Definition.no_lock || file.nil?
|
|
580
|
-
|
|
581
|
-
contents = to_lock
|
|
582
|
-
|
|
583
|
-
# Convert to \r\n if the existing lock has them
|
|
584
|
-
# i.e., Windows with `git config core.autocrlf=true`
|
|
585
|
-
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
|
|
586
|
-
|
|
587
|
-
if @locked_bundler_version
|
|
588
|
-
locked_major = @locked_bundler_version.segments.first
|
|
589
|
-
current_major = bundler_version_to_lock.segments.first
|
|
590
|
-
|
|
591
|
-
updating_major = locked_major < current_major
|
|
592
|
-
end
|
|
593
|
-
|
|
594
|
-
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
|
595
|
-
|
|
596
|
-
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
|
597
|
-
return if Bundler.frozen_bundle?
|
|
598
|
-
SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
|
|
599
|
-
return
|
|
600
|
-
end
|
|
601
|
-
|
|
602
|
-
if Bundler.frozen_bundle?
|
|
603
|
-
Bundler.ui.error "Cannot write a changed lockfile while frozen."
|
|
604
|
-
return
|
|
605
|
-
end
|
|
606
|
-
|
|
607
|
-
begin
|
|
608
|
-
SharedHelpers.filesystem_access(file) do |p|
|
|
609
|
-
File.open(p, "wb") {|f| f.puts(contents) }
|
|
610
|
-
end
|
|
611
|
-
rescue ReadOnlyFileSystemError
|
|
612
|
-
raise ProductionError, lockfile_changes_summary("file system is read-only")
|
|
613
|
-
end
|
|
614
|
-
end
|
|
615
|
-
|
|
616
631
|
def resolver
|
|
617
|
-
@resolver ||=
|
|
632
|
+
@resolver ||= new_resolver(resolution_base)
|
|
618
633
|
end
|
|
619
634
|
|
|
620
635
|
def expanded_dependencies
|
|
@@ -632,8 +647,7 @@ module Bundler
|
|
|
632
647
|
@resolution_base ||= begin
|
|
633
648
|
last_resolve = converge_locked_specs
|
|
634
649
|
remove_invalid_platforms!
|
|
635
|
-
|
|
636
|
-
base = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: @unlocking_all || @gems_to_unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms)
|
|
650
|
+
base = new_resolution_base(last_resolve: last_resolve, unlock: @unlocking_all || @gems_to_unlock)
|
|
637
651
|
base = additional_base_requirements_to_prevent_downgrades(base)
|
|
638
652
|
base = additional_base_requirements_to_force_updates(base)
|
|
639
653
|
base
|
|
@@ -645,20 +659,12 @@ module Bundler
|
|
|
645
659
|
end
|
|
646
660
|
|
|
647
661
|
def materialize(dependencies)
|
|
648
|
-
# Tracks potential endless loops trying to re-resolve.
|
|
649
|
-
# TODO: Remove as dead code if not reports are received in a while
|
|
650
|
-
incorrect_spec = nil
|
|
651
|
-
|
|
652
662
|
specs = begin
|
|
653
663
|
resolve.materialize(dependencies)
|
|
654
664
|
rescue IncorrectLockfileDependencies => e
|
|
655
665
|
raise if Bundler.frozen_bundle?
|
|
656
666
|
|
|
657
|
-
|
|
658
|
-
raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec
|
|
659
|
-
|
|
660
|
-
incorrect_spec = spec
|
|
661
|
-
reresolve_without([spec])
|
|
667
|
+
reresolve_without([e.spec])
|
|
662
668
|
retry
|
|
663
669
|
end
|
|
664
670
|
|
|
@@ -740,7 +746,6 @@ module Bundler
|
|
|
740
746
|
def start_resolution
|
|
741
747
|
local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(Bundler.local_platform)
|
|
742
748
|
@platforms << Bundler.local_platform if local_platform_needed_for_resolvability
|
|
743
|
-
add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby"
|
|
744
749
|
|
|
745
750
|
result = SpecSet.new(resolver.start)
|
|
746
751
|
|
|
@@ -772,7 +777,7 @@ module Bundler
|
|
|
772
777
|
end
|
|
773
778
|
|
|
774
779
|
def precompute_source_requirements_for_indirect_dependencies?
|
|
775
|
-
sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
|
|
780
|
+
sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
|
|
776
781
|
end
|
|
777
782
|
|
|
778
783
|
def current_platform_locked?
|
|
@@ -848,6 +853,7 @@ module Bundler
|
|
|
848
853
|
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
|
|
849
854
|
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
|
|
850
855
|
[@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
|
|
856
|
+
[@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
|
|
851
857
|
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
|
|
852
858
|
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
|
|
853
859
|
].select(&:first).map(&:last).join(", ")
|
|
@@ -907,13 +913,23 @@ module Bundler
|
|
|
907
913
|
@locked_spec_with_invalid_deps = nil
|
|
908
914
|
@locked_spec_with_missing_deps = nil
|
|
909
915
|
@locked_spec_with_missing_checksums = nil
|
|
916
|
+
@locked_spec_with_empty_checksums = nil
|
|
910
917
|
|
|
911
918
|
missing_deps = []
|
|
912
919
|
missing_checksums = []
|
|
920
|
+
empty_checksums = []
|
|
913
921
|
invalid = []
|
|
914
922
|
|
|
915
923
|
@locked_specs.each do |s|
|
|
916
|
-
|
|
924
|
+
if @locked_checksums
|
|
925
|
+
checksum_store = s.source.checksum_store
|
|
926
|
+
|
|
927
|
+
if checksum_store.missing?(s)
|
|
928
|
+
missing_checksums << s
|
|
929
|
+
elsif checksum_store.empty?(s)
|
|
930
|
+
empty_checksums << s
|
|
931
|
+
end
|
|
932
|
+
end
|
|
917
933
|
|
|
918
934
|
validation = @locked_specs.validate_deps(s)
|
|
919
935
|
|
|
@@ -922,6 +938,7 @@ module Bundler
|
|
|
922
938
|
end
|
|
923
939
|
|
|
924
940
|
@locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
|
|
941
|
+
@locked_spec_with_empty_checksums = empty_checksums.first.name if empty_checksums.any?
|
|
925
942
|
|
|
926
943
|
if missing_deps.any?
|
|
927
944
|
@locked_specs.delete(missing_deps)
|
|
@@ -951,7 +968,7 @@ module Bundler
|
|
|
951
968
|
sources.all_sources.each do |source|
|
|
952
969
|
# has to be done separately, because we want to keep the locked checksum
|
|
953
970
|
# store for a source, even when doing a full update
|
|
954
|
-
if @locked_checksums && @locked_gems && locked_source = @
|
|
971
|
+
if @locked_checksums && @locked_gems && locked_source = @originally_locked_sources.find {|s| s == source && !s.equal?(source) }
|
|
955
972
|
source.checksum_store.merge!(locked_source.checksum_store)
|
|
956
973
|
end
|
|
957
974
|
# If the source is unlockable and the current command allows an unlock of
|
|
@@ -972,10 +989,11 @@ module Bundler
|
|
|
972
989
|
@missing_lockfile_dep = nil
|
|
973
990
|
@changed_dependencies = []
|
|
974
991
|
|
|
975
|
-
|
|
992
|
+
@dependencies.each do |dep|
|
|
976
993
|
if dep.source
|
|
977
994
|
dep.source = sources.get(dep.source)
|
|
978
995
|
end
|
|
996
|
+
next unless relevant_deps?(dep)
|
|
979
997
|
|
|
980
998
|
name = dep.name
|
|
981
999
|
|
|
@@ -1033,6 +1051,8 @@ module Bundler
|
|
|
1033
1051
|
|
|
1034
1052
|
specs.each do |s|
|
|
1035
1053
|
name = s.name
|
|
1054
|
+
next if @gems_to_unlock.include?(name)
|
|
1055
|
+
|
|
1036
1056
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
|
1037
1057
|
lockfile_source = s.source
|
|
1038
1058
|
|
|
@@ -1046,12 +1066,13 @@ module Bundler
|
|
|
1046
1066
|
|
|
1047
1067
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
|
1048
1068
|
s.source = replacement_source || default_source
|
|
1069
|
+
next if s.source_changed?
|
|
1049
1070
|
|
|
1050
1071
|
source = s.source
|
|
1051
1072
|
next if @sources_to_unlock.include?(source.name)
|
|
1052
1073
|
|
|
1053
1074
|
# Path sources have special logic
|
|
1054
|
-
if source.
|
|
1075
|
+
if source.is_a?(Source::Path)
|
|
1055
1076
|
new_spec = source.specs[s].first
|
|
1056
1077
|
if new_spec
|
|
1057
1078
|
s.runtime_dependencies.replace(new_spec.runtime_dependencies)
|
|
@@ -1131,9 +1152,9 @@ module Bundler
|
|
|
1131
1152
|
end
|
|
1132
1153
|
|
|
1133
1154
|
def additional_base_requirements_to_prevent_downgrades(resolution_base)
|
|
1134
|
-
return resolution_base unless @locked_gems
|
|
1155
|
+
return resolution_base unless @locked_gems
|
|
1135
1156
|
@originally_locked_specs.each do |locked_spec|
|
|
1136
|
-
next if locked_spec.source.is_a?(Source::Path)
|
|
1157
|
+
next if locked_spec.source.is_a?(Source::Path) || locked_spec.source_changed?
|
|
1137
1158
|
|
|
1138
1159
|
name = locked_spec.name
|
|
1139
1160
|
next if @changed_dependencies.include?(name)
|
|
@@ -1145,7 +1166,7 @@ module Bundler
|
|
|
1145
1166
|
|
|
1146
1167
|
def additional_base_requirements_to_force_updates(resolution_base)
|
|
1147
1168
|
return resolution_base if @explicit_unlocks.empty?
|
|
1148
|
-
full_update =
|
|
1169
|
+
full_update = SpecSet.new(new_resolver_for_full_update.start)
|
|
1149
1170
|
@explicit_unlocks.each do |name|
|
|
1150
1171
|
version = full_update.version_for(name)
|
|
1151
1172
|
resolution_base.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
|
|
@@ -1153,17 +1174,6 @@ module Bundler
|
|
|
1153
1174
|
resolution_base
|
|
1154
1175
|
end
|
|
1155
1176
|
|
|
1156
|
-
def dup_for_full_unlock
|
|
1157
|
-
unlocked_definition = self.class.new(@lockfile, @dependencies, @sources, true, @ruby_version, @optional_groups, @gemfiles)
|
|
1158
|
-
unlocked_definition.source_requirements = source_requirements
|
|
1159
|
-
unlocked_definition.gem_version_promoter.tap do |gvp|
|
|
1160
|
-
gvp.level = gem_version_promoter.level
|
|
1161
|
-
gvp.strict = gem_version_promoter.strict
|
|
1162
|
-
gvp.pre = gem_version_promoter.pre
|
|
1163
|
-
end
|
|
1164
|
-
unlocked_definition
|
|
1165
|
-
end
|
|
1166
|
-
|
|
1167
1177
|
def remove_invalid_platforms!
|
|
1168
1178
|
return if Bundler.frozen_bundle?
|
|
1169
1179
|
|
|
@@ -1182,5 +1192,22 @@ module Bundler
|
|
|
1182
1192
|
def source_map
|
|
1183
1193
|
@source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
|
|
1184
1194
|
end
|
|
1195
|
+
|
|
1196
|
+
def new_resolver_for_full_update
|
|
1197
|
+
new_resolver(unlocked_resolution_base)
|
|
1198
|
+
end
|
|
1199
|
+
|
|
1200
|
+
def unlocked_resolution_base
|
|
1201
|
+
new_resolution_base(last_resolve: SpecSet.new([]), unlock: true)
|
|
1202
|
+
end
|
|
1203
|
+
|
|
1204
|
+
def new_resolution_base(last_resolve:, unlock:)
|
|
1205
|
+
new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms
|
|
1206
|
+
Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, locked_specs: @originally_locked_specs, unlock: unlock, prerelease: gem_version_promoter.pre?, prefer_local: @prefer_local, new_platforms: new_resolution_platforms)
|
|
1207
|
+
end
|
|
1208
|
+
|
|
1209
|
+
def new_resolver(base)
|
|
1210
|
+
Resolver.new(base, gem_version_promoter, @most_specific_locked_platform)
|
|
1211
|
+
end
|
|
1185
1212
|
end
|
|
1186
1213
|
end
|
data/lib/bundler/deployment.rb
CHANGED
|
@@ -1,69 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "shared_helpers"
|
|
4
|
-
Bundler::SharedHelpers.
|
|
4
|
+
Bundler::SharedHelpers.feature_removed! "Bundler no longer integrates with " \
|
|
5
5
|
"Capistrano, but Capistrano provides its own integration with " \
|
|
6
6
|
"Bundler via the capistrano-bundler gem. Use it instead."
|
|
7
|
-
|
|
8
|
-
module Bundler
|
|
9
|
-
class Deployment
|
|
10
|
-
def self.define_task(context, task_method = :task, opts = {})
|
|
11
|
-
if defined?(Capistrano) && context.is_a?(Capistrano::Configuration)
|
|
12
|
-
context_name = "capistrano"
|
|
13
|
-
role_default = "{:except => {:no_release => true}}"
|
|
14
|
-
error_type = ::Capistrano::CommandError
|
|
15
|
-
else
|
|
16
|
-
context_name = "vlad"
|
|
17
|
-
role_default = "[:app]"
|
|
18
|
-
error_type = ::Rake::CommandFailedError
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
roles = context.fetch(:bundle_roles, false)
|
|
22
|
-
opts[:roles] = roles if roles
|
|
23
|
-
|
|
24
|
-
context.send :namespace, :bundle do
|
|
25
|
-
send :desc, <<-DESC
|
|
26
|
-
Install the current Bundler environment. By default, gems will be \
|
|
27
|
-
installed to the shared/bundle path. Gems in the development and \
|
|
28
|
-
test group will not be installed. The install command is executed \
|
|
29
|
-
with the --deployment and --quiet flags. If the bundle cmd cannot \
|
|
30
|
-
be found then you can override the bundle_cmd variable to specify \
|
|
31
|
-
which one it should use. The base path to the app is fetched from \
|
|
32
|
-
the :latest_release variable. Set it for custom deploy layouts.
|
|
33
|
-
|
|
34
|
-
You can override any of these defaults by setting the variables shown below.
|
|
35
|
-
|
|
36
|
-
N.B. bundle_roles must be defined before you require 'bundler/#{context_name}' \
|
|
37
|
-
in your deploy.rb file.
|
|
38
|
-
|
|
39
|
-
set :bundle_gemfile, "Gemfile"
|
|
40
|
-
set :bundle_dir, File.join(fetch(:shared_path), 'bundle')
|
|
41
|
-
set :bundle_flags, "--deployment --quiet"
|
|
42
|
-
set :bundle_without, [:development, :test]
|
|
43
|
-
set :bundle_with, [:mysql]
|
|
44
|
-
set :bundle_cmd, "bundle" # e.g. "/opt/ruby/bin/bundle"
|
|
45
|
-
set :bundle_roles, #{role_default} # e.g. [:app, :batch]
|
|
46
|
-
DESC
|
|
47
|
-
send task_method, :install, opts do
|
|
48
|
-
bundle_cmd = context.fetch(:bundle_cmd, "bundle")
|
|
49
|
-
bundle_flags = context.fetch(:bundle_flags, "--deployment --quiet")
|
|
50
|
-
bundle_dir = context.fetch(:bundle_dir, File.join(context.fetch(:shared_path), "bundle"))
|
|
51
|
-
bundle_gemfile = context.fetch(:bundle_gemfile, "Gemfile")
|
|
52
|
-
bundle_without = [*context.fetch(:bundle_without, [:development, :test])].compact
|
|
53
|
-
bundle_with = [*context.fetch(:bundle_with, [])].compact
|
|
54
|
-
app_path = context.fetch(:latest_release)
|
|
55
|
-
if app_path.to_s.empty?
|
|
56
|
-
raise error_type.new("Cannot detect current release path - make sure you have deployed at least once.")
|
|
57
|
-
end
|
|
58
|
-
args = ["--gemfile #{File.join(app_path, bundle_gemfile)}"]
|
|
59
|
-
args << "--path #{bundle_dir}" unless bundle_dir.to_s.empty?
|
|
60
|
-
args << bundle_flags.to_s
|
|
61
|
-
args << "--without #{bundle_without.join(" ")}" unless bundle_without.empty?
|
|
62
|
-
args << "--with #{bundle_with.join(" ")}" unless bundle_with.empty?
|
|
63
|
-
|
|
64
|
-
run "cd #{app_path} && #{bundle_cmd} install #{args.join(" ")}"
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
data/lib/bundler/digest.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Bundler
|
|
|
26
26
|
end
|
|
27
27
|
a, b, c, d, e = *words
|
|
28
28
|
(16..79).each do |i|
|
|
29
|
-
w[i] = SHA1_MASK & rotate(
|
|
29
|
+
w[i] = SHA1_MASK & rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)
|
|
30
30
|
end
|
|
31
31
|
0.upto(79) do |i|
|
|
32
32
|
case i
|
data/lib/bundler/dsl.rb
CHANGED
|
@@ -290,7 +290,7 @@ module Bundler
|
|
|
290
290
|
@dependencies.delete(current)
|
|
291
291
|
elsif dep.gemspec_dev_dep?
|
|
292
292
|
return
|
|
293
|
-
elsif current.source != dep.source
|
|
293
|
+
elsif current.source.to_s != dep.source.to_s
|
|
294
294
|
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
|
|
295
295
|
"You specified that #{name} (#{dep.requirement}) should come from " \
|
|
296
296
|
"#{current.source || "an unspecified source"} and #{dep.source}\n"
|
|
@@ -411,7 +411,13 @@ module Bundler
|
|
|
411
411
|
next if VALID_PLATFORMS.include?(p)
|
|
412
412
|
raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
|
|
413
413
|
end
|
|
414
|
-
|
|
414
|
+
|
|
415
|
+
windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
|
|
416
|
+
if windows_platforms.any?
|
|
417
|
+
windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
|
|
418
|
+
removed_message = "Platform #{windows_platforms} has been removed. Please use platform :windows instead."
|
|
419
|
+
Bundler::SharedHelpers.feature_removed! removed_message
|
|
420
|
+
end
|
|
415
421
|
|
|
416
422
|
# Save sources passed in a key
|
|
417
423
|
if opts.key?("source")
|
|
@@ -477,14 +483,10 @@ module Bundler
|
|
|
477
483
|
def normalize_source(source)
|
|
478
484
|
case source
|
|
479
485
|
when :gemcutter, :rubygems, :rubyforge
|
|
480
|
-
message =
|
|
481
|
-
"The source :#{source} is deprecated because HTTP requests are insecure.\n" \
|
|
482
|
-
"Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
|
|
483
486
|
removed_message =
|
|
484
487
|
"The source :#{source} is disallowed because HTTP requests are insecure.\n" \
|
|
485
488
|
"Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
|
|
486
|
-
Bundler::SharedHelpers.
|
|
487
|
-
"http://rubygems.org"
|
|
489
|
+
Bundler::SharedHelpers.feature_removed! removed_message
|
|
488
490
|
when String
|
|
489
491
|
source
|
|
490
492
|
else
|
|
@@ -492,16 +494,6 @@ module Bundler
|
|
|
492
494
|
end
|
|
493
495
|
end
|
|
494
496
|
|
|
495
|
-
def deprecate_legacy_windows_platforms(platforms)
|
|
496
|
-
windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
|
|
497
|
-
return if windows_platforms.empty?
|
|
498
|
-
|
|
499
|
-
windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
|
|
500
|
-
message = "Platform #{windows_platforms} is deprecated. Please use platform :windows instead."
|
|
501
|
-
removed_message = "Platform #{windows_platforms} has been removed. Please use platform :windows instead."
|
|
502
|
-
Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
|
|
503
|
-
end
|
|
504
|
-
|
|
505
497
|
def check_path_source_safety
|
|
506
498
|
return if @sources.global_path_source.nil?
|
|
507
499
|
|
|
@@ -513,7 +505,7 @@ module Bundler
|
|
|
513
505
|
" gem 'rails'\n" \
|
|
514
506
|
" end\n\n"
|
|
515
507
|
|
|
516
|
-
SharedHelpers.
|
|
508
|
+
SharedHelpers.feature_removed! msg.strip
|
|
517
509
|
end
|
|
518
510
|
|
|
519
511
|
def check_rubygems_source_safety
|
|
@@ -521,24 +513,10 @@ module Bundler
|
|
|
521
513
|
end
|
|
522
514
|
|
|
523
515
|
def multiple_global_source_warning
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
raise GemfileEvalError, msg
|
|
529
|
-
else
|
|
530
|
-
message =
|
|
531
|
-
"Your Gemfile contains multiple global sources. " \
|
|
532
|
-
"Using `source` more than once without a block is a security risk, and " \
|
|
533
|
-
"may result in installing unexpected gems. To resolve this warning, use " \
|
|
534
|
-
"a block to indicate which gems should come from the secondary source."
|
|
535
|
-
removed_message =
|
|
536
|
-
"Your Gemfile contains multiple global sources. " \
|
|
537
|
-
"Using `source` more than once without a block is a security risk, and " \
|
|
538
|
-
"may result in installing unexpected gems. To resolve this error, use " \
|
|
539
|
-
"a block to indicate which gems should come from the secondary source."
|
|
540
|
-
Bundler::SharedHelpers.major_deprecation 2, message, removed_message: removed_message
|
|
541
|
-
end
|
|
516
|
+
msg = "This Gemfile contains multiple global sources. " \
|
|
517
|
+
"Each source after the first must include a block to indicate which gems " \
|
|
518
|
+
"should come from that source"
|
|
519
|
+
raise GemfileEvalError, msg
|
|
542
520
|
end
|
|
543
521
|
|
|
544
522
|
class DSLError < GemfileError
|
|
@@ -60,28 +60,6 @@ module Bundler
|
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
# needed for binstubs
|
|
64
|
-
def executables
|
|
65
|
-
if @remote_specification
|
|
66
|
-
@remote_specification.executables
|
|
67
|
-
elsif _local_specification
|
|
68
|
-
_local_specification.executables
|
|
69
|
-
else
|
|
70
|
-
super
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# needed for bundle clean
|
|
75
|
-
def bindir
|
|
76
|
-
if @remote_specification
|
|
77
|
-
@remote_specification.bindir
|
|
78
|
-
elsif _local_specification
|
|
79
|
-
_local_specification.bindir
|
|
80
|
-
else
|
|
81
|
-
super
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
63
|
# needed for post_install_messages during install
|
|
86
64
|
def post_install_message
|
|
87
65
|
if @remote_specification
|
data/lib/bundler/errors.rb
CHANGED
|
@@ -25,6 +25,7 @@ module Bundler
|
|
|
25
25
|
|
|
26
26
|
class GemNotFound < BundlerError; status_code(7); end
|
|
27
27
|
class InstallHookError < BundlerError; status_code(8); end
|
|
28
|
+
class RemovedError < BundlerError; status_code(9); end
|
|
28
29
|
class GemfileNotFound < BundlerError; status_code(10); end
|
|
29
30
|
class GitError < BundlerError; status_code(11); end
|
|
30
31
|
class DeprecatedError < BundlerError; status_code(12); end
|
|
@@ -76,11 +77,6 @@ module Bundler
|
|
|
76
77
|
def mismatch_resolution_instructions
|
|
77
78
|
removable, remote = [@existing, @checksum].partition(&:removable?)
|
|
78
79
|
case removable.size
|
|
79
|
-
when 0
|
|
80
|
-
msg = +"Mismatched checksums each have an authoritative source:\n"
|
|
81
|
-
msg << " 1. #{@existing.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
|
|
82
|
-
msg << " 2. #{@checksum.sources.reject(&:removable?).map(&:to_s).join(" and ")}\n"
|
|
83
|
-
msg << "You may need to alter your Gemfile sources to resolve this issue.\n"
|
|
84
80
|
when 1
|
|
85
81
|
msg = +"If you trust #{remote.first.sources.first}, to resolve this issue you can:\n"
|
|
86
82
|
msg << removable.first.removal_instructions
|