summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2021-06-14 12:55:03 +0900
committernagachika <nagachika@ruby-lang.org>2021-07-07 10:03:15 +0900
commitd4b4281959d2a9846d766253b5e21e8158948aa7 (patch)
tree64f45489cd78b781b682e2a94c16a6829b8f2edd /lib
parentdd28c03d5fd7a82d1b694a9c2332a55dab81add9 (diff)
Merge RubyGems-3.2.18 and Bundler-2.2.18
Diffstat (limited to 'lib')
-rw-r--r--lib/bundler.rb1
-rw-r--r--lib/bundler/bundler.gemspec5
-rw-r--r--lib/bundler/cli.rb46
-rw-r--r--lib/bundler/cli/outdated.rb17
-rw-r--r--lib/bundler/definition.rb89
-rw-r--r--lib/bundler/feature_flag.rb1
-rw-r--r--lib/bundler/friendly_errors.rb2
-rw-r--r--lib/bundler/index.rb3
-rw-r--r--lib/bundler/man/bundle-add.12
-rw-r--r--lib/bundler/man/bundle-binstubs.12
-rw-r--r--lib/bundler/man/bundle-cache.12
-rw-r--r--lib/bundler/man/bundle-check.12
-rw-r--r--lib/bundler/man/bundle-clean.12
-rw-r--r--lib/bundler/man/bundle-config.18
-rw-r--r--lib/bundler/man/bundle-config.1.ronn8
-rw-r--r--lib/bundler/man/bundle-doctor.12
-rw-r--r--lib/bundler/man/bundle-exec.12
-rw-r--r--lib/bundler/man/bundle-gem.12
-rw-r--r--lib/bundler/man/bundle-info.12
-rw-r--r--lib/bundler/man/bundle-init.12
-rw-r--r--lib/bundler/man/bundle-inject.12
-rw-r--r--lib/bundler/man/bundle-install.12
-rw-r--r--lib/bundler/man/bundle-list.12
-rw-r--r--lib/bundler/man/bundle-lock.12
-rw-r--r--lib/bundler/man/bundle-open.12
-rw-r--r--lib/bundler/man/bundle-outdated.12
-rw-r--r--lib/bundler/man/bundle-platform.12
-rw-r--r--lib/bundler/man/bundle-pristine.12
-rw-r--r--lib/bundler/man/bundle-remove.12
-rw-r--r--lib/bundler/man/bundle-show.12
-rw-r--r--lib/bundler/man/bundle-update.12
-rw-r--r--lib/bundler/man/bundle-viz.12
-rw-r--r--lib/bundler/man/bundle.12
-rw-r--r--lib/bundler/man/gemfile.52
-rw-r--r--lib/bundler/plugin/api/source.rb14
-rw-r--r--lib/bundler/resolver.rb109
-rw-r--r--lib/bundler/resolver/spec_group.rb24
-rw-r--r--lib/bundler/rubygems_ext.rb4
-rw-r--r--lib/bundler/settings.rb1
-rw-r--r--lib/bundler/source.rb9
-rw-r--r--lib/bundler/source/rubygems.rb19
-rw-r--r--lib/bundler/source/rubygems_aggregate.rb64
-rw-r--r--lib/bundler/source_list.rb39
-rw-r--r--lib/bundler/source_map.rb58
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt2
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/rubygems.rb2
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb8
-rw-r--r--lib/rubygems/specification.rb2
-rw-r--r--lib/rubygems/test_case.rb120
50 files changed, 377 insertions, 328 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index d370d8a53a..b2363a25f4 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -69,6 +69,7 @@ module Bundler
autoload :SharedHelpers, File.expand_path("bundler/shared_helpers", __dir__)
autoload :Source, File.expand_path("bundler/source", __dir__)
autoload :SourceList, File.expand_path("bundler/source_list", __dir__)
+ autoload :SourceMap, File.expand_path("bundler/source_map", __dir__)
autoload :SpecSet, File.expand_path("bundler/spec_set", __dir__)
autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__)
autoload :UI, File.expand_path("bundler/ui", __dir__)
diff --git a/lib/bundler/bundler.gemspec b/lib/bundler/bundler.gemspec
index f6cb02cea2..1a2ced54d3 100644
--- a/lib/bundler/bundler.gemspec
+++ b/lib/bundler/bundler.gemspec
@@ -34,13 +34,12 @@ Gem::Specification.new do |s|
s.required_ruby_version = ">= 2.3.0"
s.required_rubygems_version = ">= 2.5.2"
- s.files = Dir.glob("{lib,exe}/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
+ s.files = Dir.glob("lib/bundler{.rb,/**/*}", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
- # Include the CHANGELOG.md, LICENSE.md, README.md manually
- s.files += %w[CHANGELOG.md LICENSE.md README.md]
# include the gemspec itself because warbler breaks w/o it
s.files += %w[bundler.gemspec]
+ s.extra_rdoc_files = %w[CHANGELOG.md LICENSE.md README.md]
s.bindir = "exe"
s.executables = %w[bundle bundler]
s.require_paths = ["lib"]
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index d6e69afddf..45d4e62481 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -308,39 +308,19 @@ module Bundler
end
end
- unless Bundler.feature_flag.bundler_3_mode?
- desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
- long_desc <<-D
- Show lists the names and versions of all gems that are required by your Gemfile.
- Calling show with [GEM] will list the exact location of that gem on your machine.
- D
- method_option "paths", :type => :boolean,
- :banner => "List the paths of all gems that are required by your Gemfile."
- method_option "outdated", :type => :boolean,
- :banner => "Show verbose output including whether gems are outdated."
- def show(gem_name = nil)
- if ARGV[0] == "show"
- rest = ARGV[1..-1]
-
- if flag = rest.find{|arg| ["--verbose", "--outdated"].include?(arg) }
- Bundler::SharedHelpers.major_deprecation(2, "the `#{flag}` flag to `bundle show` was undocumented and will be removed without replacement")
- else
- new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
-
- new_arguments = rest.map do |arg|
- next arg if arg != "--paths"
- next "--path" if new_command == "info"
- end
-
- old_argv = ARGV.join(" ")
- new_argv = [new_command, *new_arguments.compact].join(" ")
-
- Bundler::SharedHelpers.major_deprecation(2, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
- end
- end
- require_relative "cli/show"
- Show.new(options, gem_name).run
- end
+ desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
+ long_desc <<-D
+ Show lists the names and versions of all gems that are required by your Gemfile.
+ Calling show with [GEM] will list the exact location of that gem on your machine.
+ D
+ method_option "paths", :type => :boolean,
+ :banner => "List the paths of all gems that are required by your Gemfile."
+ method_option "outdated", :type => :boolean,
+ :banner => "Show verbose output including whether gems are outdated."
+ def show(gem_name = nil)
+ SharedHelpers.major_deprecation(2, "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement") if ARGV.include?("--outdated")
+ require_relative "cli/show"
+ Show.new(options, gem_name).run
end
desc "list", "List all gems in the bundle"
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index e5d9af477c..d86ed2d002 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -146,17 +146,14 @@ module Bundler
end
def retrieve_active_spec(definition, current_spec)
- if strict
- active_spec = definition.find_resolved_spec(current_spec)
- else
- active_specs = definition.find_indexed_specs(current_spec)
- if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
- active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
- end
- active_spec = active_specs.last
- end
+ active_spec = definition.resolve.find_by_name_and_platform(current_spec.name, current_spec.platform)
+ return active_spec if strict
- active_spec
+ active_specs = active_spec.source.specs.search(current_spec.name).select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
+ if !current_spec.version.prerelease? && !options[:pre] && active_specs.size > 1
+ active_specs.delete_if {|b| b.respond_to?(:version) && b.version.prerelease? }
+ end
+ active_specs.last
end
def print_gems(gems_list)
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index d4d3ce5a2d..bdf287b1e7 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -219,7 +219,6 @@ module Bundler
Bundler.ui.debug "The definition is missing #{missing.map(&:full_name)}"
true
rescue BundlerError => e
- @index = nil
@resolve = nil
@specs = nil
@gem_version_promoter = nil
@@ -282,50 +281,6 @@ module Bundler
end
end
- def index
- @index ||= Index.build do |idx|
- dependency_names = @dependencies.map(&:name)
-
- sources.all_sources.each do |source|
- source.dependency_names = dependency_names - pinned_spec_names(source)
- idx.add_source source.specs
- dependency_names.concat(source.unmet_deps).uniq!
- end
-
- double_check_for_index(idx, dependency_names)
- end
- end
-
- # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
- # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
- # but will not have found any versions of Bar from source B, which is a problem if the requested version
- # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
- # each spec we found, we add all possible versions from all sources to the index.
- def double_check_for_index(idx, dependency_names)
- pinned_names = pinned_spec_names
- loop do
- idxcount = idx.size
-
- names = :names # do this so we only have to traverse to get dependency_names from the index once
- unmet_dependency_names = lambda do
- return names unless names == :names
- new_names = sources.all_sources.map(&:dependency_names_to_double_check)
- return names = nil if new_names.compact!
- names = new_names.flatten(1).concat(dependency_names)
- names.uniq!
- names -= pinned_names
- names
- end
-
- sources.all_sources.each do |source|
- source.double_check_for(unmet_dependency_names)
- end
-
- break if idxcount == idx.size
- end
- end
- private :double_check_for_index
-
def has_rubygems_remotes?
sources.rubygems_sources.any? {|s| s.remotes.any? }
end
@@ -532,14 +487,6 @@ module Bundler
end
end
- def find_resolved_spec(current_spec)
- specs.find_by_name_and_platform(current_spec.name, current_spec.platform)
- end
-
- def find_indexed_specs(current_spec)
- index[current_spec.name].select {|spec| spec.match_platform(current_spec.platform) }.sort_by(&:version)
- end
-
attr_reader :sources
private :sources
@@ -556,6 +503,10 @@ module Bundler
private
+ def precompute_source_requirements_for_indirect_dependencies?
+ sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && sources.no_aggregate_global_source?
+ end
+
def current_ruby_platform_locked?
return false unless generic_local_platform == Gem::Platform::RUBY
@@ -681,9 +632,9 @@ module Bundler
changes = false
# If there is a RubyGems source in both
- locked_gem_sources.each do |locked_gem|
+ locked_gem_sources.each do |locked_gem_source|
# Merge the remotes from the Gemfile into the Gemfile.lock
- changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
+ changes |= locked_gem_source.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
end
changes
@@ -902,26 +853,22 @@ module Bundler
end
def source_requirements
- # Load all specs from remote sources
- index
-
# Record the specs available in each gem's source, so that those
# specs will be available later when the resolver knows where to
# look for that gemspec (or its dependencies)
- source_requirements = { :default => sources.default_source }.merge(dependency_source_requirements)
+ source_requirements = if precompute_source_requirements_for_indirect_dependencies?
+ { :default => sources.default_source }.merge(source_map.all_requirements)
+ else
+ { :default => Source::RubygemsAggregate.new(sources, source_map) }.merge(source_map.direct_requirements)
+ end
metadata_dependencies.each do |dep|
source_requirements[dep.name] = sources.metadata_source
end
- source_requirements[:global] = index unless Bundler.feature_flag.disable_multisource?
- source_requirements[:default_bundler] = source_requirements["bundler"] || source_requirements[:default]
+ source_requirements[:default_bundler] = source_requirements["bundler"] || sources.default_source
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
source_requirements
end
- def pinned_spec_names(skip = nil)
- dependency_source_requirements.reject {|_, source| source == skip }.keys
- end
-
def requested_groups
groups - Bundler.settings[:without] - @optional_groups + Bundler.settings[:with]
end
@@ -977,16 +924,8 @@ module Bundler
Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
end
- def dependency_source_requirements
- @dependency_source_requirements ||= begin
- source_requirements = {}
- default = sources.default_source
- dependencies.each do |dep|
- dep_source = dep.source || default
- source_requirements[dep.name] = dep_source
- end
- source_requirements
- end
+ def source_map
+ @source_map ||= SourceMap.new(sources, dependencies)
end
end
end
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index 3f9a502179..53d76b8ae8 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -32,7 +32,6 @@ module Bundler
settings_flag(:cache_all) { bundler_3_mode? }
settings_flag(:default_install_uses_path) { bundler_3_mode? }
settings_flag(:deployment_means_frozen) { bundler_3_mode? }
- settings_flag(:disable_multisource) { bundler_3_mode? }
settings_flag(:forget_cli_options) { bundler_3_mode? }
settings_flag(:global_gem_cache) { bundler_3_mode? }
settings_flag(:path_relative_to_cwd) { bundler_3_mode? }
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index 5d0bb905bc..c5a19d3eea 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -112,7 +112,7 @@ module Bundler
#{issues_url(e)}
If there aren't any reports for this error yet, please create copy and paste the report template above into a new issue. Don't forget to anonymize any private data! The new issue form is located at:
- https://github.com/rubygems/rubygems/issues/new?labels=Bundler
+ https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md
EOS
end
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index f945176037..36520c0a43 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -122,10 +122,9 @@ module Bundler
names
end
- # returns a list of the dependencies
def unmet_dependency_names
dependency_names.select do |name|
- name != "bundler" && search(name).empty?
+ search(name).empty?
end
end
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
index ffcd63bbcc..a8d3420d59 100644
--- a/lib/bundler/man/bundle-add.1
+++ b/lib/bundler/man/bundle-add.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-ADD" "1" "April 2021" "" ""
+.TH "BUNDLE\-ADD" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1
index 23c371b7de..3493770304 100644
--- a/lib/bundler/man/bundle-binstubs.1
+++ b/lib/bundler/man/bundle-binstubs.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-BINSTUBS" "1" "April 2021" "" ""
+.TH "BUNDLE\-BINSTUBS" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1
index 9bb8011a8a..7bfbaa6a4e 100644
--- a/lib/bundler/man/bundle-cache.1
+++ b/lib/bundler/man/bundle-cache.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CACHE" "1" "April 2021" "" ""
+.TH "BUNDLE\-CACHE" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1
index 6696479fef..bae888df27 100644
--- a/lib/bundler/man/bundle-check.1
+++ b/lib/bundler/man/bundle-check.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CHECK" "1" "April 2021" "" ""
+.TH "BUNDLE\-CHECK" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1
index 625d87c580..2e2bb615c4 100644
--- a/lib/bundler/man/bundle-clean.1
+++ b/lib/bundler/man/bundle-clean.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CLEAN" "1" "April 2021" "" ""
+.TH "BUNDLE\-CLEAN" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1
index 3a1cee9b81..26e9418c0c 100644
--- a/lib/bundler/man/bundle-config.1
+++ b/lib/bundler/man/bundle-config.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CONFIG" "1" "April 2021" "" ""
+.TH "BUNDLE\-CONFIG" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options
@@ -56,9 +56,6 @@ Executing \fBbundle config unset \-\-local <name> <value>\fR will delete the con
.P
Executing bundle with the \fBBUNDLE_IGNORE_CONFIG\fR environment variable set will cause it to ignore all configuration\.
.
-.P
-Executing \fBbundle config set \-\-local disable_multisource true\fR upgrades the warning about the Gemfile containing multiple primary sources to an error\. Executing \fBbundle config unset disable_multisource\fR downgrades this error to a warning\.
-.
.SH "REMEMBERING OPTIONS"
Flags passed to \fBbundle install\fR or the Bundler runtime, such as \fB\-\-path foo\fR or \fB\-\-without production\fR, are remembered between commands and saved to your local application\'s configuration (normally, \fB\./\.bundle/config\fR)\.
.
@@ -184,9 +181,6 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\.
.
.IP "\(bu" 4
-\fBdisable_multisource\fR (\fBBUNDLE_DISABLE_MULTISOURCE\fR): When set, Gemfiles containing multiple sources will produce errors instead of warnings\. Use \fBbundle config unset disable_multisource\fR to unset\.
-.
-.IP "\(bu" 4
\fBdisable_shared_gems\fR (\fBBUNDLE_DISABLE_SHARED_GEMS\fR): Stop Bundler from accessing gems installed to RubyGems\' normal location\.
.
.IP "\(bu" 4
diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn
index 15bc5af778..cffd87a160 100644
--- a/lib/bundler/man/bundle-config.1.ronn
+++ b/lib/bundler/man/bundle-config.1.ronn
@@ -47,10 +47,6 @@ configuration only from the local application.
Executing bundle with the `BUNDLE_IGNORE_CONFIG` environment variable set will
cause it to ignore all configuration.
-Executing `bundle config set --local disable_multisource true` upgrades the warning about
-the Gemfile containing multiple primary sources to an error. Executing `bundle
-config unset disable_multisource` downgrades this error to a warning.
-
## REMEMBERING OPTIONS
Flags passed to `bundle install` or the Bundler runtime, such as `--path foo` or
@@ -178,10 +174,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
* `disable_local_revision_check` (`BUNDLE_DISABLE_LOCAL_REVISION_CHECK`):
Allow Bundler to use a local git override without checking if the revision
present in the lockfile is present in the repository.
-* `disable_multisource` (`BUNDLE_DISABLE_MULTISOURCE`):
- When set, Gemfiles containing multiple sources will produce errors
- instead of warnings.
- Use `bundle config unset disable_multisource` to unset.
* `disable_shared_gems` (`BUNDLE_DISABLE_SHARED_GEMS`):
Stop Bundler from accessing gems installed to RubyGems' normal location.
* `disable_version_check` (`BUNDLE_DISABLE_VERSION_CHECK`):
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
index 8e4c47c683..0c8ff27d3e 100644
--- a/lib/bundler/man/bundle-doctor.1
+++ b/lib/bundler/man/bundle-doctor.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-DOCTOR" "1" "April 2021" "" ""
+.TH "BUNDLE\-DOCTOR" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems
diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1
index 863b76e4b7..c8d51cd4a2 100644
--- a/lib/bundler/man/bundle-exec.1
+++ b/lib/bundler/man/bundle-exec.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-EXEC" "1" "April 2021" "" ""
+.TH "BUNDLE\-EXEC" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1
index e71ccb4832..4b7e5a088c 100644
--- a/lib/bundler/man/bundle-gem.1
+++ b/lib/bundler/man/bundle-gem.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-GEM" "1" "April 2021" "" ""
+.TH "BUNDLE\-GEM" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
index 168d021112..4039ec9c94 100644
--- a/lib/bundler/man/bundle-info.1
+++ b/lib/bundler/man/bundle-info.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INFO" "1" "April 2021" "" ""
+.TH "BUNDLE\-INFO" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle
diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1
index 5d3e61d05b..f538b06bf6 100644
--- a/lib/bundler/man/bundle-init.1
+++ b/lib/bundler/man/bundle-init.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INIT" "1" "April 2021" "" ""
+.TH "BUNDLE\-INIT" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
index 37acabfa9a..85549b4585 100644
--- a/lib/bundler/man/bundle-inject.1
+++ b/lib/bundler/man/bundle-inject.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INJECT" "1" "April 2021" "" ""
+.TH "BUNDLE\-INJECT" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1
index 2dcb4d3ac6..867a41d70d 100644
--- a/lib/bundler/man/bundle-install.1
+++ b/lib/bundler/man/bundle-install.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INSTALL" "1" "April 2021" "" ""
+.TH "BUNDLE\-INSTALL" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1
index 7c93b89dc3..0b67785a21 100644
--- a/lib/bundler/man/bundle-list.1
+++ b/lib/bundler/man/bundle-list.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LIST" "1" "April 2021" "" ""
+.TH "BUNDLE\-LIST" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle
diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1
index a4dfda9c86..860a2e07ef 100644
--- a/lib/bundler/man/bundle-lock.1
+++ b/lib/bundler/man/bundle-lock.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LOCK" "1" "April 2021" "" ""
+.TH "BUNDLE\-LOCK" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1
index 0511bc655b..b907e2d544 100644
--- a/lib/bundler/man/bundle-open.1
+++ b/lib/bundler/man/bundle-open.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OPEN" "1" "April 2021" "" ""
+.TH "BUNDLE\-OPEN" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1
index 268b4b157c..5427a2ab77 100644
--- a/lib/bundler/man/bundle-outdated.1
+++ b/lib/bundler/man/bundle-outdated.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OUTDATED" "1" "April 2021" "" ""
+.TH "BUNDLE\-OUTDATED" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available
diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1
index 77638b2b4b..2a80abb8d6 100644
--- a/lib/bundler/man/bundle-platform.1
+++ b/lib/bundler/man/bundle-platform.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PLATFORM" "1" "April 2021" "" ""
+.TH "BUNDLE\-PLATFORM" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
index 0fcf9fdb39..7fff665de0 100644
--- a/lib/bundler/man/bundle-pristine.1
+++ b/lib/bundler/man/bundle-pristine.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PRISTINE" "1" "April 2021" "" ""
+.TH "BUNDLE\-PRISTINE" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1
index ca366b81a9..17de5ed5a9 100644
--- a/lib/bundler/man/bundle-remove.1
+++ b/lib/bundler/man/bundle-remove.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-REMOVE" "1" "April 2021" "" ""
+.TH "BUNDLE\-REMOVE" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile
diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1
index e403ae980f..fbbe18741f 100644
--- a/lib/bundler/man/bundle-show.1
+++ b/lib/bundler/man/bundle-show.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-SHOW" "1" "April 2021" "" ""
+.TH "BUNDLE\-SHOW" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1
index 5546b51792..3c9af3dcc1 100644
--- a/lib/bundler/man/bundle-update.1
+++ b/lib/bundler/man/bundle-update.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-UPDATE" "1" "April 2021" "" ""
+.TH "BUNDLE\-UPDATE" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
index 645c45b607..fbc48aa902 100644
--- a/lib/bundler/man/bundle-viz.1
+++ b/lib/bundler/man/bundle-viz.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-VIZ" "1" "April 2021" "" ""
+.TH "BUNDLE\-VIZ" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
index 5c1bc96572..5b6c9afe78 100644
--- a/lib/bundler/man/bundle.1
+++ b/lib/bundler/man/bundle.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE" "1" "April 2021" "" ""
+.TH "BUNDLE" "1" "May 2021" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index 480d38f39c..2497fad234 100644
--- a/lib/bundler/man/gemfile.5
+++ b/lib/bundler/man/gemfile.5
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "GEMFILE" "5" "April 2021" "" ""
+.TH "GEMFILE" "5" "May 2021" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index d70a16f4bc..f6f4ac4f0a 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -244,6 +244,20 @@ module Bundler
specs.unmet_dependency_names
end
+ # Used by definition.
+ #
+ # Note: Do not override if you don't know what you are doing.
+ def spec_names
+ specs.spec_names
+ end
+
+ # Used by definition.
+ #
+ # Note: Do not override if you don't know what you are doing.
+ def add_dependency_names(names)
+ @dependencies |= Array(names)
+ end
+
# Note: Do not override if you don't know what you are doing.
def can_lock?(spec)
spec.source == self
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 69899dc6c3..9a25e49d4b 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -21,17 +21,11 @@ module Bundler
base = SpecSet.new(base) unless base.is_a?(SpecSet)
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
result = resolver.start(requirements)
- SpecSet.new(result)
+ SpecSet.new(result).for(requirements.reject{|dep| dep.name.end_with?("\0") })
end
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
@source_requirements = source_requirements
-
- @index_requirements = source_requirements.each_with_object({}) do |source_requirement, index_requirements|
- name, source = source_requirement
- index_requirements[name] = name == :global ? source : source.specs
- end
-
@base = base
@resolver = Molinillo::Resolver.new(self, self)
@search_for = {}
@@ -45,10 +39,6 @@ module Bundler
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
- @no_aggregate_global_source = @source_requirements[:global].nil?
-
- @variant_specific_names = []
- @generic_names = ["Ruby\0", "RubyGems\0"]
end
def start(requirements)
@@ -58,7 +48,6 @@ module Bundler
verify_gemfile_dependencies_are_found!(requirements)
dg = @resolver.resolve(requirements, @base_dg)
dg.
- tap {|resolved| validate_resolved_specs!(resolved) }.
map(&:payload).
reject {|sg| sg.name.end_with?("\0") }.
map(&:to_specs).
@@ -112,24 +101,14 @@ module Bundler
include Molinillo::SpecificationProvider
def dependencies_for(specification)
- all_dependencies = specification.dependencies_for_activated_platforms
-
- if @variant_specific_names.include?(specification.name)
- @variant_specific_names |= all_dependencies.map(&:name) - @generic_names
- else
- generic_names, variant_specific_names = specification.partitioned_dependency_names_for_activated_platforms
- @variant_specific_names |= variant_specific_names - @generic_names
- @generic_names |= generic_names
- end
-
- all_dependencies
+ specification.dependencies_for_activated_platforms
end
def search_for(dependency_proxy)
platform = dependency_proxy.__platform
dependency = dependency_proxy.dep
name = dependency.name
- search_result = @search_for[dependency_proxy] ||= begin
+ @search_for[dependency_proxy] ||= begin
results = results_for(dependency, @base[name])
if vertex = @base_dg.vertex_named(name)
@@ -181,35 +160,14 @@ module Bundler
@gem_version_promoter.sort_versions(dependency, spec_groups)
end
end
-
- unless search_result.empty?
- specific_dependency = @variant_specific_names.include?(name)
- return search_result unless specific_dependency
-
- search_result.each do |sg|
- if @generic_names.include?(name)
- @variant_specific_names -= [name]
- sg.activate_all_platforms!
- else
- sg.activate_platform!(platform)
- end
- end
- end
-
- search_result
end
def index_for(dependency)
- source = @index_requirements[dependency.name]
- if source
- source
- elsif @no_aggregate_global_source
- Index.build do |idx|
- dependency.all_sources.each {|s| idx.add_source(s.specs) }
- end
- else
- @index_requirements[:global]
- end
+ source_for(dependency.name).specs
+ end
+
+ def source_for(name)
+ @source_requirements[name] || @source_requirements[:default]
end
def results_for(dependency, base)
@@ -240,23 +198,10 @@ module Bundler
dependencies.map(&:dep) == other_dependencies.map(&:dep)
end
- def relevant_sources_for_vertex(vertex)
- if vertex.root?
- [@source_requirements[vertex.name]]
- elsif @no_aggregate_global_source
- vertex.recursive_predecessors.map do |v|
- @source_requirements[v.name]
- end.compact << @source_requirements[:default]
- else
- []
- end
- end
-
def sort_dependencies(dependencies, activated, conflicts)
dependencies.sort_by do |dependency|
name = name_for(dependency)
vertex = activated.vertex_named(name)
- dependency.all_sources = relevant_sources_for_vertex(vertex)
[
@base_dg.vertex_named(name) ? 0 : 1,
vertex.payload ? 0 : 1,
@@ -398,7 +343,7 @@ module Bundler
if other_bundler_required
o << "\n\n"
- candidate_specs = @index_requirements[:default_bundler].search(conflict_dependency)
+ candidate_specs = source_for(:default_bundler).specs.search(conflict_dependency)
if candidate_specs.any?
target_version = candidate_specs.last.version
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
@@ -415,11 +360,7 @@ module Bundler
elsif !conflict.existing
o << "\n"
- relevant_sources = if conflict.requirement.source
- [conflict.requirement.source]
- else
- conflict.requirement.all_sources
- end.compact.map(&:to_s).uniq.sort
+ relevant_source = conflict.requirement.source || source_for(name)
metadata_requirement = name.end_with?("\0")
@@ -432,12 +373,10 @@ module Bundler
end
o << " "
- o << if relevant_sources.empty?
- "in any of the sources.\n"
- elsif metadata_requirement
- "is not available in #{relevant_sources.join(" or ")}"
+ o << if metadata_requirement
+ "is not available in #{relevant_source}"
else
- "in any of the relevant sources:\n #{relevant_sources * "\n "}\n"
+ "in #{relevant_source}.\n"
end
end
end,
@@ -451,27 +390,5 @@ module Bundler
end
)
end
-
- def validate_resolved_specs!(resolved_specs)
- resolved_specs.each do |v|
- name = v.name
- sources = relevant_sources_for_vertex(v)
- next unless sources.any?
- if default_index = sources.index(@source_requirements[:default])
- sources.delete_at(default_index)
- end
- sources.reject! {|s| s.specs.search(name).empty? }
- sources.uniq!
- next if sources.size <= 1
-
- msg = ["The gem '#{name}' was found in multiple relevant sources."]
- msg.concat sources.map {|s| " * #{s}" }.sort
- msg << "You #{@no_aggregate_global_source ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
- msg = msg.join("\n")
-
- raise SecurityError, msg if @no_aggregate_global_source
- Bundler.ui.warn "Warning: #{msg}"
- end
- end
end
end
diff --git a/lib/bundler/resolver/spec_group.rb b/lib/bundler/resolver/spec_group.rb
index 73ffec5838..8f4fd18c46 100644
--- a/lib/bundler/resolver/spec_group.rb
+++ b/lib/bundler/resolver/spec_group.rb
@@ -21,14 +21,10 @@ module Bundler
@version = exemplary_spec.version
@source = exemplary_spec.source
- @all_platforms = relevant_platforms
@activated_platforms = relevant_platforms
@dependencies = Hash.new do |dependencies, platforms|
dependencies[platforms] = dependencies_for(platforms)
end
- @partitioned_dependency_names = Hash.new do |partitioned_dependency_names, platforms|
- partitioned_dependency_names[platforms] = partitioned_dependency_names_for(platforms)
- end
@specs = specs
end
@@ -45,14 +41,6 @@ module Bundler
end.flatten.compact.uniq
end
- def activate_platform!(platform)
- self.activated_platforms = [platform]
- end
-
- def activate_all_platforms!
- self.activated_platforms = @all_platforms
- end
-
def to_s
activated_platforms_string = sorted_activated_platforms.join(", ")
"#{name} (#{version}) (#{activated_platforms_string})"
@@ -62,10 +50,6 @@ module Bundler
@dependencies[activated_platforms]
end
- def partitioned_dependency_names_for_activated_platforms
- @partitioned_dependency_names[activated_platforms]
- end
-
def ==(other)
return unless other.is_a?(SpecGroup)
name == other.name &&
@@ -100,14 +84,6 @@ module Bundler
end.flatten
end
- def partitioned_dependency_names_for(platforms)
- return @dependencies[platforms].map(&:name), [] if platforms.size == 1
-
- @dependencies[platforms].partition do |dep_proxy|
- @dependencies[platforms].count {|dp| dp.dep == dep_proxy.dep } == platforms.size
- end.map {|deps| deps.map(&:name) }
- end
-
def __dependencies(platform)
dependencies = []
@specs[platform].first.dependencies.each do |dep|
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index 2bd2dcb451..c95664965c 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -105,7 +105,7 @@ module Gem
end
class Dependency
- attr_accessor :source, :groups, :all_sources
+ attr_accessor :source, :groups
alias_method :eql?, :==
@@ -116,7 +116,7 @@ module Gem
end
def to_yaml_properties
- instance_variables.reject {|p| ["@source", "@groups", "@all_sources"].include?(p.to_s) }
+ instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) }
end
def to_lock
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index 612c56f041..0702a80440 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -21,7 +21,6 @@ module Bundler
disable_exec_load
disable_local_branch_check
disable_local_revision_check
- disable_multisource
disable_shared_gems
disable_version_check
force_ruby_platform
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index a3f4b09cce..f39072791c 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -7,6 +7,7 @@ module Bundler
autoload :Metadata, File.expand_path("source/metadata", __dir__)
autoload :Path, File.expand_path("source/path", __dir__)
autoload :Rubygems, File.expand_path("source/rubygems", __dir__)
+ autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__)
attr_accessor :dependency_names
@@ -39,6 +40,10 @@ module Bundler
def remote!; end
+ def add_dependency_names(names)
+ @dependency_names = Array(dependency_names) | Array(names)
+ end
+
# it's possible that gems from one source depend on gems from some
# other source, so now we download gemspecs and iterate over those
# dependencies, looking for gems we don't have info on yet.
@@ -48,6 +53,10 @@ module Bundler
specs.dependency_names
end
+ def spec_names
+ specs.spec_names
+ end
+
def include?(other)
other == self
end
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 2b7cfd53b9..a11a89cf72 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -259,8 +259,16 @@ module Bundler
!equivalent
end
+ def spec_names
+ if @allow_remote && dependency_api_available?
+ remote_specs.spec_names
+ else
+ []
+ end
+ end
+
def unmet_deps
- if @allow_remote && api_fetchers.any?
+ if @allow_remote && dependency_api_available?
remote_specs.unmet_dependency_names
else
[]
@@ -276,7 +284,7 @@ module Bundler
def double_check_for(unmet_dependency_names)
return unless @allow_remote
- return unless api_fetchers.any?
+ return unless dependency_api_available?
unmet_dependency_names = unmet_dependency_names.call
unless unmet_dependency_names.nil?
@@ -298,17 +306,20 @@ module Bundler
remote_specs.each do |spec|
case spec
when EndpointSpecification, Gem::Specification, StubSpecification, LazySpecification
- names.concat(spec.runtime_dependencies)
+ names.concat(spec.runtime_dependencies.map(&:name))
when RemoteSpecification # from the full index
return nil
else
raise "unhandled spec type (#{spec.inspect})"
end
end
- names.map!(&:name) if names
names
end
+ def dependency_api_available?
+ api_fetchers.any?
+ end
+
protected
def credless_remotes
diff --git a/lib/bundler/source/rubygems_aggregate.rb b/lib/bundler/source/rubygems_aggregate.rb
new file mode 100644
index 0000000000..685bf7e90a
--- /dev/null
+++ b/lib/bundler/source/rubygems_aggregate.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module Bundler
+ class Source
+ class RubygemsAggregate
+ attr_reader :source_map, :sources
+
+ def initialize(sources, source_map)
+ @sources = sources
+ @source_map = source_map
+
+ @index = build_index
+ end
+
+ def specs
+ @index
+ end
+
+ def to_s
+ "any of the sources"
+ end
+
+ private
+
+ def build_index
+ Index.build do |idx|
+ dependency_names = source_map.pinned_spec_names
+
+ sources.all_sources.each do |source|
+ source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
+ idx.add_source source.specs
+ dependency_names.concat(source.unmet_deps).uniq!
+ end
+
+ double_check_for_index(idx, dependency_names)
+ end
+ end
+
+ # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
+ # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
+ # but will not have found any versions of Bar from source B, which is a problem if the requested version
+ # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
+ # each spec we found, we add all possible versions from all sources to the index.
+ def double_check_for_index(idx, dependency_names)
+ pinned_names = source_map.pinned_spec_names
+
+ names = :names # do this so we only have to traverse to get dependency_names from the index once
+ unmet_dependency_names = lambda do
+ return names unless names == :names
+ new_names = sources.all_sources.map(&:dependency_names_to_double_check)
+ return names = nil if new_names.compact!
+ names = new_names.flatten(1).concat(dependency_names)
+ names.uniq!
+ names -= pinned_names
+ names
+ end
+
+ sources.all_sources.each do |source|
+ source.double_check_for(unmet_dependency_names)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index 6f5636f41e..f7eb3a1c03 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -21,15 +21,19 @@ module Bundler
@rubygems_sources = []
@metadata_source = Source::Metadata.new
- @disable_multisource = true
+ @merged_gem_lockfile_sections = false
end
- def disable_multisource?
- @disable_multisource
+ def merged_gem_lockfile_sections?
+ @merged_gem_lockfile_sections
end
def merged_gem_lockfile_sections!
- @disable_multisource = false
+ @merged_gem_lockfile_sections = true
+ end
+
+ def no_aggregate_global_source?
+ global_rubygems_source.remotes.size <= 1
end
def add_path_source(options = {})
@@ -70,7 +74,11 @@ module Bundler
end
def rubygems_sources
- @rubygems_sources + [global_rubygems_source]
+ non_global_rubygems_sources + [global_rubygems_source]
+ end
+
+ def non_global_rubygems_sources
+ @rubygems_sources
end
def rubygems_remotes
@@ -81,16 +89,27 @@ module Bundler
path_sources + git_sources + plugin_sources + rubygems_sources + [metadata_source]
end
+ def non_default_explicit_sources
+ all_sources - [default_source, metadata_source]
+ end
+
def get(source)
source_list_for(source).find {|s| equal_source?(source, s) || equivalent_source?(source, s) }
end
def lock_sources
- lock_sources = (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
- if disable_multisource?
- lock_sources + rubygems_sources.sort_by(&:to_s).uniq
+ lock_other_sources + lock_rubygems_sources
+ end
+
+ def lock_other_sources
+ (path_sources + git_sources + plugin_sources).sort_by(&:to_s)
+ end
+
+ def lock_rubygems_sources
+ if merged_gem_lockfile_sections?
+ [combine_rubygems_sources]
else
- lock_sources << combine_rubygems_sources
+ rubygems_sources.sort_by(&:to_s).uniq
end
end
@@ -104,7 +123,7 @@ module Bundler
end
end
- replacement_rubygems = !disable_multisource? &&
+ replacement_rubygems = merged_gem_lockfile_sections? &&
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
@global_rubygems_source = replacement_rubygems if replacement_rubygems
diff --git a/lib/bundler/source_map.rb b/lib/bundler/source_map.rb
new file mode 100644
index 0000000000..a554f26f76
--- /dev/null
+++ b/lib/bundler/source_map.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Bundler
+ class SourceMap
+ attr_reader :sources, :dependencies
+
+ def initialize(sources, dependencies)
+ @sources = sources
+ @dependencies = dependencies
+ end
+
+ def pinned_spec_names(skip = nil)
+ direct_requirements.reject {|_, source| source == skip }.keys
+ end
+
+ def all_requirements
+ requirements = direct_requirements.dup
+
+ unmet_deps = sources.non_default_explicit_sources.map do |source|
+ (source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
+ previous_source = requirements[indirect_dependency_name]
+ if previous_source.nil?
+ requirements[indirect_dependency_name] = source
+ else
+ no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode?
+
+ msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."]
+ msg.concat [previous_source, source].map {|s| " * #{s}" }.sort
+ msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
+ msg = msg.join("\n")
+
+ raise SecurityError, msg if no_ambiguous_sources
+ Bundler.ui.warn "Warning: #{msg}"
+ end
+ end
+
+ source.unmet_deps
+ end
+
+ sources.default_source.add_dependency_names(unmet_deps.flatten - requirements.keys)
+
+ requirements
+ end
+
+ def direct_requirements
+ @direct_requirements ||= begin
+ requirements = {}
+ default = sources.default_source
+ dependencies.each do |dep|
+ dep_source = dep.source || default
+ dep_source.add_dependency_names(dep.name)
+ requirements[dep.name] = dep_source
+ end
+ requirements
+ end
+ end
+ end
+end
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index 632b24dda9..7032004076 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
<%- if config[:mit] -%>
spec.license = "MIT"
<%- end -%>
- spec.required_ruby_version = Gem::Requirement.new(">= <%= config[:required_ruby_version] %>")
+ spec.required_ruby_version = ">= <%= config[:required_ruby_version] %>"
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 735cb09c88..8e327e0951 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: false
module Bundler
- VERSION = "2.2.17".freeze
+ VERSION = "2.2.18".freeze
def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i
diff --git a/lib/rubygems.rb b/lib/rubygems.rb
index 48d0117efb..dec57f8309 100644
--- a/lib/rubygems.rb
+++ b/lib/rubygems.rb
@@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
- VERSION = "3.2.17".freeze
+ VERSION = "3.2.18".freeze
end
# Must be first since it unloads the prelude from 1.9.2
diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb
index fede270417..1f73796351 100644
--- a/lib/rubygems/ext/ext_conf_builder.rb
+++ b/lib/rubygems/ext/ext_conf_builder.rb
@@ -23,11 +23,11 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
# spaces do not work.
#
# Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940
- tmp_dest = get_relative_path(tmp_dest, extension_dir)
+ tmp_dest_relative = get_relative_path(tmp_dest.clone, extension_dir)
Tempfile.open %w[siteconf .rb], extension_dir do |siteconf|
siteconf.puts "require 'rbconfig'"
- siteconf.puts "dest_path = #{tmp_dest.dump}"
+ siteconf.puts "dest_path = #{tmp_dest_relative.dump}"
%w[sitearchdir sitelibdir].each do |dir|
siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
@@ -63,8 +63,8 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
make dest_path, results, extension_dir
- if tmp_dest
- full_tmp_dest = File.join(extension_dir, tmp_dest)
+ if tmp_dest_relative
+ full_tmp_dest = File.join(extension_dir, tmp_dest_relative)
# TODO remove in RubyGems 3
if Gem.install_extension_in_lib and lib_dir
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 6b569032ba..7206c3eaf0 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -1558,7 +1558,6 @@ class Gem::Specification < Gem::BasicSpecification
def build_extensions # :nodoc:
return if default_gem?
return if extensions.empty?
- return if installed_by_version < Gem::Version.new('2.2.0.preview.2')
return if File.exist? gem_build_complete_path
return if !File.writable?(base_dir)
return if !File.exist?(File.join(base_dir, 'extensions'))
@@ -2129,7 +2128,6 @@ class Gem::Specification < Gem::BasicSpecification
def missing_extensions?
return false if default_gem?
return false if extensions.empty?
- return false if installed_by_version < Gem::Version.new('2.2.0.preview.2')
return false if File.exist? gem_build_complete_path
true
diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb
index e2763561c6..b3e23360ed 100644
--- a/lib/rubygems/test_case.rb
+++ b/lib/rubygems/test_case.rb
@@ -12,7 +12,7 @@ if File.exist?(bundler_gemspec)
end
begin
- gem 'minitest', '~> 5.13'
+ gem 'test-unit', '~> 3.0'
rescue Gem::LoadError
end
@@ -32,16 +32,7 @@ else
require 'bundler'
end
-# Enable server plugin needed for bisection
-if ENV["RG_BISECT_SERVER_PLUGIN"]
- require ENV["RG_BISECT_SERVER_PLUGIN"]
-
- Minitest.extensions << "server"
-end
-
-ENV["MT_NO_PLUGINS"] = "true"
-
-require 'minitest/autorun'
+require 'test/unit'
ENV["JARS_SKIP"] = "true" if Gem.java_platform? # avoid unnecessary and noisy `jar-dependencies` post install hook
@@ -111,7 +102,7 @@ end
# and uninstall gems, fetch remote gems through a stub fetcher and be assured
# your normal set of gems is not affected.
-class Gem::TestCase < Minitest::Test
+class Gem::TestCase < Test::Unit::TestCase
extend Gem::Deprecate
attr_accessor :fetcher # :nodoc:
@@ -140,11 +131,48 @@ class Gem::TestCase < Minitest::Test
end
def assert_directory_exists(path, msg = nil)
- msg = message(msg) { "Expected path '#{path}' to be a directory" }
- assert_path_exists path
+ msg = build_message(msg, "Expected path '#{path}' to be a directory")
+ assert_path_exist path
assert File.directory?(path), msg
end
+ # https://github.com/seattlerb/minitest/blob/21d9e804b63c619f602f3f4ece6c71b48974707a/lib/minitest/assertions.rb#L188
+ def _synchronize
+ yield
+ end
+
+ # https://github.com/seattlerb/minitest/blob/21d9e804b63c619f602f3f4ece6c71b48974707a/lib/minitest/assertions.rb#L546
+ def capture_subprocess_io
+ _synchronize do
+ begin
+ require "tempfile"
+
+ captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err")
+
+ orig_stdout, orig_stderr = $stdout.dup, $stderr.dup
+ $stdout.reopen captured_stdout
+ $stderr.reopen captured_stderr
+
+ yield
+
+ $stdout.rewind
+ $stderr.rewind
+
+ return captured_stdout.read, captured_stderr.read
+ ensure
+ captured_stdout.unlink
+ captured_stderr.unlink
+ $stdout.reopen orig_stdout
+ $stderr.reopen orig_stderr
+
+ orig_stdout.close
+ orig_stderr.close
+ captured_stdout.close
+ captured_stderr.close
+ end
+ end
+ end
+
##
# Sets the ENABLE_SHARED entry in RbConfig::CONFIG to +value+ and restores
# the original value when the block ends
@@ -262,19 +290,19 @@ class Gem::TestCase < Minitest::Test
def assert_contains_make_command(target, output, msg = nil)
if output.match(/\n/)
- msg = message(msg) do
+ msg = build_message(msg,
"Expected output containing make command \"%s\", but was \n\nBEGIN_OF_OUTPUT\n%sEND_OF_OUTPUT" % [
('%s %s' % [make_command, target]).rstrip,
output,
]
- end
+ )
else
- msg = message(msg) do
+ msg = build_message(msg,
'Expected make command "%s": %s' % [
('%s %s' % [make_command, target]).rstrip,
output,
]
- end
+ )
end
assert scan_make_command_lines(output).any? {|line|
@@ -664,6 +692,28 @@ class Gem::TestCase < Minitest::Test
path
end
+ ##
+ # Load a YAML string, the psych 3 way
+
+ def load_yaml(yaml)
+ if YAML.respond_to?(:unsafe_load)
+ YAML.unsafe_load(yaml)
+ else
+ YAML.load(yaml)
+ end
+ end
+
+ ##
+ # Load a YAML file, the psych 3 way
+
+ def load_yaml_file(file)
+ if YAML.respond_to?(:unsafe_load_file)
+ YAML.unsafe_load_file(file)
+ else
+ YAML.load_file(file)
+ end
+ end
+
def all_spec_names
Gem::Specification.map(&:full_name)
end
@@ -1519,4 +1569,38 @@ Also, a list:
end if Gem::HAVE_OPENSSL
end
+# https://github.com/seattlerb/minitest/blob/13c48a03d84a2a87855a4de0c959f96800100357/lib/minitest/mock.rb#L192
+class Object
+ def stub(name, val_or_callable, *block_args)
+ new_name = "__minitest_stub__#{name}"
+
+ metaclass = class << self; self; end
+
+ if respond_to? name and not methods.map(&:to_s).include? name.to_s
+ metaclass.send :define_method, name do |*args|
+ super(*args)
+ end
+ end
+
+ metaclass.send :alias_method, new_name, name
+
+ metaclass.send :define_method, name do |*args, &blk|
+ if val_or_callable.respond_to? :call
+ val_or_callable.call(*args, &blk)
+ else
+ blk.call(*block_args) if blk
+ val_or_callable
+ end
+ end
+
+ metaclass.send(:ruby2_keywords, name) if metaclass.respond_to?(:ruby2_keywords, true)
+
+ yield self
+ ensure
+ metaclass.send :undef_method, name
+ metaclass.send :alias_method, name, new_name
+ metaclass.send :undef_method, new_name
+ end
+end
+
require 'rubygems/test_utilities'