bundler 2.7.0 → 4.0.1
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 +1058 -896
- 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 +10 -85
- 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 +4 -4
- data/lib/bundler/cli.rb +157 -122
- data/lib/bundler/compact_index_client.rb +0 -1
- data/lib/bundler/current_ruby.rb +3 -15
- data/lib/bundler/definition.rb +143 -95
- data/lib/bundler/deployment.rb +1 -64
- data/lib/bundler/digest.rb +1 -1
- data/lib/bundler/dsl.rb +27 -37
- data/lib/bundler/environment_preserver.rb +1 -0
- 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/fetcher/gem_remote_fetcher.rb +6 -0
- data/lib/bundler/friendly_errors.rb +2 -2
- data/lib/bundler/index.rb +0 -7
- data/lib/bundler/inline.rb +9 -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 +39 -46
- data/lib/bundler/man/bundle-config.1.ronn +73 -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 +16 -59
- data/lib/bundler/man/bundle-install.1.ronn +27 -108
- 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 +5 -5
- data/lib/bundler/man/bundle-update.1.ronn +4 -4
- 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 +32 -1
- data/lib/bundler/man/gemfile.5.ronn +28 -0
- 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/runtime.rb +5 -1
- data/lib/bundler/self_manager.rb +1 -1
- data/lib/bundler/settings.rb +9 -27
- data/lib/bundler/shared_helpers.rb +12 -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/Rakefile.tt +5 -0
- 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/lib/newgem.rb.tt +1 -1
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +7 -4
- data/lib/bundler/ui/shell.rb +10 -6
- 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/thor/lib/thor.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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "lockfile_parser"
|
|
4
|
+
require_relative "worker"
|
|
4
5
|
|
|
5
6
|
module Bundler
|
|
6
7
|
class Definition
|
|
@@ -9,6 +10,8 @@ module Bundler
|
|
|
9
10
|
attr_accessor :no_lock
|
|
10
11
|
end
|
|
11
12
|
|
|
13
|
+
attr_writer :lockfile
|
|
14
|
+
|
|
12
15
|
attr_reader(
|
|
13
16
|
:dependencies,
|
|
14
17
|
:locked_checksums,
|
|
@@ -107,6 +110,7 @@ module Bundler
|
|
|
107
110
|
@locked_ruby_version = @locked_gems.ruby_version
|
|
108
111
|
@locked_deps = @locked_gems.dependencies
|
|
109
112
|
@originally_locked_specs = SpecSet.new(@locked_gems.specs)
|
|
113
|
+
@originally_locked_sources = @locked_gems.sources
|
|
110
114
|
@locked_checksums = @locked_gems.checksums
|
|
111
115
|
|
|
112
116
|
if @unlocking_all
|
|
@@ -114,7 +118,16 @@ module Bundler
|
|
|
114
118
|
@locked_sources = []
|
|
115
119
|
else
|
|
116
120
|
@locked_specs = @originally_locked_specs
|
|
117
|
-
@locked_sources = @
|
|
121
|
+
@locked_sources = @originally_locked_sources
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
locked_gem_sources = @originally_locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
|
125
|
+
multisource_lockfile = locked_gem_sources.size == 1 && locked_gem_sources.first.multiple_remotes?
|
|
126
|
+
|
|
127
|
+
if multisource_lockfile
|
|
128
|
+
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."
|
|
129
|
+
|
|
130
|
+
Bundler::SharedHelpers.feature_removed! msg
|
|
118
131
|
end
|
|
119
132
|
else
|
|
120
133
|
@locked_gems = nil
|
|
@@ -123,22 +136,10 @@ module Bundler
|
|
|
123
136
|
@platforms = []
|
|
124
137
|
@locked_deps = {}
|
|
125
138
|
@locked_specs = SpecSet.new([])
|
|
126
|
-
@originally_locked_specs = @locked_specs
|
|
127
139
|
@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)
|
|
140
|
+
@originally_locked_specs = @locked_specs
|
|
141
|
+
@originally_locked_sources = @locked_sources
|
|
142
|
+
@locked_checksums = Bundler.settings[:lockfile_checksums]
|
|
142
143
|
end
|
|
143
144
|
|
|
144
145
|
@unlocking_ruby ||= if @ruby_version && locked_ruby_version_object
|
|
@@ -189,12 +190,14 @@ module Bundler
|
|
|
189
190
|
def setup_domain!(options = {})
|
|
190
191
|
prefer_local! if options[:"prefer-local"]
|
|
191
192
|
|
|
193
|
+
sources.cached!
|
|
194
|
+
|
|
192
195
|
if options[:add_checksums] || (!options[:local] && install_needed?)
|
|
193
|
-
|
|
196
|
+
sources.remote!
|
|
194
197
|
true
|
|
195
198
|
else
|
|
196
199
|
Bundler.settings.set_command_option(:jobs, 1) unless install_needed? # to avoid the overhead of Bundler::Worker
|
|
197
|
-
|
|
200
|
+
sources.local!
|
|
198
201
|
false
|
|
199
202
|
end
|
|
200
203
|
end
|
|
@@ -282,12 +285,17 @@ module Bundler
|
|
|
282
285
|
end
|
|
283
286
|
|
|
284
287
|
def filter_relevant(dependencies)
|
|
285
|
-
platforms_array = [Bundler.generic_local_platform].freeze
|
|
286
288
|
dependencies.select do |d|
|
|
287
|
-
|
|
289
|
+
relevant_deps?(d)
|
|
288
290
|
end
|
|
289
291
|
end
|
|
290
292
|
|
|
293
|
+
def relevant_deps?(dep)
|
|
294
|
+
platforms_array = [Bundler.generic_local_platform].freeze
|
|
295
|
+
|
|
296
|
+
dep.should_include? && !dep.gem_platforms(platforms_array).empty?
|
|
297
|
+
end
|
|
298
|
+
|
|
291
299
|
def locked_dependencies
|
|
292
300
|
@locked_deps.values
|
|
293
301
|
end
|
|
@@ -367,12 +375,50 @@ module Bundler
|
|
|
367
375
|
|
|
368
376
|
msg = "`Definition#lock` was passed a target file argument. #{suggestion}"
|
|
369
377
|
|
|
370
|
-
Bundler::SharedHelpers.
|
|
378
|
+
Bundler::SharedHelpers.feature_removed! msg
|
|
371
379
|
end
|
|
372
380
|
|
|
373
381
|
write_lock(target_lockfile, preserve_unknown_sections)
|
|
374
382
|
end
|
|
375
383
|
|
|
384
|
+
def write_lock(file, preserve_unknown_sections)
|
|
385
|
+
return if Definition.no_lock || !lockfile || file.nil?
|
|
386
|
+
|
|
387
|
+
contents = to_lock
|
|
388
|
+
|
|
389
|
+
# Convert to \r\n if the existing lock has them
|
|
390
|
+
# i.e., Windows with `git config core.autocrlf=true`
|
|
391
|
+
contents.gsub!(/\n/, "\r\n") if @lockfile_contents.match?("\r\n")
|
|
392
|
+
|
|
393
|
+
if @locked_bundler_version
|
|
394
|
+
locked_major = @locked_bundler_version.segments.first
|
|
395
|
+
current_major = bundler_version_to_lock.segments.first
|
|
396
|
+
|
|
397
|
+
updating_major = locked_major < current_major
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
preserve_unknown_sections ||= !updating_major && (Bundler.frozen_bundle? || !(unlocking? || @unlocking_bundler))
|
|
401
|
+
|
|
402
|
+
if File.exist?(file) && lockfiles_equal?(@lockfile_contents, contents, preserve_unknown_sections)
|
|
403
|
+
return if Bundler.frozen_bundle?
|
|
404
|
+
SharedHelpers.filesystem_access(file) { FileUtils.touch(file) }
|
|
405
|
+
return
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
if Bundler.frozen_bundle?
|
|
409
|
+
Bundler.ui.error "Cannot write a changed lockfile while frozen."
|
|
410
|
+
return
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
begin
|
|
414
|
+
SharedHelpers.filesystem_access(file) do |p|
|
|
415
|
+
File.open(p, "wb") {|f| f.puts(contents) }
|
|
416
|
+
end
|
|
417
|
+
rescue ReadOnlyFileSystemError
|
|
418
|
+
raise ProductionError, lockfile_changes_summary("file system is read-only")
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
376
422
|
def locked_ruby_version
|
|
377
423
|
return unless ruby_version
|
|
378
424
|
if @unlocking_ruby || !@locked_ruby_version
|
|
@@ -492,14 +538,25 @@ module Bundler
|
|
|
492
538
|
@unlocking
|
|
493
539
|
end
|
|
494
540
|
|
|
495
|
-
attr_writer :source_requirements
|
|
496
|
-
|
|
497
541
|
def add_checksums
|
|
542
|
+
require "rubygems/package"
|
|
543
|
+
|
|
498
544
|
@locked_checksums = true
|
|
499
545
|
|
|
500
546
|
setup_domain!(add_checksums: true)
|
|
501
547
|
|
|
502
|
-
|
|
548
|
+
# force materialization to real specifications, so that checksums are fetched
|
|
549
|
+
specs.each do |spec|
|
|
550
|
+
next unless spec.source.is_a?(Bundler::Source::Rubygems)
|
|
551
|
+
# Checksum was fetched from the compact index API.
|
|
552
|
+
next if !spec.source.checksum_store.missing?(spec) && !spec.source.checksum_store.empty?(spec)
|
|
553
|
+
# The gem isn't installed, can't compute the checksum.
|
|
554
|
+
next unless spec.loaded_from
|
|
555
|
+
|
|
556
|
+
package = Gem::Package.new(spec.source.cached_built_in_gem(spec))
|
|
557
|
+
checksum = Checksum.from_gem_package(package)
|
|
558
|
+
spec.source.checksum_store.register(spec, checksum)
|
|
559
|
+
end
|
|
503
560
|
end
|
|
504
561
|
|
|
505
562
|
private
|
|
@@ -533,7 +590,7 @@ module Bundler
|
|
|
533
590
|
|
|
534
591
|
return unless added.any? || deleted.any? || changed.any? || resolve_needed?
|
|
535
592
|
|
|
536
|
-
msg = String.new("#{change_reason.
|
|
593
|
+
msg = String.new("#{change_reason[0].upcase}#{change_reason[1..-1].strip}, but ")
|
|
537
594
|
msg << "the lockfile " unless msg.start_with?("Your lockfile")
|
|
538
595
|
msg << "can't be updated because #{update_refused_reason}"
|
|
539
596
|
msg << "\n\nYou have added to the Gemfile:\n" << added.join("\n") if added.any?
|
|
@@ -559,6 +616,7 @@ module Bundler
|
|
|
559
616
|
@missing_lockfile_dep ||
|
|
560
617
|
@unlocking_bundler ||
|
|
561
618
|
@locked_spec_with_missing_checksums ||
|
|
619
|
+
@locked_spec_with_empty_checksums ||
|
|
562
620
|
@locked_spec_with_missing_deps ||
|
|
563
621
|
@locked_spec_with_invalid_deps
|
|
564
622
|
end
|
|
@@ -575,46 +633,8 @@ module Bundler
|
|
|
575
633
|
lockfile && File.exist?(lockfile)
|
|
576
634
|
end
|
|
577
635
|
|
|
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
636
|
def resolver
|
|
617
|
-
@resolver ||=
|
|
637
|
+
@resolver ||= new_resolver(resolution_base)
|
|
618
638
|
end
|
|
619
639
|
|
|
620
640
|
def expanded_dependencies
|
|
@@ -632,8 +652,7 @@ module Bundler
|
|
|
632
652
|
@resolution_base ||= begin
|
|
633
653
|
last_resolve = converge_locked_specs
|
|
634
654
|
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)
|
|
655
|
+
base = new_resolution_base(last_resolve: last_resolve, unlock: @unlocking_all || @gems_to_unlock)
|
|
637
656
|
base = additional_base_requirements_to_prevent_downgrades(base)
|
|
638
657
|
base = additional_base_requirements_to_force_updates(base)
|
|
639
658
|
base
|
|
@@ -645,20 +664,12 @@ module Bundler
|
|
|
645
664
|
end
|
|
646
665
|
|
|
647
666
|
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
667
|
specs = begin
|
|
653
668
|
resolve.materialize(dependencies)
|
|
654
669
|
rescue IncorrectLockfileDependencies => e
|
|
655
670
|
raise if Bundler.frozen_bundle?
|
|
656
671
|
|
|
657
|
-
|
|
658
|
-
raise "Infinite loop while fixing lockfile dependencies" if incorrect_spec == spec
|
|
659
|
-
|
|
660
|
-
incorrect_spec = spec
|
|
661
|
-
reresolve_without([spec])
|
|
672
|
+
reresolve_without([e.spec])
|
|
662
673
|
retry
|
|
663
674
|
end
|
|
664
675
|
|
|
@@ -740,7 +751,6 @@ module Bundler
|
|
|
740
751
|
def start_resolution
|
|
741
752
|
local_platform_needed_for_resolvability = @most_specific_non_local_locked_platform && !@platforms.include?(Bundler.local_platform)
|
|
742
753
|
@platforms << Bundler.local_platform if local_platform_needed_for_resolvability
|
|
743
|
-
add_platform(Gem::Platform::RUBY) if RUBY_ENGINE == "truffleruby"
|
|
744
754
|
|
|
745
755
|
result = SpecSet.new(resolver.start)
|
|
746
756
|
|
|
@@ -772,7 +782,7 @@ module Bundler
|
|
|
772
782
|
end
|
|
773
783
|
|
|
774
784
|
def precompute_source_requirements_for_indirect_dependencies?
|
|
775
|
-
sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
|
|
785
|
+
sources.non_global_rubygems_sources.all?(&:dependency_api_available?)
|
|
776
786
|
end
|
|
777
787
|
|
|
778
788
|
def current_platform_locked?
|
|
@@ -848,6 +858,7 @@ module Bundler
|
|
|
848
858
|
[@missing_lockfile_dep, "your lockfile is missing \"#{@missing_lockfile_dep}\""],
|
|
849
859
|
[@unlocking_bundler, "an update to the version of Bundler itself was requested"],
|
|
850
860
|
[@locked_spec_with_missing_checksums, "your lockfile is missing a CHECKSUMS entry for \"#{@locked_spec_with_missing_checksums}\""],
|
|
861
|
+
[@locked_spec_with_empty_checksums, "your lockfile has an empty CHECKSUMS entry for \"#{@locked_spec_with_empty_checksums}\""],
|
|
851
862
|
[@locked_spec_with_missing_deps, "your lockfile includes \"#{@locked_spec_with_missing_deps}\" but not some of its dependencies"],
|
|
852
863
|
[@locked_spec_with_invalid_deps, "your lockfile does not satisfy dependencies of \"#{@locked_spec_with_invalid_deps}\""],
|
|
853
864
|
].select(&:first).map(&:last).join(", ")
|
|
@@ -907,13 +918,23 @@ module Bundler
|
|
|
907
918
|
@locked_spec_with_invalid_deps = nil
|
|
908
919
|
@locked_spec_with_missing_deps = nil
|
|
909
920
|
@locked_spec_with_missing_checksums = nil
|
|
921
|
+
@locked_spec_with_empty_checksums = nil
|
|
910
922
|
|
|
911
923
|
missing_deps = []
|
|
912
924
|
missing_checksums = []
|
|
925
|
+
empty_checksums = []
|
|
913
926
|
invalid = []
|
|
914
927
|
|
|
915
928
|
@locked_specs.each do |s|
|
|
916
|
-
|
|
929
|
+
if @locked_checksums
|
|
930
|
+
checksum_store = s.source.checksum_store
|
|
931
|
+
|
|
932
|
+
if checksum_store.missing?(s)
|
|
933
|
+
missing_checksums << s
|
|
934
|
+
elsif checksum_store.empty?(s)
|
|
935
|
+
empty_checksums << s
|
|
936
|
+
end
|
|
937
|
+
end
|
|
917
938
|
|
|
918
939
|
validation = @locked_specs.validate_deps(s)
|
|
919
940
|
|
|
@@ -922,6 +943,7 @@ module Bundler
|
|
|
922
943
|
end
|
|
923
944
|
|
|
924
945
|
@locked_spec_with_missing_checksums = missing_checksums.first.name if missing_checksums.any?
|
|
946
|
+
@locked_spec_with_empty_checksums = empty_checksums.first.name if empty_checksums.any?
|
|
925
947
|
|
|
926
948
|
if missing_deps.any?
|
|
927
949
|
@locked_specs.delete(missing_deps)
|
|
@@ -951,7 +973,7 @@ module Bundler
|
|
|
951
973
|
sources.all_sources.each do |source|
|
|
952
974
|
# has to be done separately, because we want to keep the locked checksum
|
|
953
975
|
# store for a source, even when doing a full update
|
|
954
|
-
if @locked_checksums && @locked_gems && locked_source = @
|
|
976
|
+
if @locked_checksums && @locked_gems && locked_source = @originally_locked_sources.find {|s| s == source && !s.equal?(source) }
|
|
955
977
|
source.checksum_store.merge!(locked_source.checksum_store)
|
|
956
978
|
end
|
|
957
979
|
# If the source is unlockable and the current command allows an unlock of
|
|
@@ -972,10 +994,11 @@ module Bundler
|
|
|
972
994
|
@missing_lockfile_dep = nil
|
|
973
995
|
@changed_dependencies = []
|
|
974
996
|
|
|
975
|
-
|
|
997
|
+
@dependencies.each do |dep|
|
|
976
998
|
if dep.source
|
|
977
999
|
dep.source = sources.get(dep.source)
|
|
978
1000
|
end
|
|
1001
|
+
next unless relevant_deps?(dep)
|
|
979
1002
|
|
|
980
1003
|
name = dep.name
|
|
981
1004
|
|
|
@@ -1033,6 +1056,8 @@ module Bundler
|
|
|
1033
1056
|
|
|
1034
1057
|
specs.each do |s|
|
|
1035
1058
|
name = s.name
|
|
1059
|
+
next if @gems_to_unlock.include?(name)
|
|
1060
|
+
|
|
1036
1061
|
dep = @dependencies.find {|d| s.satisfies?(d) }
|
|
1037
1062
|
lockfile_source = s.source
|
|
1038
1063
|
|
|
@@ -1046,12 +1071,13 @@ module Bundler
|
|
|
1046
1071
|
|
|
1047
1072
|
# Replace the locked dependency's source with the equivalent source from the Gemfile
|
|
1048
1073
|
s.source = replacement_source || default_source
|
|
1074
|
+
next if s.source_changed?
|
|
1049
1075
|
|
|
1050
1076
|
source = s.source
|
|
1051
1077
|
next if @sources_to_unlock.include?(source.name)
|
|
1052
1078
|
|
|
1053
1079
|
# Path sources have special logic
|
|
1054
|
-
if source.
|
|
1080
|
+
if source.is_a?(Source::Path)
|
|
1055
1081
|
new_spec = source.specs[s].first
|
|
1056
1082
|
if new_spec
|
|
1057
1083
|
s.runtime_dependencies.replace(new_spec.runtime_dependencies)
|
|
@@ -1079,7 +1105,23 @@ module Bundler
|
|
|
1079
1105
|
@source_requirements ||= find_source_requirements
|
|
1080
1106
|
end
|
|
1081
1107
|
|
|
1108
|
+
def preload_git_source_worker
|
|
1109
|
+
@preload_git_source_worker ||= Bundler::Worker.new(5, "Git source preloading", ->(source, _) { source.specs })
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
def preload_git_sources
|
|
1113
|
+
sources.git_sources.each {|source| preload_git_source_worker.enq(source) }
|
|
1114
|
+
ensure
|
|
1115
|
+
preload_git_source_worker.stop
|
|
1116
|
+
end
|
|
1117
|
+
|
|
1082
1118
|
def find_source_requirements
|
|
1119
|
+
if Gem.ruby_version >= Gem::Version.new("3.3")
|
|
1120
|
+
# Ruby 3.2 has a bug that incorrectly triggers a circular dependency warning. This version will continue to
|
|
1121
|
+
# fetch git repositories one by one.
|
|
1122
|
+
preload_git_sources
|
|
1123
|
+
end
|
|
1124
|
+
|
|
1083
1125
|
# Record the specs available in each gem's source, so that those
|
|
1084
1126
|
# specs will be available later when the resolver knows where to
|
|
1085
1127
|
# look for that gemspec (or its dependencies)
|
|
@@ -1131,9 +1173,9 @@ module Bundler
|
|
|
1131
1173
|
end
|
|
1132
1174
|
|
|
1133
1175
|
def additional_base_requirements_to_prevent_downgrades(resolution_base)
|
|
1134
|
-
return resolution_base unless @locked_gems
|
|
1176
|
+
return resolution_base unless @locked_gems
|
|
1135
1177
|
@originally_locked_specs.each do |locked_spec|
|
|
1136
|
-
next if locked_spec.source.is_a?(Source::Path)
|
|
1178
|
+
next if locked_spec.source.is_a?(Source::Path) || locked_spec.source_changed?
|
|
1137
1179
|
|
|
1138
1180
|
name = locked_spec.name
|
|
1139
1181
|
next if @changed_dependencies.include?(name)
|
|
@@ -1145,7 +1187,7 @@ module Bundler
|
|
|
1145
1187
|
|
|
1146
1188
|
def additional_base_requirements_to_force_updates(resolution_base)
|
|
1147
1189
|
return resolution_base if @explicit_unlocks.empty?
|
|
1148
|
-
full_update =
|
|
1190
|
+
full_update = SpecSet.new(new_resolver_for_full_update.start)
|
|
1149
1191
|
@explicit_unlocks.each do |name|
|
|
1150
1192
|
version = full_update.version_for(name)
|
|
1151
1193
|
resolution_base.base_requirements[name] = Gem::Requirement.new("= #{version}") if version
|
|
@@ -1153,17 +1195,6 @@ module Bundler
|
|
|
1153
1195
|
resolution_base
|
|
1154
1196
|
end
|
|
1155
1197
|
|
|
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
1198
|
def remove_invalid_platforms!
|
|
1168
1199
|
return if Bundler.frozen_bundle?
|
|
1169
1200
|
|
|
@@ -1182,5 +1213,22 @@ module Bundler
|
|
|
1182
1213
|
def source_map
|
|
1183
1214
|
@source_map ||= SourceMap.new(sources, dependencies, @locked_specs)
|
|
1184
1215
|
end
|
|
1216
|
+
|
|
1217
|
+
def new_resolver_for_full_update
|
|
1218
|
+
new_resolver(unlocked_resolution_base)
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
def unlocked_resolution_base
|
|
1222
|
+
new_resolution_base(last_resolve: SpecSet.new([]), unlock: true)
|
|
1223
|
+
end
|
|
1224
|
+
|
|
1225
|
+
def new_resolution_base(last_resolve:, unlock:)
|
|
1226
|
+
new_resolution_platforms = @current_platform_missing ? @new_platforms + [Bundler.local_platform] : @new_platforms
|
|
1227
|
+
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)
|
|
1228
|
+
end
|
|
1229
|
+
|
|
1230
|
+
def new_resolver(base)
|
|
1231
|
+
Resolver.new(base, gem_version_promoter, @most_specific_locked_platform)
|
|
1232
|
+
end
|
|
1185
1233
|
end
|
|
1186
1234
|
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
|
@@ -9,8 +9,9 @@ module Bundler
|
|
|
9
9
|
|
|
10
10
|
def self.evaluate(gemfile, lockfile, unlock)
|
|
11
11
|
builder = new
|
|
12
|
+
builder.lockfile(lockfile)
|
|
12
13
|
builder.eval_gemfile(gemfile)
|
|
13
|
-
builder.to_definition(
|
|
14
|
+
builder.to_definition(builder.lockfile_path, unlock)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
VALID_PLATFORMS = Bundler::CurrentRuby::PLATFORM_MAP.keys.freeze
|
|
@@ -38,6 +39,7 @@ module Bundler
|
|
|
38
39
|
@gemspecs = []
|
|
39
40
|
@gemfile = nil
|
|
40
41
|
@gemfiles = []
|
|
42
|
+
@lockfile = nil
|
|
41
43
|
add_git_sources
|
|
42
44
|
end
|
|
43
45
|
|
|
@@ -101,6 +103,15 @@ module Bundler
|
|
|
101
103
|
add_dependency(name, version, options)
|
|
102
104
|
end
|
|
103
105
|
|
|
106
|
+
# For usage in Dsl.evaluate, since lockfile is used as part of the Gemfile.
|
|
107
|
+
def lockfile_path
|
|
108
|
+
@lockfile
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def lockfile(file)
|
|
112
|
+
@lockfile = file
|
|
113
|
+
end
|
|
114
|
+
|
|
104
115
|
def source(source, *args, &blk)
|
|
105
116
|
options = args.last.is_a?(Hash) ? args.pop.dup : {}
|
|
106
117
|
options = normalize_hash(options)
|
|
@@ -175,6 +186,7 @@ module Bundler
|
|
|
175
186
|
|
|
176
187
|
def to_definition(lockfile, unlock)
|
|
177
188
|
check_primary_source_safety
|
|
189
|
+
lockfile = @lockfile unless @lockfile.nil?
|
|
178
190
|
Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version, @optional_groups, @gemfiles)
|
|
179
191
|
end
|
|
180
192
|
|
|
@@ -290,7 +302,7 @@ module Bundler
|
|
|
290
302
|
@dependencies.delete(current)
|
|
291
303
|
elsif dep.gemspec_dev_dep?
|
|
292
304
|
return
|
|
293
|
-
elsif current.source != dep.source
|
|
305
|
+
elsif current.source.to_s != dep.source.to_s
|
|
294
306
|
raise GemfileError, "You cannot specify the same gem twice coming from different sources.\n" \
|
|
295
307
|
"You specified that #{name} (#{dep.requirement}) should come from " \
|
|
296
308
|
"#{current.source || "an unspecified source"} and #{dep.source}\n"
|
|
@@ -411,7 +423,13 @@ module Bundler
|
|
|
411
423
|
next if VALID_PLATFORMS.include?(p)
|
|
412
424
|
raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
|
|
413
425
|
end
|
|
414
|
-
|
|
426
|
+
|
|
427
|
+
windows_platforms = platforms.select {|pl| pl.to_s.match?(/mingw|mswin/) }
|
|
428
|
+
if windows_platforms.any?
|
|
429
|
+
windows_platforms = windows_platforms.map! {|pl| ":#{pl}" }.join(", ")
|
|
430
|
+
deprecated_message = "Platform #{windows_platforms} will be removed in the future. Please use platform :windows instead."
|
|
431
|
+
Bundler::SharedHelpers.feature_deprecated! deprecated_message
|
|
432
|
+
end
|
|
415
433
|
|
|
416
434
|
# Save sources passed in a key
|
|
417
435
|
if opts.key?("source")
|
|
@@ -477,14 +495,10 @@ module Bundler
|
|
|
477
495
|
def normalize_source(source)
|
|
478
496
|
case source
|
|
479
497
|
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
498
|
removed_message =
|
|
484
499
|
"The source :#{source} is disallowed because HTTP requests are insecure.\n" \
|
|
485
500
|
"Please change your source to 'https://rubygems.org' if possible, or 'http://rubygems.org' if not."
|
|
486
|
-
Bundler::SharedHelpers.
|
|
487
|
-
"http://rubygems.org"
|
|
501
|
+
Bundler::SharedHelpers.feature_removed! removed_message
|
|
488
502
|
when String
|
|
489
503
|
source
|
|
490
504
|
else
|
|
@@ -492,16 +506,6 @@ module Bundler
|
|
|
492
506
|
end
|
|
493
507
|
end
|
|
494
508
|
|
|
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
509
|
def check_path_source_safety
|
|
506
510
|
return if @sources.global_path_source.nil?
|
|
507
511
|
|
|
@@ -513,7 +517,7 @@ module Bundler
|
|
|
513
517
|
" gem 'rails'\n" \
|
|
514
518
|
" end\n\n"
|
|
515
519
|
|
|
516
|
-
SharedHelpers.
|
|
520
|
+
SharedHelpers.feature_removed! msg.strip
|
|
517
521
|
end
|
|
518
522
|
|
|
519
523
|
def check_rubygems_source_safety
|
|
@@ -521,24 +525,10 @@ module Bundler
|
|
|
521
525
|
end
|
|
522
526
|
|
|
523
527
|
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
|
|
528
|
+
msg = "This Gemfile contains multiple global sources. " \
|
|
529
|
+
"Each source after the first must include a block to indicate which gems " \
|
|
530
|
+
"should come from that source"
|
|
531
|
+
raise GemfileEvalError, msg
|
|
542
532
|
end
|
|
543
533
|
|
|
544
534
|
class DSLError < GemfileError
|