1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Sync latest bundler & rubygems development version

This commit is contained in:
David Rodríguez 2021-05-28 12:47:49 +02:00 committed by Hiroshi SHIBATA
parent 9952e9358e
commit 6e2240a2f9
Notes: git 2021-07-07 13:30:45 +09:00
111 changed files with 1575 additions and 1099 deletions

View file

@ -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__)

View file

@ -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"

View file

@ -11,9 +11,11 @@ module Bundler
def run
Bundler.settings.set_command_option_if_given :path, options[:path]
definition = Bundler.definition
definition.validate_runtime!
begin
definition = Bundler.definition
definition.validate_runtime!
definition.resolve_only_locally!
not_installed = definition.missing_specs
rescue GemNotFound, VersionConflict
Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."

View file

@ -58,7 +58,10 @@ module Bundler
definition.validate_runtime!
installer = Installer.install(Bundler.root, definition, options)
Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
Bundler.settings.temporary(:cache_all_platforms => options[:local] ? false : Bundler.settings[:cache_all_platforms]) do
Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.frozen_bundle?
end
Bundler.ui.confirm "Bundle complete! #{dependencies_count_for(definition)}, #{gems_installed_for(definition)}."
Bundler::CLI::Common.output_without_groups_message(:install)

View file

@ -21,9 +21,13 @@ module Bundler
Bundler::Fetcher.disable_endpoint = options["full-index"]
update = options[:update]
conservative = options[:conservative]
if update.is_a?(Array) # unlocking specific gems
Bundler::CLI::Common.ensure_all_gems_in_lockfile!(update)
update = { :gems => update, :lock_shared_dependencies => options[:conservative] }
update = { :gems => update, :conservative => conservative }
elsif update
update = { :conservative => conservative } if conservative
end
definition = Bundler.definition(update)

View file

@ -146,17 +146,16 @@ 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 unless active_spec
active_spec
return active_spec if strict
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)

View file

@ -27,9 +27,14 @@ module Bundler
raise InvalidOption, "Cannot specify --all along with specific options."
end
conservative = options[:conservative]
if full_update
# We're doing a full update
Bundler.definition(true)
if conservative
Bundler.definition(:conservative => conservative)
else
Bundler.definition(true)
end
else
unless Bundler.default_lockfile.exist?
raise GemfileLockNotFound, "This Bundle hasn't been installed yet. " \
@ -43,7 +48,7 @@ module Bundler
end
Bundler.definition(:gems => gems, :sources => sources, :ruby => options[:ruby],
:lock_shared_dependencies => options[:conservative],
:conservative => conservative,
:bundler => options[:bundler])
end

View file

@ -112,17 +112,18 @@ module Bundler
end
@locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
@disable_multisource = @locked_gem_sources.all?(&:disable_multisource?)
@multisource_allowed = @locked_gem_sources.any?(&:multiple_remotes?) && Bundler.frozen_bundle?
unless @disable_multisource
msg = "Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch."
if @multisource_allowed
unless sources.aggregate_global_source?
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."
Bundler::SharedHelpers.major_deprecation 2, msg
Bundler::SharedHelpers.major_deprecation 2, msg
end
@sources.merged_gem_lockfile_sections!
end
@unlock[:gems] ||= []
@unlock[:sources] ||= []
@unlock[:ruby] ||= if @ruby_version && locked_ruby_version_object
@ruby_version.diff(locked_ruby_version_object)
@ -135,8 +136,10 @@ module Bundler
@path_changes = converge_paths
@source_changes = converge_sources
unless @unlock[:lock_shared_dependencies]
eager_unlock = expand_dependencies(@unlock[:gems], true)
if @unlock[:conservative]
@unlock[:gems] ||= @dependencies.map(&:name)
else
eager_unlock = expand_dependencies(@unlock[:gems] || [], true)
@unlock[:gems] = @locked_specs.for(eager_unlock, [], false, false, false).map(&:name)
end
@ -161,8 +164,14 @@ module Bundler
end
end
def disable_multisource?
@disable_multisource
def multisource_allowed?
@multisource_allowed
end
def resolve_only_locally!
@remote = false
sources.local_only!
resolve
end
def resolve_with_cache!
@ -224,7 +233,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
@ -255,7 +263,7 @@ module Bundler
def specs_for(groups)
deps = dependencies_for(groups)
specs.for(expand_dependencies(deps))
SpecSet.new(specs.for(expand_dependencies(deps)))
end
def dependencies_for(groups)
@ -287,50 +295,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
@ -539,14 +503,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
@ -563,6 +519,10 @@ module Bundler
private
def precompute_source_requirements_for_indirect_dependencies?
sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
end
def current_ruby_platform_locked?
return false unless generic_local_platform == Gem::Platform::RUBY
@ -677,7 +637,7 @@ module Bundler
end
def converge_rubygems_sources
return false if disable_multisource?
return false unless multisource_allowed?
return false if locked_gem_sources.empty?
@ -688,9 +648,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
@ -789,8 +749,6 @@ module Bundler
end
end
unlock_source_unlocks_spec = Bundler.feature_flag.unlock_source_unlocks_spec?
converged = []
@locked_specs.each do |s|
# Replace the locked dependency's source with the equivalent source from the Gemfile
@ -802,11 +760,6 @@ module Bundler
next if s.source.nil?
next if @unlock[:sources].include?(s.source.name)
# XXX This is a backwards-compatibility fix to preserve the ability to
# unlock a single gem by passing its name via `--source`. See issue #3759
# TODO: delete in Bundler 2
next if unlock_source_unlocks_spec && @unlock[:sources].include?(s.name)
# If the spec is from a path source and it doesn't exist anymore
# then we unlock it.
@ -838,7 +791,7 @@ module Bundler
resolve = SpecSet.new(converged)
@locked_specs_incomplete_for_platform = !resolve.for(expand_dependencies(requested_dependencies & deps), @unlock[:gems], true, true)
resolve = resolve.for(expand_dependencies(deps, true), @unlock[:gems], false, false, false)
resolve = SpecSet.new(resolve.for(expand_dependencies(deps, true), [], false, false, false).reject{|s| @unlock[:gems].include?(s.name) })
diff = nil
# Now, we unlock any sources that do not have anymore gems pinned to it
@ -909,26 +862,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
@ -984,16 +933,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

View file

@ -31,7 +31,6 @@ module Bundler
settings_flag(:auto_clean_without_path) { bundler_3_mode? }
settings_flag(:cache_all) { bundler_3_mode? }
settings_flag(:default_install_uses_path) { 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? }
@ -39,7 +38,6 @@ module Bundler
settings_flag(:print_only_version_number) { bundler_3_mode? }
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
settings_flag(:update_requires_all_flag) { bundler_4_mode? }
settings_flag(:use_gem_version_promoter_for_major_updates) { bundler_3_mode? }

View file

@ -116,7 +116,7 @@ module Bundler
def bundle_worker(func = nil)
@bundle_worker ||= begin
worker_name = "Compact Index (#{display_uri.host})"
Bundler::Worker.new(Bundler.current_ruby.rbx? ? 1 : 25, worker_name, func)
Bundler::Worker.new(Bundler.settings.processor_count, worker_name, func)
end
@bundle_worker.tap do |worker|
worker.instance_variable_set(:@func, func) if func

View file

@ -68,8 +68,7 @@ module Bundler
raise CertificateFailureError.new(uri)
rescue *HTTP_ERRORS => e
Bundler.ui.trace e
case e.message
when /host down:/, /getaddrinfo: nodename nor servname provided/
if e.is_a?(SocketError) || e.message =~ /host down:/
raise NetworkDownError, "Could not reach host #{uri.host}. Check your network " \
"connection and try again."
else

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true
require_relative "base"
require "rubygems/remote_fetcher"
module Bundler
class Fetcher

View file

@ -49,8 +49,6 @@ module Bundler
"Alternatively, you can increase the amount of memory the JVM is able to use by running Bundler with jruby -J-Xmx1024m -S bundle (JRuby defaults to 500MB)."
else request_issue_report_for(error)
end
rescue StandardError
raise error
end
def exit_status(error)
@ -111,8 +109,8 @@ module Bundler
First, try this link to see if there are any existing issue reports for this error:
#{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
If there aren't any reports for this error yet, please 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&template=bundler-related-issue.md
EOS
end

View file

@ -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

View file

@ -222,14 +222,7 @@ module Bundler
# Parallelization has some issues on Windows, so it's not yet the default
return 1 if Gem.win_platform?
processor_count
end
def processor_count
require "etc"
Etc.nprocessors
rescue StandardError
1
Bundler.settings.processor_count
end
def load_plugins

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory

View file

@ -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" "June 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
@ -280,9 +274,6 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBtimeout\fR (\fBBUNDLE_TIMEOUT\fR): The seconds allowed before timing out for network requests\. Defaults to \fB10\fR\.
.
.IP "\(bu" 4
\fBunlock_source_unlocks_spec\fR (\fBBUNDLE_UNLOCK_SOURCE_UNLOCKS_SPEC\fR): Whether running \fBbundle update \-\-source NAME\fR unlocks a gem with the given name\. Defaults to \fBtrue\fR\.
.
.IP "\(bu" 4
\fBupdate_requires_all_flag\fR (\fBBUNDLE_UPDATE_REQUIRES_ALL_FLAG\fR): Require passing \fB\-\-all\fR to \fBbundle update\fR when everything should be updated, and disallow passing no options to \fBbundle update\fR\.
.
.IP "\(bu" 4

View file

@ -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`):
@ -268,9 +260,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
The location where RubyGems installs binstubs. Defaults to `Gem.bindir`.
* `timeout` (`BUNDLE_TIMEOUT`):
The seconds allowed before timing out for network requests. Defaults to `10`.
* `unlock_source_unlocks_spec` (`BUNDLE_UNLOCK_SOURCE_UNLOCKS_SPEC`):
Whether running `bundle update --source NAME` unlocks a gem with the given
name. Defaults to `true`.
* `update_requires_all_flag` (`BUNDLE_UPDATE_REQUIRES_ALL_FLAG`):
Require passing `--all` to `bundle update` when everything should be updated,
and disallow passing no options to `bundle update`.

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions
@ -79,7 +79,7 @@ Do not allow any gem to be updated past latest \fB\-\-patch\fR | \fB\-\-minor\fR
.
.TP
\fB\-\-conservative\fR
Use bundle install conservative update behavior and do not allow shared dependencies to be updated\.
Use bundle install conservative update behavior and do not allow indirect dependencies to be updated\.
.
.SH "UPDATING ALL GEMS"
If you run \fBbundle update \-\-all\fR, bundler will ignore any previously installed gems and resolve all dependencies again based on the latest versions of all gems available in the sources\.
@ -208,13 +208,13 @@ In this case, the two gems have their own set of dependencies, but they share \f
In short, by default, when you update a gem using \fBbundle update\fR, bundler will update all dependencies of that gem, including those that are also dependencies of another gem\.
.
.P
To prevent updating shared dependencies, prior to version 1\.14 the only option was the \fBCONSERVATIVE UPDATING\fR behavior in bundle install(1) \fIbundle\-install\.1\.html\fR:
To prevent updating indirect dependencies, prior to version 1\.14 the only option was the \fBCONSERVATIVE UPDATING\fR behavior in bundle install(1) \fIbundle\-install\.1\.html\fR:
.
.P
In this scenario, updating the \fBthin\fR version manually in the Gemfile(5), and then running bundle install(1) \fIbundle\-install\.1\.html\fR will only update \fBdaemons\fR and \fBeventmachine\fR, but not \fBrack\fR\. For more information, see the \fBCONSERVATIVE UPDATING\fR section of bundle install(1) \fIbundle\-install\.1\.html\fR\.
.
.P
Starting with 1\.14, specifying the \fB\-\-conservative\fR option will also prevent shared dependencies from being updated\.
Starting with 1\.14, specifying the \fB\-\-conservative\fR option will also prevent indirect dependencies from being updated\.
.
.SH "PATCH LEVEL OPTIONS"
Version 1\.14 introduced 4 patch\-level options that will influence how gem versions are resolved\. One of the following options can be used: \fB\-\-patch\fR, \fB\-\-minor\fR or \fB\-\-major\fR\. \fB\-\-strict\fR can be added to further influence resolution\.

View file

@ -80,7 +80,7 @@ gem.
Do not allow any gem to be updated past latest `--patch` | `--minor` | `--major`.
* `--conservative`:
Use bundle install conservative update behavior and do not allow shared dependencies to be updated.
Use bundle install conservative update behavior and do not allow indirect dependencies to be updated.
## UPDATING ALL GEMS
@ -195,7 +195,7 @@ In short, by default, when you update a gem using `bundle update`, bundler will
update all dependencies of that gem, including those that are also dependencies
of another gem.
To prevent updating shared dependencies, prior to version 1.14 the only option
To prevent updating indirect dependencies, prior to version 1.14 the only option
was the `CONSERVATIVE UPDATING` behavior in [bundle install(1)](bundle-install.1.html):
In this scenario, updating the `thin` version manually in the Gemfile(5),
@ -203,7 +203,7 @@ and then running [bundle install(1)](bundle-install.1.html) will only update `da
but not `rack`. For more information, see the `CONSERVATIVE UPDATING` section
of [bundle install(1)](bundle-install.1.html).
Starting with 1.14, specifying the `--conservative` option will also prevent shared
Starting with 1.14, specifying the `--conservative` option will also prevent indirect
dependencies from being updated.
## PATCH LEVEL OPTIONS

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management

View file

@ -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" "June 2021" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs

View file

@ -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

View file

@ -21,23 +21,19 @@ 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).for(requirements.reject{|dep| dep.name.end_with?("\0") })
SpecSet.new(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 = {}
@base_dg = Molinillo::DependencyGraph.new
aggregate_global_source = @source_requirements[:default].is_a?(Source::RubygemsAggregate)
@base.each do |ls|
dep = Dependency.new(ls.name, ls.version)
ls.source = source_for(ls.name) unless aggregate_global_source
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
end
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
@ -45,7 +41,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?
end
def start(requirements)
@ -55,7 +50,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).
@ -171,16 +165,11 @@ module Bundler
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)
@ -211,23 +200,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,
@ -369,7 +345,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(" ")
@ -386,11 +362,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")
@ -403,12 +375,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,
@ -422,27 +392,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

View file

@ -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

View file

@ -526,13 +526,14 @@ module Bundler
Bundler::Retry.new("download gem from #{uri}").attempts do
fetcher.download(spec, uri, path)
end
rescue Gem::RemoteFetcher::FetchError => e
raise Bundler::HTTPError, "Could not download gem from #{uri} due to underlying error <#{e.message}>"
end
def gem_remote_fetcher
require "resolv"
require "rubygems/remote_fetcher"
proxy = configuration[:http_proxy]
dns = Resolv::DNS.new
Gem::RemoteFetcher.new(proxy, dns)
Gem::RemoteFetcher.new(proxy)
end
def gem_from_path(path, policy = nil)

View file

@ -20,7 +20,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
@ -45,7 +44,6 @@ module Bundler
silence_deprecations
silence_root_warning
suppress_install_using_messages
unlock_source_unlocks_spec
update_requires_all_flag
use_gem_version_promoter_for_major_updates
].freeze
@ -210,6 +208,13 @@ module Bundler
locations
end
def processor_count
require "etc"
Etc.nprocessors
rescue StandardError
1
end
# for legacy reasons, in Bundler 2, we do not respect :disable_shared_gems
def path
configs.each do |_level, settings|
@ -442,7 +447,20 @@ module Bundler
valid_file = file.exist? && !file.size.zero?
return {} unless valid_file
require_relative "yaml_serializer"
YAMLSerializer.load file.read
YAMLSerializer.load(file.read).inject({}) do |config, (k, v)|
new_k = k
if k.include?("-")
Bundler.ui.warn "Your #{file} config includes `#{k}`, which contains the dash character (`-`).\n" \
"This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
"Please edit #{file} and replace any dashes in configuration keys with a triple underscore (`___`)."
new_k = k.gsub("-", "___")
end
config[new_k] = v
config
end
end
end

View file

@ -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
@ -35,10 +36,16 @@ module Bundler
def local!; end
def local_only!; end
def cached!; end
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 +55,10 @@ module Bundler
specs.dependency_names
end
def spec_names
specs.spec_names
end
def include?(other)
other == self
end

View file

@ -26,6 +26,12 @@ module Bundler
Array(options["remotes"]).reverse_each {|r| add_remote(r) }
end
def local_only!
@specs = nil
@allow_local = true
@allow_remote = false
end
def local!
return if @allow_local
@ -61,13 +67,13 @@ module Bundler
o.is_a?(Rubygems) && (o.credless_remotes - credless_remotes).empty?
end
def disable_multisource?
@remotes.size <= 1
def multiple_remotes?
@remotes.size > 1
end
def can_lock?(spec)
return super if disable_multisource?
spec.source.is_a?(Rubygems)
return super unless multiple_remotes?
include?(spec.source)
end
def options
@ -259,8 +265,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 +290,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 +312,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
@ -387,10 +404,6 @@ module Bundler
next if gemfile =~ /^bundler\-[\d\.]+?\.gem/
s ||= Bundler.rubygems.spec_from_gem(gemfile)
s.source = self
if Bundler.rubygems.spec_missing_extensions?(s, false)
Bundler.ui.debug "Source #{self} is ignoring #{s} because it is missing extensions"
next
end
idx << s
end

View file

@ -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

View file

@ -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 aggregate_global_source?
global_rubygems_source.multiple_remotes?
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
@ -113,6 +132,10 @@ module Bundler
false
end
def local_only!
all_sources.each(&:local_only!)
end
def cached!
all_sources.each(&:cached!)
end
@ -162,6 +185,8 @@ module Bundler
end
def equal_source?(source, other_source)
return source.include?(other_source) if source.is_a?(Source::Rubygems) && other_source.is_a?(Source::Rubygems) && !merged_gem_lockfile_sections?
source == other_source
end

58
lib/bundler/source_map.rb Normal file
View file

@ -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

View file

@ -46,11 +46,7 @@ module Bundler
specs << spec
end
check ? true : SpecSet.new(specs)
end
def valid_for?(deps)
self.for(deps, [], true)
check ? true : specs
end
def [](key)
@ -77,7 +73,7 @@ module Bundler
end
def materialize(deps, missing_specs = nil)
materialized = self.for(deps, [], false, true, !missing_specs).to_a
materialized = self.for(deps, [], false, true, !missing_specs)
materialized.group_by(&:source).each do |source, specs|
next unless specs.any?{|s| s.is_a?(LazySpecification) }

View file

@ -14,9 +14,9 @@ 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'"
spec.metadata["allowed_push_host"] = "TODO: Set to 'https://mygemserver.com'"
spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."

View file

@ -355,6 +355,8 @@ class Gem::Command
def add_option(*opts, &handler) # :yields: value, options
group_name = Symbol === opts.first ? opts.shift : :options
raise "Do not pass an empty string in opts" if opts.include?("")
@option_groups[group_name] << [opts, handler]
end

View file

@ -23,7 +23,7 @@ class Gem::Commands::BuildCommand < Gem::Command
options[:output] = value
end
add_option '-C PATH', '', 'Run as if gem build was started in <PATH> instead of the current working directory.' do |value, options|
add_option '-C PATH', 'Run as if gem build was started in <PATH> instead of the current working directory.' do |value, options|
options[:build_path] = value
end
end

View file

@ -7,37 +7,9 @@ class Gem::Commands::CertCommand < Gem::Command
super 'cert', 'Manage RubyGems certificates and signing settings',
:add => [], :remove => [], :list => [], :build => [], :sign => []
OptionParser.accept OpenSSL::X509::Certificate do |certificate_file|
begin
certificate = OpenSSL::X509::Certificate.new File.read certificate_file
rescue Errno::ENOENT
raise OptionParser::InvalidArgument, "#{certificate_file}: does not exist"
rescue OpenSSL::X509::CertificateError
raise OptionParser::InvalidArgument,
"#{certificate_file}: invalid X509 certificate"
end
[certificate, certificate_file]
end
OptionParser.accept OpenSSL::PKey::RSA do |key_file|
begin
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
key = OpenSSL::PKey::RSA.new File.read(key_file), passphrase
rescue Errno::ENOENT
raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
rescue OpenSSL::PKey::RSAError
raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA key"
end
raise OptionParser::InvalidArgument,
"#{key_file}: private key not found" unless key.private?
key
end
add_option('-a', '--add CERT', OpenSSL::X509::Certificate,
'Add a trusted certificate.') do |(cert, _), options|
options[:add] << cert
add_option('-a', '--add CERT',
'Add a trusted certificate.') do |cert_file, options|
options[:add] << open_cert(cert_file)
end
add_option('-l', '--list [FILTER]',
@ -60,15 +32,15 @@ class Gem::Commands::CertCommand < Gem::Command
options[:build] << email_address
end
add_option('-C', '--certificate CERT', OpenSSL::X509::Certificate,
'Signing certificate for --sign') do |(cert, cert_file), options|
options[:issuer_cert] = cert
add_option('-C', '--certificate CERT',
'Signing certificate for --sign') do |cert_file, options|
options[:issuer_cert] = open_cert(cert_file)
options[:issuer_cert_file] = cert_file
end
add_option('-K', '--private-key KEY', OpenSSL::PKey::RSA,
'Key for --sign or --build') do |key, options|
options[:key] = key
add_option('-K', '--private-key KEY',
'Key for --sign or --build') do |key_file, options|
options[:key] = open_private_key(key_file)
end
add_option('-s', '--sign CERT',
@ -97,7 +69,39 @@ class Gem::Commands::CertCommand < Gem::Command
say "Added '#{certificate.subject}'"
end
def check_openssl
return if Gem::HAVE_OPENSSL
alert_error "OpenSSL library is required for the cert command"
terminate_interaction 1
end
def open_cert(certificate_file)
check_openssl
OpenSSL::X509::Certificate.new File.read certificate_file
rescue Errno::ENOENT
raise OptionParser::InvalidArgument, "#{certificate_file}: does not exist"
rescue OpenSSL::X509::CertificateError
raise OptionParser::InvalidArgument,
"#{certificate_file}: invalid X509 certificate"
end
def open_private_key(key_file)
check_openssl
passphrase = ENV['GEM_PRIVATE_KEY_PASSPHRASE']
key = OpenSSL::PKey::RSA.new File.read(key_file), passphrase
raise OptionParser::InvalidArgument,
"#{key_file}: private key not found" unless key.private?
key
rescue Errno::ENOENT
raise OptionParser::InvalidArgument, "#{key_file}: does not exist"
rescue OpenSSL::PKey::RSAError
raise OptionParser::InvalidArgument, "#{key_file}: invalid RSA key"
end
def execute
check_openssl
options[:add].each do |certificate|
add_certificate certificate
end
@ -311,4 +315,4 @@ For further reading on signing gems see `ri Gem::Security`.
# It's simple, but is all we need
email =~ /\A.+@.+\z/
end
end if Gem::HAVE_OPENSSL
end

View file

@ -320,7 +320,7 @@ if you believe they were disclosed to a third party.
config = load_file(credentials_path).merge(host => api_key)
dirname = File.dirname credentials_path
Dir.mkdir(dirname) unless File.exist? dirname
FileUtils.mkdir_p(dirname) unless File.exist? dirname
Gem.load_yaml

View file

@ -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

View file

@ -728,6 +728,10 @@ class Gem::Installer
raise Gem::InstallError, "#{spec} has an invalid extensions"
end
if spec.platform.to_s =~ /\R/
raise Gem::InstallError, "#{spec.platform} is an invalid platform"
end
unless spec.specification_version.to_s =~ /\A\d+\z/
raise Gem::InstallError, "#{spec} has an invalid specification_version"
end

View file

@ -44,7 +44,7 @@ class Gem::Request
end
def self.configure_connection_for_https(connection, cert_files)
raise Gem::Exception.new('OpenSSl is not available. Install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources') unless Gem::HAVE_OPENSSL
raise Gem::Exception.new('OpenSSL is not available. Install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources') unless Gem::HAVE_OPENSSL
connection.use_ssl = true
connection.verify_mode =

View file

@ -2421,7 +2421,6 @@ class Gem::Specification < Gem::BasicSpecification
# still have their default values are omitted.
def to_ruby
require_relative 'openssl'
mark_version
result = []
result << "# -*- encoding: utf-8 -*-"
@ -2455,16 +2454,21 @@ class Gem::Specification < Gem::BasicSpecification
:has_rdoc,
:default_executable,
:metadata,
:signing_key,
]
@@attributes.each do |attr_name|
next if handled.include? attr_name
current_value = self.send(attr_name)
if current_value != default_value(attr_name) || self.class.required_attribute?(attr_name)
result << " s.#{attr_name} = #{ruby_code current_value}" unless defined?(OpenSSL::PKey::RSA) && current_value.is_a?(OpenSSL::PKey::RSA)
result << " s.#{attr_name} = #{ruby_code current_value}"
end
end
if String === signing_key
result << " s.signing_key = #{signing_key.dump}.freeze"
end
if @installed_by_version
result << nil
result << " s.installed_by_version = \"#{Gem::VERSION}\" if s.respond_to? :installed_by_version"

View file

@ -124,25 +124,26 @@ class Gem::SpecificationPolicy
end
metadata.each do |key, value|
entry = "metadata['#{key}']"
if !key.kind_of?(String)
error "metadata keys must be a String"
end
if key.size > 128
error "metadata key too large (#{key.size} > 128)"
error "metadata key is too large (#{key.size} > 128)"
end
if !value.kind_of?(String)
error "metadata values must be a String"
error "#{entry} value must be a String"
end
if value.size > 1024
error "metadata value too large (#{value.size} > 1024)"
error "#{entry} value is too large (#{value.size} > 1024)"
end
if METADATA_LINK_KEYS.include? key
if value !~ VALID_URI_PATTERN
error "metadata['#{key}'] has invalid link: #{value.inspect}"
error "#{entry} has invalid link: #{value.inspect}"
end
end
end

View file

@ -261,7 +261,10 @@ class Gem::Uninstaller
safe_delete { FileUtils.rm_r gem }
Gem::RDoc.new(spec).remove
begin
Gem::RDoc.new(spec).remove
rescue NameError
end
gemspec = spec.spec_file

View file

@ -18,6 +18,8 @@ class Gem::Licenses
AFL-2.1
AFL-3.0
AGPL-1.0
AGPL-1.0-only
AGPL-1.0-or-later
AGPL-3.0
AGPL-3.0-only
AGPL-3.0-or-later
@ -25,6 +27,7 @@ class Gem::Licenses
AML
AMPAS
ANTLR-PD
ANTLR-PD-fallback
APAFML
APL-1.0
APSL-1.0
@ -48,29 +51,41 @@ class Gem::Licenses
BSD-2-Clause-FreeBSD
BSD-2-Clause-NetBSD
BSD-2-Clause-Patent
BSD-2-Clause-Views
BSD-3-Clause
BSD-3-Clause-Attribution
BSD-3-Clause-Clear
BSD-3-Clause-LBNL
BSD-3-Clause-Modification
BSD-3-Clause-No-Military-License
BSD-3-Clause-No-Nuclear-License
BSD-3-Clause-No-Nuclear-License-2014
BSD-3-Clause-No-Nuclear-Warranty
BSD-3-Clause-Open-MPI
BSD-4-Clause
BSD-4-Clause-Shortened
BSD-4-Clause-UC
BSD-Protection
BSD-Source-Code
BSL-1.0
BUSL-1.1
Bahyph
Barr
Beerware
BitTorrent-1.0
BitTorrent-1.1
BlueOak-1.0.0
Borceux
C-UDA-1.0
CAL-1.0
CAL-1.0-Combined-Work-Exception
CATOSL-1.1
CC-BY-1.0
CC-BY-2.0
CC-BY-2.5
CC-BY-3.0
CC-BY-3.0-AT
CC-BY-3.0-US
CC-BY-4.0
CC-BY-NC-1.0
CC-BY-NC-2.0
@ -81,6 +96,7 @@ class Gem::Licenses
CC-BY-NC-ND-2.0
CC-BY-NC-ND-2.5
CC-BY-NC-ND-3.0
CC-BY-NC-ND-3.0-IGO
CC-BY-NC-ND-4.0
CC-BY-NC-SA-1.0
CC-BY-NC-SA-2.0
@ -94,12 +110,17 @@ class Gem::Licenses
CC-BY-ND-4.0
CC-BY-SA-1.0
CC-BY-SA-2.0
CC-BY-SA-2.0-UK
CC-BY-SA-2.1-JP
CC-BY-SA-2.5
CC-BY-SA-3.0
CC-BY-SA-3.0-AT
CC-BY-SA-4.0
CC-PDDC
CC0-1.0
CDDL-1.0
CDDL-1.1
CDL-1.0
CDLA-Permissive-1.0
CDLA-Sharing-1.0
CECILL-1.0
@ -108,6 +129,11 @@ class Gem::Licenses
CECILL-2.1
CECILL-B
CECILL-C
CERN-OHL-1.1
CERN-OHL-1.2
CERN-OHL-P-2.0
CERN-OHL-S-2.0
CERN-OHL-W-2.0
CNRI-Jython
CNRI-Python
CNRI-Python-GPL-Compatible
@ -123,12 +149,14 @@ class Gem::Licenses
Cube
D-FSL-1.0
DOC
DRL-1.0
DSDP
Dotseqn
ECL-1.0
ECL-2.0
EFL-1.0
EFL-2.0
EPICS
EPL-1.0
EPL-2.0
EUDatagrid
@ -144,17 +172,32 @@ class Gem::Licenses
FTL
Fair
Frameworx-1.0
FreeBSD-DOC
FreeImage
GD
GFDL-1.1
GFDL-1.1-invariants-only
GFDL-1.1-invariants-or-later
GFDL-1.1-no-invariants-only
GFDL-1.1-no-invariants-or-later
GFDL-1.1-only
GFDL-1.1-or-later
GFDL-1.2
GFDL-1.2-invariants-only
GFDL-1.2-invariants-or-later
GFDL-1.2-no-invariants-only
GFDL-1.2-no-invariants-or-later
GFDL-1.2-only
GFDL-1.2-or-later
GFDL-1.3
GFDL-1.3-invariants-only
GFDL-1.3-invariants-or-later
GFDL-1.3-no-invariants-only
GFDL-1.3-no-invariants-or-later
GFDL-1.3-only
GFDL-1.3-or-later
GL2PS
GLWTPL
GPL-1.0
GPL-1.0+
GPL-1.0-only
@ -178,7 +221,10 @@ class Gem::Licenses
Glide
Glulxe
HPND
HPND-sell-variant
HTMLTIDY
HaskellReport
Hippocratic-2.1
IBM-pibs
ICU
IJG
@ -191,6 +237,7 @@ class Gem::Licenses
Intel
Intel-ACPI
Interbase-1.0
JPNIC
JSON
JasPer-2.0
LAL-1.2
@ -221,11 +268,15 @@ class Gem::Licenses
LiLiQ-R-1.1
LiLiQ-Rplus-1.1
Libpng
Linux-OpenIB
MIT
MIT-0
MIT-CMU
MIT-Modern-Variant
MIT-advertising
MIT-enna
MIT-feh
MIT-open-group
MITNFA
MPL-1.0
MPL-1.1
@ -237,12 +288,18 @@ class Gem::Licenses
MakeIndex
MirOS
Motosoto
MulanPSL-1.0
MulanPSL-2.0
Multics
Mup
NAIST-2003
NASA-1.3
NBPL-1.0
NCGL-UK-2.0
NCSA
NGPL
NIST-PD
NIST-PD-fallback
NLOD-1.0
NLPL
NOSL
@ -251,6 +308,7 @@ class Gem::Licenses
NPOSL-3.0
NRL
NTP
NTP-0
Naumen
Net-SNMP
NetCDF
@ -258,11 +316,23 @@ class Gem::Licenses
Nokia
Noweb
Nunit
O-UDA-1.0
OCCT-PL
OCLC-2.0
ODC-By-1.0
ODbL-1.0
OFL-1.0
OFL-1.0-RFN
OFL-1.0-no-RFN
OFL-1.1
OFL-1.1-RFN
OFL-1.1-no-RFN
OGC-1.0
OGDL-Taiwan-1.0
OGL-Canada-2.0
OGL-UK-1.0
OGL-UK-2.0
OGL-UK-3.0
OGTSL
OLDAP-1.1
OLDAP-1.2
@ -292,7 +362,12 @@ class Gem::Licenses
PDDL-1.0
PHP-3.0
PHP-3.01
PSF-2.0
Parity-6.0.0
Parity-7.0.0
Plexus
PolyForm-Noncommercial-1.0.0
PolyForm-Small-Business-1.0.0
PostgreSQL
Python-2.0
QPL-1.0
@ -310,15 +385,21 @@ class Gem::Licenses
SGI-B-1.0
SGI-B-1.1
SGI-B-2.0
SHL-0.5
SHL-0.51
SISSL
SISSL-1.2
SMLNJ
SMPPL
SNIA
SPL-1.0
SSH-OpenSSH
SSH-short
SSPL-1.0
SWL
Saxpath
Sendmail
Sendmail-8.23
SimPL-2.0
Sleepycat
Spencer-86
@ -326,11 +407,15 @@ class Gem::Licenses
Spencer-99
StandardML-NJ
SugarCRM-1.1.3
TAPR-OHL-1.0
TCL
TCP-wrappers
TMate
TORQUE-1.1
TOSL
TU-Berlin-1.0
TU-Berlin-2.0
UCL-1.0
UPL-1.0
Unicode-DFS-2015
Unicode-DFS-2016
@ -360,16 +445,22 @@ class Gem::Licenses
Zimbra-1.3
Zimbra-1.4
Zlib
blessing
bzip2-1.0.5
bzip2-1.0.6
copyleft-next-0.3.0
copyleft-next-0.3.1
curl
diffmark
dvipdfm
eCos-2.0
eGenix
etalab-2.0
gSOAP-1.3b
gnuplot
iMatix
libpng-2.0
libselinux-1.0
libtiff
mpich2
psfrag
@ -395,12 +486,26 @@ class Gem::Licenses
Font-exception-2.0
GCC-exception-2.0
GCC-exception-3.1
GPL-3.0-linking-exception
GPL-3.0-linking-source-exception
GPL-CC-1.0
LGPL-3.0-linking-exception
LLVM-exception
LZMA-exception
Libtool-exception
Linux-syscall-note
Nokia-Qt-exception-1.1
OCCT-exception-1.0
OCaml-LGPL-linking-exception
OpenJDK-assembly-exception-1.0
PS-or-PDF-font-exception-20170817
Qt-GPL-exception-1.0
Qt-LGPL-exception-1.1
Qwt-exception-1.0
SHL-2.0
SHL-2.1
Swift-exception
Universal-FOSS-exception-1.0
WxWindows-exception-3.1
eCos-exception-2.0
freertos-exception-2.0
@ -413,10 +518,10 @@ class Gem::Licenses
REGEXP = %r{
\A
(
(?:
#{Regexp.union(LICENSE_IDENTIFIERS)}
\+?
(\s WITH \s #{Regexp.union(EXCEPTION_IDENTIFIERS)})?
(?:\s WITH \s #{Regexp.union(EXCEPTION_IDENTIFIERS)})?
| #{NONSTANDARD}
)
\Z

View file

@ -268,7 +268,7 @@ RSpec.describe Bundler::Definition do
bundled_app_lock,
updated_deps_in_gemfile,
source_list,
:gems => ["shared_owner_a"], :lock_shared_dependencies => true
:gems => ["shared_owner_a"], :conservative => true
)
locked = definition.send(:converge_locked_specs).map(&:name)
expect(locked).to eq %w[isolated_dep isolated_owner shared_dep shared_owner_b]
@ -278,33 +278,6 @@ RSpec.describe Bundler::Definition do
end
end
describe "find_resolved_spec" do
it "with no platform set in SpecSet" do
ss = Bundler::SpecSet.new([build_stub_spec("a", "1.0"), build_stub_spec("b", "1.0")])
dfn = Bundler::Definition.new(nil, [], mock_source_list, true)
dfn.instance_variable_set("@specs", ss)
found = dfn.find_resolved_spec(build_spec("a", "0.9", "ruby").first)
expect(found.name).to eq "a"
expect(found.version.to_s).to eq "1.0"
end
end
describe "find_indexed_specs" do
it "with no platform set in indexed specs" do
index = Bundler::Index.new
%w[1.0.0 1.0.1 1.1.0].each {|v| index << build_stub_spec("foo", v) }
dfn = Bundler::Definition.new(nil, [], mock_source_list, true)
dfn.instance_variable_set("@index", index)
found = dfn.find_indexed_specs(build_spec("foo", "0.9", "ruby").first)
expect(found.length).to eq 3
end
end
def build_stub_spec(name, version)
Bundler::StubSpecification.new(name, version, nil, nil)
end
def mock_source_list
Class.new do
def all_sources

View file

@ -231,16 +231,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
end
context "when error message is about getaddrinfo issues" do
let(:message) { "getaddrinfo: nodename nor servname provided for http://www.uri-to-fetch.com" }
it "should raise a Bundler::Fetcher::NetworkDownError" do
expect { subject.request(uri, options) }.to raise_error(Bundler::Fetcher::NetworkDownError,
/Could not reach host www.uri-to-fetch.com/)
end
end
context "when error message is about neither host down or getaddrinfo" do
context "when error message is not about host down" do
let(:message) { "other error about network" }
it "should raise a Bundler::HTTPError" do

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true
require "rubygems/remote_fetcher"
RSpec.describe Bundler::Fetcher::Index do
let(:downloader) { nil }
let(:remote) { nil }

View file

@ -312,16 +312,26 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
describe "BUNDLE_ keys format" do
let(:settings) { described_class.new(bundled_app(".bundle")) }
it "converts older keys without double dashes" do
it "converts older keys without double underscore" do
config("BUNDLE_MY__PERSONAL.RACK" => "~/Work/git/rack")
expect(settings["my.personal.rack"]).to eq("~/Work/git/rack")
end
it "converts older keys without trailing slashes and double dashes" do
it "converts older keys without trailing slashes and double underscore" do
config("BUNDLE_MIRROR__HTTPS://RUBYGEMS.ORG" => "http://rubygems-mirror.org")
expect(settings["mirror.https://rubygems.org/"]).to eq("http://rubygems-mirror.org")
end
it "converts older keys with dashes" do
config("BUNDLE_MY-PERSONAL-SERVER__ORG" => "my-personal-server.org")
expect(Bundler.ui).to receive(:warn).with(
"Your #{bundled_app(".bundle/config")} config includes `BUNDLE_MY-PERSONAL-SERVER__ORG`, which contains the dash character (`-`).\n" \
"This is deprecated, because configuration through `ENV` should be possible, but `ENV` keys cannot include dashes.\n" \
"Please edit #{bundled_app(".bundle/config")} and replace any dashes in configuration keys with a triple underscore (`___`)."
)
expect(settings["my-personal-server.org"]).to eq("my-personal-server.org")
end
it "reads newer keys format properly" do
config("BUNDLE_MIRROR__HTTPS://RUBYGEMS__ORG/" => "http://rubygems-mirror.org")
expect(settings["mirror.https://rubygems.org/"]).to eq("http://rubygems-mirror.org")

View file

@ -298,6 +298,30 @@ RSpec.describe "bundle cache" do
expect(out).to include("frozen").or include("deployment")
end
end
context "with gems with extensions" do
before do
build_repo2 do
build_gem "racc", "2.0" do |s|
s.add_dependency "rake"
s.extensions << "Rakefile"
s.write "Rakefile", "task(:default) { puts 'INSTALLING rack' }"
end
end
gemfile <<~G
source "#{file_uri_for(gem_repo2)}"
gem "racc"
G
end
it "installs them properly from cache to a different path" do
bundle "cache"
bundle "config set --local path vendor/bundle"
bundle "install --local"
end
end
end
RSpec.describe "bundle install with gem sources" do
@ -317,7 +341,7 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "does not hit the remote at all" do
it "does not hit the remote at all in frozen mode" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
@ -334,6 +358,24 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "does not hit the remote at all when cache_all_platforms configured" do
build_repo2
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "rack"
G
bundle :cache
simulate_new_machine
FileUtils.rm_rf gem_repo2
bundle "config set --local cache_all_platforms true"
bundle "config set --local path vendor/bundle"
bundle "install --local"
expect(out).not_to include("Fetching gem metadata")
expect(the_bundle).to include_gems "rack 1.0.0"
end
it "does not reinstall already-installed gems" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"

View file

@ -288,6 +288,66 @@ RSpec.describe "bundle check" do
end
end
describe "when using only scoped rubygems sources" do
before do
gemfile <<~G
source "#{file_uri_for(gem_repo1)}" do
gem "rack"
end
G
end
it "returns success when the Gemfile is satisfied" do
system_gems "rack-1.0.0", :path => default_bundle_path
bundle :check
expect(out).to include("The Gemfile's dependencies are satisfied")
end
end
describe "when using only scoped rubygems sources with indirect dependencies" do
before do
build_repo4 do
build_gem "depends_on_rack" do |s|
s.add_dependency "rack"
end
build_gem "rack"
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}" do
gem "depends_on_rack"
end
G
end
it "returns success when the Gemfile is satisfied and generates a correct lockfile" do
system_gems "depends_on_rack-1.0", "rack-1.0", :gem_repo => gem_repo4, :path => default_bundle_path
bundle :check
expect(out).to include("The Gemfile's dependencies are satisfied")
expect(lockfile).to eq <<~L
GEM
specs:
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
depends_on_rack (1.0)
rack
rack (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
depends_on_rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
end
describe "BUNDLED WITH" do
def lock_with(bundler_version = nil)
lock = <<-L

View file

@ -533,7 +533,7 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION}
L
bundle "lock --add-platform x86_64-linux", :artifice => :compact_index, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
bundle "lock --add-platform x86_64-linux", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end
context "when an update is available" do

View file

@ -205,8 +205,8 @@ RSpec.describe "bundle outdated" do
end
it "works" do
bundle :install, :artifice => :compact_index
bundle :outdated, :artifice => :compact_index, :raise_on_error => false
bundle :install, :artifice => "compact_index"
bundle :outdated, :artifice => "compact_index", :raise_on_error => false
expected_output = <<~TABLE
Gem Current Latest Requested Groups
@ -1292,4 +1292,53 @@ RSpec.describe "bundle outdated" do
expect(out).to end_with(expected_output)
end
end
context "when a gem is no longer a dependency after a full update" do
before do
build_repo4 do
build_gem "mini_portile2", "2.5.2" do |s|
s.add_dependency "net-ftp", "~> 0.1"
end
build_gem "mini_portile2", "2.5.3"
build_gem "net-ftp", "0.1.2"
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "mini_portile2"
G
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
mini_portile2 (2.5.2)
net-ftp (~> 0.1)
net-ftp (0.1.2)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
mini_portile2
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "works" do
bundle "outdated", :raise_on_error => false
expected_output = <<~TABLE.strip
Gem Current Latest Requested Groups
mini_portile2 2.5.2 2.5.3 >= 0 default
TABLE
expect(out).to end_with(expected_output)
end
end
end

View file

@ -411,18 +411,7 @@ RSpec.describe "bundle update" do
build_repo2
end
it "should not update gems not included in the source that happen to have the same name", :bundler => "< 3" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
G
update_repo2 { build_gem "activesupport", "3.0" }
bundle "update --source activesupport"
expect(the_bundle).to include_gem "activesupport 3.0"
end
it "should not update gems not included in the source that happen to have the same name", :bundler => "3" do
it "should not update gems not included in the source that happen to have the same name" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
@ -433,19 +422,15 @@ RSpec.describe "bundle update" do
expect(the_bundle).not_to include_gem "activesupport 3.0"
end
context "with unlock_source_unlocks_spec set to false" do
before { bundle "config set unlock_source_unlocks_spec false" }
it "should not update gems not included in the source that happen to have the same name" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
G
update_repo2 { build_gem "activesupport", "3.0" }
it "should not update gems not included in the source that happen to have the same name" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "activesupport"
G
update_repo2 { build_gem "activesupport", "3.0" }
bundle "update --source activesupport"
expect(the_bundle).not_to include_gems "activesupport 3.0"
end
bundle "update --source activesupport"
expect(the_bundle).not_to include_gems "activesupport 3.0"
end
end
@ -465,20 +450,7 @@ RSpec.describe "bundle update" do
G
end
it "should not update the child dependencies of a gem that has the same name as the source", :bundler => "< 3" do
update_repo2 do
build_gem "fred", "2.0"
build_gem "harry", "2.0" do |s|
s.add_dependency "fred"
end
end
bundle "update --source harry"
expect(the_bundle).to include_gems "harry 2.0"
expect(the_bundle).to include_gems "fred 1.0"
end
it "should not update the child dependencies of a gem that has the same name as the source", :bundler => "3" do
it "should not update the child dependencies of a gem that has the same name as the source" do
update_repo2 do
build_gem "fred", "2.0"
build_gem "harry", "2.0" do |s|
@ -510,21 +482,7 @@ RSpec.describe "bundle update" do
G
end
it "should not update the child dependencies of a gem that has the same name as the source", :bundler => "< 3" do
update_repo2 do
build_gem "george", "2.0"
build_gem "harry", "2.0" do |s|
s.add_dependency "george"
end
end
bundle "update --source harry"
expect(the_bundle).to include_gems "harry 2.0"
expect(the_bundle).to include_gems "fred 1.0"
expect(the_bundle).to include_gems "george 1.0"
end
it "should not update the child dependencies of a gem that has the same name as the source", :bundler => "3" do
it "should not update the child dependencies of a gem that has the same name as the source" do
update_repo2 do
build_gem "george", "2.0"
build_gem "harry", "2.0" do |s|
@ -649,8 +607,8 @@ RSpec.describe "bundle update" do
end
it "works" do
bundle :install, :artifice => :compact_index
bundle "update oj", :artifice => :compact_index
bundle :install, :artifice => "compact_index"
bundle "update oj", :artifice => "compact_index"
expect(out).to include("Bundle updated!")
expect(the_bundle).to include_gems "oj 3.11.5"
@ -1106,9 +1064,9 @@ RSpec.describe "bundle update conservative" do
gem 'shared_owner_b'
G
lockfile <<-L
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}
remote: #{file_uri_for(gem_repo4)}/
specs:
isolated_dep (2.0.1)
isolated_owner (1.0.1)
@ -1120,12 +1078,12 @@ RSpec.describe "bundle update conservative" do
shared_dep (~> 5.0)
PLATFORMS
ruby
#{specific_local_platform}
DEPENDENCIES
isolated_owner
shared_owner_a
shared_owner_b
isolated_owner
BUNDLED WITH
#{Bundler::VERSION}
@ -1147,7 +1105,42 @@ RSpec.describe "bundle update conservative" do
it "should not eagerly unlock with --conservative" do
bundle "update --conservative shared_owner_a isolated_owner"
expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.2", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.1"
expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.1", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.1"
end
it "should only update direct dependencies when fully updating with --conservative" do
bundle "update --conservative"
expect(the_bundle).to include_gems "isolated_owner 1.0.2", "isolated_dep 2.0.1", "shared_dep 5.0.1", "shared_owner_a 3.0.2", "shared_owner_b 4.0.2"
end
it "should only change direct dependencies when updating the lockfile with --conservative" do
bundle "lock --update --conservative"
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
isolated_dep (2.0.1)
isolated_owner (1.0.2)
isolated_dep (~> 2.0)
shared_dep (5.0.1)
shared_owner_a (3.0.2)
shared_dep (~> 5.0)
shared_owner_b (4.0.2)
shared_dep (~> 5.0)
PLATFORMS
#{specific_local_platform}
DEPENDENCIES
isolated_owner
shared_owner_a
shared_owner_b
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "should match bundle install conservative update behavior when not eagerly unlocking" do

View file

@ -358,7 +358,7 @@ RSpec.describe "bundle install with groups" do
G
ruby <<-R
require "#{lib_dir}/bundler"
require "#{entrypoint}"
Bundler.setup :default
Bundler.require :default
puts RACK

File diff suppressed because it is too large Load diff

View file

@ -141,10 +141,10 @@ RSpec.describe "bundle install with specific platforms" do
2.1.4
L
bundle "install --verbose", :artifice => :compact_index, :env => { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
bundle "install --verbose", :artifice => "compact_index", :env => { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Installing libv8 8.4.255.0 (universal-darwin)")
bundle "add mini_racer --verbose", :artifice => :compact_index, :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
bundle "add mini_racer --verbose", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }
expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)")
end

View file

@ -366,31 +366,6 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(the_bundle).to include_gems "activesupport 1.2.3"
end
it "considers all possible versions of dependencies from all api gem sources when using blocks", :bundler => "< 3" do
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
# repo and installs it.
build_repo4 do
build_gem "activesupport", "1.2.0"
build_gem "somegem", "1.0.0" do |s|
s.add_dependency "activesupport", "1.2.3" # This version exists only in repo1
end
end
gemfile <<-G
source "#{source_uri}"
source "#{source_uri}/extra" do
gem 'somegem', '1.0.0'
end
G
bundle :install, :artifice => "compact_index_extra_api"
expect(the_bundle).to include_gems "somegem 1.0.0"
expect(the_bundle).to include_gems "activesupport 1.2.3"
end
it "prints API output properly with back deps" do
build_repo2 do
build_gem "back_deps" do |s|
@ -467,7 +442,7 @@ The checksum of /versions does not match the checksum provided by the server! So
expect(the_bundle).to include_gems "foo 1.0"
end
it "fetches again when more dependencies are found in subsequent sources using --deployment", :bundler => "< 3" do
it "fetches again when more dependencies are found in subsequent sources using deployment mode", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@ -482,8 +457,8 @@ The checksum of /versions does not match the checksum provided by the server! So
G
bundle :install, :artifice => "compact_index_extra"
bundle "install --deployment", :artifice => "compact_index_extra"
bundle "config --set local deployment true"
bundle :install, :artifice => "compact_index_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end

View file

@ -338,31 +338,6 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "activesupport 1.2.3"
end
it "considers all possible versions of dependencies from all api gem sources using blocks" do
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
# repo and installs it.
build_repo4 do
build_gem "activesupport", "1.2.0"
build_gem "somegem", "1.0.0" do |s|
s.add_dependency "activesupport", "1.2.3" # This version exists only in repo1
end
end
gemfile <<-G
source "#{source_uri}"
source "#{source_uri}/extra" do
gem 'somegem', '1.0.0'
end
G
bundle :install, :artifice => "endpoint_extra_api"
expect(the_bundle).to include_gems "somegem 1.0.0"
expect(the_bundle).to include_gems "activesupport 1.2.3"
end
it "prints API output properly with back deps" do
build_repo2 do
build_gem "back_deps" do |s|
@ -438,7 +413,7 @@ RSpec.describe "gemcutter's dependency API" do
expect(the_bundle).to include_gems "foo 1.0"
end
it "fetches again when more dependencies are found in subsequent sources using --deployment", :bundler => "< 3" do
it "fetches again when more dependencies are found in subsequent sources using deployment mode", :bundler => "< 3" do
build_repo2 do
build_gem "back_deps" do |s|
s.add_dependency "foo"
@ -453,8 +428,8 @@ RSpec.describe "gemcutter's dependency API" do
G
bundle :install, :artifice => "endpoint_extra"
bundle "install --deployment", :artifice => "endpoint_extra"
bundle "config set --local deployment true"
bundle :install, :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0"
end
@ -474,7 +449,6 @@ RSpec.describe "gemcutter's dependency API" do
G
bundle :install, :artifice => "endpoint_extra"
bundle "config set --local deployment true"
bundle "install", :artifice => "endpoint_extra"
expect(the_bundle).to include_gems "back_deps 1.0"

View file

@ -113,6 +113,8 @@ RSpec.describe "global gem caching" do
expect(source2_global_cache("rack-0.9.1.gem")).to exist
bundle :install, :artifice => "compact_index_no_gem", :raise_on_error => false
expect(err).to include("Internal Server Error 500")
expect(err).not_to include("please copy and paste the report template above into a new issue")
# rack 1.0.0 is not installed and rack 0.9.1 is not
expect(the_bundle).not_to include_gems "rack 1.0.0"
expect(the_bundle).not_to include_gems "rack 0.9.1"
@ -126,6 +128,8 @@ RSpec.describe "global gem caching" do
expect(source2_global_cache("rack-0.9.1.gem")).to exist
bundle :install, :artifice => "compact_index_no_gem", :raise_on_error => false
expect(err).to include("Internal Server Error 500")
expect(err).not_to include("please copy and paste the report template above into a new issue")
# rack 0.9.1 is not installed and rack 1.0.0 is not
expect(the_bundle).not_to include_gems "rack 0.9.1"
expect(the_bundle).not_to include_gems "rack 1.0.0"

View file

@ -1347,7 +1347,7 @@ RSpec.describe "the lockfile format" do
expect do
ruby <<-RUBY
require '#{lib_dir}/bundler'
require '#{entrypoint}'
Bundler.setup
RUBY
end.not_to change { File.mtime(bundled_app_lock) }

View file

@ -409,10 +409,38 @@ RSpec.describe "major deprecations" do
)
end
it "doesn't show lockfile deprecations if there's a lockfile", :bundler => "< 3" do
bundle "install"
expect(deprecations).to include(
"Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source."
)
expect(deprecations).not_to include(
"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."
)
bundle "config set --local frozen true"
bundle "install"
expect(deprecations).to include(
"Your Gemfile contains multiple primary sources. " \
"Using `source` more than once without a block is a security risk, and " \
"may result in installing unexpected gems. To resolve this warning, use " \
"a block to indicate which gems should come from the secondary source."
)
expect(deprecations).not_to include(
"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."
)
end
pending "fails with a helpful error", :bundler => "3"
end
context "bundle install with a lockfile with a single rubygems section with multiple remotes" do
context "bundle install in frozen mode with a lockfile with a single rubygems section with multiple remotes" do
before do
build_repo gem_repo3 do
build_gem "rack", "0.9.1"
@ -441,12 +469,14 @@ RSpec.describe "major deprecations" do
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "config set --local frozen true"
end
it "shows a deprecation", :bundler => "< 3" do
bundle "install"
expect(deprecations).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. You should run `bundle update` or generate your lockfile from scratch.")
expect(deprecations).to include("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.")
end
pending "fails with a helpful error", :bundler => "3"
@ -461,7 +491,7 @@ RSpec.describe "major deprecations" do
G
ruby <<-RUBY
require '#{lib_dir}/bundler'
require '#{entrypoint}'
Bundler.setup
Bundler.setup
@ -569,18 +599,6 @@ The :gist git source is deprecated, and will be removed in the future. Add this
G
end
context "without flags" do
before do
bundle :show
end
it "prints a deprecation warning recommending `bundle list`", :bundler => "< 3" do
expect(deprecations).to include("use `bundle list` instead of `bundle show`")
end
pending "fails with a helpful message", :bundler => "3"
end
context "with --outdated flag" do
before do
bundle "show --outdated"
@ -592,54 +610,6 @@ The :gist git source is deprecated, and will be removed in the future. Add this
pending "fails with a helpful message", :bundler => "3"
end
context "with --verbose flag" do
before do
bundle "show --verbose"
end
it "prints a deprecation warning informing about its removal", :bundler => "< 3" do
expect(deprecations).to include("the `--verbose` flag to `bundle show` was undocumented and will be removed without replacement")
end
pending "fails with a helpful message", :bundler => "3"
end
context "with a gem argument" do
before do
bundle "show rack"
end
it "prints a deprecation warning recommending `bundle info`", :bundler => "< 3" do
expect(deprecations).to include("use `bundle info rack` instead of `bundle show rack`")
end
pending "fails with a helpful message", :bundler => "3"
end
context "with the --paths option" do
before do
bundle "show --paths"
end
it "prints a deprecation warning recommending `bundle list`", :bundler => "< 3" do
expect(deprecations).to include("use `bundle list` instead of `bundle show --paths`")
end
pending "fails with a helpful message", :bundler => "3"
end
context "with a gem argument and the --paths option" do
before do
bundle "show rack --paths"
end
it "prints deprecation warning recommending `bundle info`", :bundler => "< 3" do
expect(deprecations).to include("use `bundle info rack --path` instead of `bundle show rack --paths`")
end
pending "fails with a helpful message", :bundler => "3"
end
end
context "bundle console" do

View file

@ -25,9 +25,9 @@ RSpec.describe "double checking sources", :realworld => true do
RUBY
cmd = <<-RUBY
require "#{lib_dir}/bundler"
require "#{entrypoint}"
require "#{spec_dir}/support/artifice/vcr"
require "#{lib_dir}/bundler/inline"
require "#{entrypoint}/inline"
gemfile(true) do
source "https://rubygems.org"
gem "rails", path: "."

View file

@ -4,9 +4,9 @@ RSpec.describe "real world edgecases", :realworld => true do
def rubygems_version(name, requirement)
ruby <<-RUBY
require "#{spec_dir}/support/artifice/vcr"
require "#{lib_dir}/bundler"
require "#{lib_dir}/bundler/source/rubygems/remote"
require "#{lib_dir}/bundler/fetcher"
require "#{entrypoint}"
require "#{entrypoint}/source/rubygems/remote"
require "#{entrypoint}/fetcher"
rubygem = Bundler.ui.silence do
source = Bundler::Source::Rubygems::Remote.new(Bundler::URI("https://rubygems.org"))
fetcher = Bundler::Fetcher.new(source)

View file

@ -2,7 +2,7 @@
RSpec.describe "bundler/inline#gemfile" do
def script(code, options = {})
requires = ["#{lib_dir}/bundler/inline"]
requires = ["#{entrypoint}/inline"]
requires.unshift "#{spec_dir}/support/artifice/" + options.delete(:artifice) if options.key?(:artifice)
requires = requires.map {|r| "require '#{r}'" }.join("\n")
ruby("#{requires}\n\n" + code, options)
@ -93,7 +93,7 @@ RSpec.describe "bundler/inline#gemfile" do
it "lets me use my own ui object" do
script <<-RUBY, :artifice => "endpoint"
require '#{lib_dir}/bundler'
require '#{entrypoint}'
class MyBundlerUI < Bundler::UI::Silent
def confirm(msg, newline = nil)
puts "CONFIRMED!"
@ -110,7 +110,7 @@ RSpec.describe "bundler/inline#gemfile" do
it "has an option for quiet installation" do
script <<-RUBY, :artifice => "endpoint"
require '#{lib_dir}/bundler/inline'
require '#{entrypoint}/inline'
gemfile(true, :quiet => true) do
source "https://notaserver.com"
@ -136,7 +136,7 @@ RSpec.describe "bundler/inline#gemfile" do
it "does not mutate the option argument" do
script <<-RUBY
require '#{lib_dir}/bundler'
require '#{entrypoint}'
options = { :ui => Bundler::UI::Shell.new }
gemfile(false, options) do
path "#{lib_path}" do
@ -218,7 +218,7 @@ RSpec.describe "bundler/inline#gemfile" do
rake
BUNDLED WITH
1.13.6
#{Bundler::VERSION}
G
script <<-RUBY

View file

@ -82,7 +82,7 @@ RSpec.describe "Bundler.load" do
G
ruby <<-RUBY
require "#{lib_dir}/bundler"
require "#{entrypoint}"
Bundler.setup :default
Bundler.require :default
puts RACK

View file

@ -22,7 +22,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do
ruby <<-R
begin
require '#{lib_dir}/bundler'
require '#{entrypoint}'
Bundler.ui.silence { Bundler.setup }
rescue Bundler::GemNotFound => e
puts "WIN"

View file

@ -192,7 +192,7 @@ RSpec.describe "Bundler.require" do
G
cmd = <<-RUBY
require '#{lib_dir}/bundler'
require '#{entrypoint}'
Bundler.require
RUBY
ruby(cmd)

View file

@ -108,8 +108,8 @@ RSpec.describe "Bundler.setup" do
context "load order" do
def clean_load_path(lp)
without_bundler_load_path = ruby("puts $LOAD_PATH").split("\n")
lp -= without_bundler_load_path
lp.map! {|p| p.sub(/^#{Regexp.union system_gem_path.to_s, default_bundle_path.to_s, lib_dir.to_s}/i, "") }
lp -= [*without_bundler_load_path, lib_dir.to_s]
lp.map! {|p| p.sub(system_gem_path.to_s, "") }
end
it "puts loaded gems after -I and RUBYLIB", :ruby_repo do
@ -143,12 +143,8 @@ RSpec.describe "Bundler.setup" do
gem "rails"
G
# We require an absolute path because relying on the $LOAD_PATH behaves
# inconsistently depending on whether we're in a ruby-core setup (and
# bundler's lib is in RUBYLIB) or not.
ruby <<-RUBY
require '#{lib_dir}/bundler'
require 'bundler'
Bundler.setup
puts $LOAD_PATH
RUBY
@ -157,7 +153,6 @@ RSpec.describe "Bundler.setup" do
expect(load_path).to start_with(
"/gems/rails-2.3.2/lib",
"/gems/bundler-#{Bundler::VERSION}/lib",
"/gems/activeresource-2.3.2/lib",
"/gems/activerecord-2.3.2/lib",
"/gems/actionpack-2.3.2/lib",
@ -168,6 +163,8 @@ RSpec.describe "Bundler.setup" do
end
it "falls back to order the load path alphabetically for backwards compatibility" do
bundle "config set path.system true"
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "weakling"
@ -175,12 +172,8 @@ RSpec.describe "Bundler.setup" do
gem "terranova"
G
# We require an absolute path because relying on the $LOAD_PATH behaves
# inconsistently depending on whether we're in a ruby-core setup (and
# bundler's lib is in RUBYLIB) or not.
ruby <<-RUBY
require '#{lib_dir}/bundler/setup'
require 'bundler/setup'
puts $LOAD_PATH
RUBY
@ -200,8 +193,6 @@ RSpec.describe "Bundler.setup" do
gem "rack"
G
entrypoint = mis_activates_prerelease_default_bundler? ? "#{lib_dir}/bundler" : "bundler"
ruby <<-R
require '#{entrypoint}'
@ -474,8 +465,6 @@ RSpec.describe "Bundler.setup" do
break_git!
entrypoint = mis_activates_prerelease_default_bundler? ? "#{lib_dir}/bundler" : "bundler"
ruby <<-R
require "#{entrypoint}"
@ -1126,9 +1115,8 @@ end
context "is not present" do
it "does not change the lock" do
entrypoint = mis_activates_prerelease_default_bundler? ? "#{lib_dir}/bundler/setup" : "bundler/setup"
lockfile lock_with(nil)
ruby "require '#{entrypoint}'"
ruby "require '#{entrypoint}/setup'"
lockfile_should_be lock_with(nil)
end
end
@ -1145,10 +1133,9 @@ end
context "is older" do
it "does not change the lock" do
entrypoint = mis_activates_prerelease_default_bundler? ? "#{lib_dir}/bundler/setup" : "bundler/setup"
system_gems "bundler-1.10.1"
lockfile lock_with("1.10.1")
ruby "require '#{entrypoint}'"
ruby "require '#{entrypoint}/setup'"
lockfile_should_be lock_with("1.10.1")
end
end
@ -1219,9 +1206,8 @@ end
describe "with gemified standard libraries" do
it "does not load Psych" do
gemfile ""
entrypoint = mis_activates_prerelease_default_bundler? ? "#{lib_dir}/bundler/setup" : "bundler/setup"
ruby <<-RUBY
require '#{entrypoint}'
require '#{entrypoint}/setup'
puts defined?(Psych::VERSION) ? Psych::VERSION : "undefined"
require 'psych'
puts Psych::VERSION
@ -1422,9 +1408,4 @@ end
expect(last_command.stdboth).to eq("true")
end
end
# Tested rubygems does not include https://github.com/rubygems/rubygems/pull/2728 and will not always end up activating the current bundler
def mis_activates_prerelease_default_bundler?
Gem.rubygems_version < Gem::Version.new("3.1.a")
end
end

View file

@ -45,10 +45,14 @@ class Endpoint < Sinatra::Base
Pathname.new(ENV["BUNDLER_SPEC_GEM_REPO"])
else
case request.host
when "gem.repo1"
Spec::Path.gem_repo1
when "gem.repo2"
Spec::Path.gem_repo2
when "gem.repo3"
Spec::Path.gem_repo3
when "gem.repo4"
Spec::Path.gem_repo4
else
Spec::Path.gem_repo1
end

View file

@ -60,7 +60,7 @@ module Spec
def run(cmd, *args)
opts = args.last.is_a?(Hash) ? args.pop : {}
groups = args.map(&:inspect).join(", ")
setup = "require '#{lib_dir}/bundler' ; Bundler.ui.silence { Bundler.setup(#{groups}) }"
setup = "require '#{entrypoint}' ; Bundler.ui.silence { Bundler.setup(#{groups}) }"
ruby([setup, cmd].join(" ; "), opts)
end
@ -468,9 +468,8 @@ module Spec
ENV["BUNDLER_SPEC_WINDOWS"] = old
end
# workaround for missing https://github.com/rubygems/rubygems/commit/929e92d752baad3a08f3ac92eaec162cb96aedd1
def simulate_bundler_version_when_missing_prerelease_default_gem_activation
return yield unless Gem.rubygems_version < Gem::Version.new("3.1.0.pre.1")
return yield unless rubygems_version_failing_to_activate_bundler_prereleases
old = ENV["BUNDLER_VERSION"]
ENV["BUNDLER_VERSION"] = Bundler::VERSION
@ -479,15 +478,20 @@ module Spec
ENV["BUNDLER_VERSION"] = old
end
# workaround for missing https://github.com/rubygems/rubygems/commit/929e92d752baad3a08f3ac92eaec162cb96aedd1
def env_for_missing_prerelease_default_gem_activation
if Gem.rubygems_version < Gem::Version.new("3.1.0.pre.1")
if rubygems_version_failing_to_activate_bundler_prereleases
{ "BUNDLER_VERSION" => Bundler::VERSION }
else
{}
end
end
# versions providing a bundler version finder but not including
# https://github.com/rubygems/rubygems/commit/929e92d752baad3a08f3ac92eaec162cb96aedd1
def rubygems_version_failing_to_activate_bundler_prereleases
Gem.rubygems_version < Gem::Version.new("3.1.0.pre.1") && Gem.rubygems_version >= Gem::Version.new("2.7.0")
end
def revision_for(path)
sys_exec("git rev-parse HEAD", :dir => path).strip
end

View file

@ -20,12 +20,11 @@ module Spec
default_source = instance_double("Bundler::Source::Rubygems", :specs => @index)
source_requirements = { :default => default_source }
@deps.each do |d|
source_requirements[d.name] = d.source = default_source
@platforms.each do |p|
source_requirements[d.name] = d.source = default_source
deps << Bundler::DepProxy.get_proxy(d, p)
end
end
source_requirements ||= {}
args[0] ||= [] # base
args[1] ||= Bundler::GemVersionPromoter.new # gem_version_promoter
args[2] ||= [] # additional_base_requirements

View file

@ -156,7 +156,7 @@ module Spec
actual_source = out.split("\n").last
next "Expected #{name} (#{version}) to be installed from `#{source}`, was actually from `#{actual_source}`"
end
next "Command to check forgem inclusion of gem #{full_name} failed"
next "Command to check for inclusion of gem #{full_name} failed"
end.compact
@errors.empty?

View file

@ -213,6 +213,13 @@ module Spec
root.join("lib")
end
# Sometimes rubygems version under test does not include
# https://github.com/rubygems/rubygems/pull/2728 and will not always end up
# activating the current bundler. In that case, require bundler absolutely.
def entrypoint
Gem.rubygems_version < Gem::Version.new("3.1.a") ? "#{lib_dir}/bundler" : "bundler"
end
def global_plugin_gem(*args)
home ".bundle", "plugin", "gems", *args
end

View file

@ -544,6 +544,10 @@ class Gem::TestCase < Test::Unit::TestCase
Gem.pre_uninstall_hooks.clear
end
def without_any_upwards_gemfiles
ENV["BUNDLE_GEMFILE"] = File.join(@tempdir, "Gemfile")
end
##
# A git_gem is used with a gem dependencies file. The gem created here
# has no files, just a gem specification for the given +name+ and +version+.
@ -1291,7 +1295,7 @@ Also, a list:
end
def ruby_with_rubygems_in_load_path
[Gem.ruby, "-I", File.expand_path("../../lib", __dir__)]
[Gem.ruby, "-I", $LOAD_PATH.find{|p| p == File.dirname($LOADED_FEATURES.find{|f| f.end_with?("/rubygems.rb") }) }]
end
def with_clean_path_to_ruby
@ -1591,7 +1595,7 @@ class Object
metaclass.send :undef_method, name
metaclass.send :alias_method, name, new_name
metaclass.send :undef_method, new_name
end unless method_defined?(:stub) # lib/resolv/test_dns.rb also has the same method definition
end
end
require_relative 'utilities'

View file

@ -6,14 +6,12 @@ class TestGemBundlerVersionFinder < Gem::TestCase
super
@argv = ARGV.dup
@env = ENV.to_hash.clone
ENV.delete("BUNDLER_VERSION")
@dollar_0 = $0
without_any_upwards_gemfiles
end
def teardown
ARGV.replace @argv
ENV.replace @env
$0 = @dollar_0
super

View file

@ -189,6 +189,18 @@ class TestGemCommand < Gem::TestCase
assert_match %r{Usage: gem doit}, @ui.output
end
def test_add_option
assert_nothing_raised RuntimeError do
@cmd.add_option('--force', 'skip validation of the spec') {|v,o| }
end
end
def test_add_option_with_empty
assert_raise RuntimeError, "Do not pass an empty string in opts" do
@cmd.add_option('', 'skip validation of the spec') {|v,o| }
end
end
def test_option_recognition
@cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
options[:help] = true

View file

@ -35,6 +35,13 @@ class TestGemCommandsHelpCommand < Gem::TestCase
end
end
def test_gem_help_build
util_gem 'build' do |out, err|
assert_match(/-C PATH *Run as if gem build was started in <PATH>/, out)
assert_equal '', err
end
end
def test_gem_help_commands
mgr = Gem::CommandManager.new

View file

@ -155,7 +155,6 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host => @api_key,
}
FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end
@ -190,7 +189,6 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host => @api_key,
}
FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end
@ -232,7 +230,6 @@ class TestGemCommandsPushCommand < Gem::TestCase
:rubygems_api_key => @api_key,
}
FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end
@ -274,7 +271,6 @@ class TestGemCommandsPushCommand < Gem::TestCase
@host => @api_key,
}
FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end
@ -305,7 +301,6 @@ class TestGemCommandsPushCommand < Gem::TestCase
host => api_key,
}
FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end

Some files were not shown because too many files have changed in this diff Show more