summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler.rb1
-rw-r--r--lib/bundler/cli.rb46
-rw-r--r--lib/bundler/cli/check.rb6
-rw-r--r--lib/bundler/cli/install.rb5
-rw-r--r--lib/bundler/cli/lock.rb6
-rw-r--r--lib/bundler/cli/outdated.rb19
-rw-r--r--lib/bundler/cli/update.rb11
-rw-r--r--lib/bundler/definition.rb129
-rw-r--r--lib/bundler/feature_flag.rb2
-rw-r--r--lib/bundler/fetcher/compact_index.rb2
-rw-r--r--lib/bundler/fetcher/downloader.rb3
-rw-r--r--lib/bundler/fetcher/index.rb1
-rw-r--r--lib/bundler/friendly_errors.rb6
-rw-r--r--lib/bundler/index.rb3
-rw-r--r--lib/bundler/installer.rb9
-rw-r--r--lib/bundler/man/bundle-add.12
-rw-r--r--lib/bundler/man/bundle-binstubs.12
-rw-r--r--lib/bundler/man/bundle-cache.12
-rw-r--r--lib/bundler/man/bundle-check.12
-rw-r--r--lib/bundler/man/bundle-clean.12
-rw-r--r--lib/bundler/man/bundle-config.111
-rw-r--r--lib/bundler/man/bundle-config.1.ronn11
-rw-r--r--lib/bundler/man/bundle-doctor.12
-rw-r--r--lib/bundler/man/bundle-exec.12
-rw-r--r--lib/bundler/man/bundle-gem.12
-rw-r--r--lib/bundler/man/bundle-info.12
-rw-r--r--lib/bundler/man/bundle-init.12
-rw-r--r--lib/bundler/man/bundle-inject.12
-rw-r--r--lib/bundler/man/bundle-install.12
-rw-r--r--lib/bundler/man/bundle-list.12
-rw-r--r--lib/bundler/man/bundle-lock.12
-rw-r--r--lib/bundler/man/bundle-open.12
-rw-r--r--lib/bundler/man/bundle-outdated.12
-rw-r--r--lib/bundler/man/bundle-platform.12
-rw-r--r--lib/bundler/man/bundle-pristine.12
-rw-r--r--lib/bundler/man/bundle-remove.12
-rw-r--r--lib/bundler/man/bundle-show.12
-rw-r--r--lib/bundler/man/bundle-update.18
-rw-r--r--lib/bundler/man/bundle-update.1.ronn6
-rw-r--r--lib/bundler/man/bundle-viz.12
-rw-r--r--lib/bundler/man/bundle.12
-rw-r--r--lib/bundler/man/gemfile.52
-rw-r--r--lib/bundler/plugin/api/source.rb14
-rw-r--r--lib/bundler/resolver.rb78
-rw-r--r--lib/bundler/rubygems_ext.rb4
-rw-r--r--lib/bundler/rubygems_integration.rb7
-rw-r--r--lib/bundler/settings.rb24
-rw-r--r--lib/bundler/source.rb11
-rw-r--r--lib/bundler/source/rubygems.rb37
-rw-r--r--lib/bundler/source/rubygems_aggregate.rb64
-rw-r--r--lib/bundler/source_list.rb45
-rw-r--r--lib/bundler/source_map.rb58
-rw-r--r--lib/bundler/spec_set.rb8
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt4
-rw-r--r--lib/rubygems/command.rb2
-rw-r--r--lib/rubygems/commands/build_command.rb2
-rw-r--r--lib/rubygems/commands/cert_command.rb80
-rw-r--r--lib/rubygems/config_file.rb2
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb8
-rw-r--r--lib/rubygems/installer.rb4
-rw-r--r--lib/rubygems/request.rb2
-rw-r--r--lib/rubygems/specification.rb8
-rw-r--r--lib/rubygems/specification_policy.rb9
-rw-r--r--lib/rubygems/uninstaller.rb5
-rw-r--r--lib/rubygems/util/licenses.rb109
-rw-r--r--spec/bundler/bundler/definition_spec.rb29
-rw-r--r--spec/bundler/bundler/fetcher/downloader_spec.rb11
-rw-r--r--spec/bundler/bundler/fetcher/index_spec.rb2
-rw-r--r--spec/bundler/bundler/settings_spec.rb14
-rw-r--r--spec/bundler/commands/cache_spec.rb44
-rw-r--r--spec/bundler/commands/check_spec.rb60
-rw-r--r--spec/bundler/commands/lock_spec.rb2
-rw-r--r--spec/bundler/commands/outdated_spec.rb53
-rw-r--r--spec/bundler/commands/update_spec.rb103
-rw-r--r--spec/bundler/install/gemfile/groups_spec.rb2
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb950
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb4
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb31
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb32
-rw-r--r--spec/bundler/install/global_cache_spec.rb4
-rw-r--r--spec/bundler/lock/lockfile_spec.rb2
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb96
-rw-r--r--spec/bundler/realworld/double_check_spec.rb4
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb6
-rw-r--r--spec/bundler/runtime/inline_spec.rb10
-rw-r--r--spec/bundler/runtime/load_spec.rb2
-rw-r--r--spec/bundler/runtime/platform_spec.rb2
-rw-r--r--spec/bundler/runtime/require_spec.rb2
-rw-r--r--spec/bundler/runtime/setup_spec.rb37
-rw-r--r--spec/bundler/support/artifice/endpoint.rb4
-rw-r--r--spec/bundler/support/helpers.rb14
-rw-r--r--spec/bundler/support/indexes.rb3
-rw-r--r--spec/bundler/support/matchers.rb2
-rw-r--r--spec/bundler/support/path.rb7
-rw-r--r--test/rubygems/helper.rb8
-rw-r--r--test/rubygems/packages/ill-formatted-platform-1.0.0.10.gembin0 -> 10240 bytes
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb4
-rw-r--r--test/rubygems/test_gem_command.rb12
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb7
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb5
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb4
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb7
-rw-r--r--test/rubygems/test_gem_dependency.rb6
-rw-r--r--test/rubygems/test_gem_ext_builder.rb6
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb1
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb2
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb6
-rw-r--r--test/rubygems/test_gem_installer.rb20
-rw-r--r--test/rubygems/test_gem_specification.rb6
-rw-r--r--test/rubygems/test_kernel.rb2
-rw-r--r--test/rubygems/test_require.rb2
111 files changed, 1511 insertions, 1035 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 9f7f9b218f..8b9e870f7b 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -69,6 +69,7 @@ module Bundler
autoload :SharedHelpers, File.expand_path("bundler/shared_helpers", __dir__)
autoload :Source, File.expand_path("bundler/source", __dir__)
autoload :SourceList, File.expand_path("bundler/source_list", __dir__)
+ autoload :SourceMap, File.expand_path("bundler/source_map", __dir__)
autoload :SpecSet, File.expand_path("bundler/spec_set", __dir__)
autoload :StubSpecification, File.expand_path("bundler/stub_specification", __dir__)
autoload :UI, File.expand_path("bundler/ui", __dir__)
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 6562f3a853..3027535724 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -308,39 +308,19 @@ module Bundler
end
end
- unless Bundler.feature_flag.bundler_3_mode?
- desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
- long_desc <<-D
- Show lists the names and versions of all gems that are required by your Gemfile.
- Calling show with [GEM] will list the exact location of that gem on your machine.
- D
- method_option "paths", :type => :boolean,
- :banner => "List the paths of all gems that are required by your Gemfile."
- method_option "outdated", :type => :boolean,
- :banner => "Show verbose output including whether gems are outdated."
- def show(gem_name = nil)
- if ARGV[0] == "show"
- rest = ARGV[1..-1]
-
- if flag = rest.find{|arg| ["--verbose", "--outdated"].include?(arg) }
- Bundler::SharedHelpers.major_deprecation(2, "the `#{flag}` flag to `bundle show` was undocumented and will be removed without replacement")
- else
- new_command = rest.find {|arg| !arg.start_with?("--") } ? "info" : "list"
-
- new_arguments = rest.map do |arg|
- next arg if arg != "--paths"
- next "--path" if new_command == "info"
- end
-
- old_argv = ARGV.join(" ")
- new_argv = [new_command, *new_arguments.compact].join(" ")
-
- Bundler::SharedHelpers.major_deprecation(2, "use `bundle #{new_argv}` instead of `bundle #{old_argv}`")
- end
- end
- require_relative "cli/show"
- Show.new(options, gem_name).run
- end
+ desc "show GEM [OPTIONS]", "Shows all gems that are part of the bundle, or the path to a given gem"
+ long_desc <<-D
+ Show lists the names and versions of all gems that are required by your Gemfile.
+ Calling show with [GEM] will list the exact location of that gem on your machine.
+ D
+ method_option "paths", :type => :boolean,
+ :banner => "List the paths of all gems that are required by your Gemfile."
+ method_option "outdated", :type => :boolean,
+ :banner => "Show verbose output including whether gems are outdated."
+ def show(gem_name = nil)
+ SharedHelpers.major_deprecation(2, "the `--outdated` flag to `bundle show` was undocumented and will be removed without replacement") if ARGV.include?("--outdated")
+ require_relative "cli/show"
+ Show.new(options, gem_name).run
end
desc "list", "List all gems in the bundle"
diff --git a/lib/bundler/cli/check.rb b/lib/bundler/cli/check.rb
index 19c0aaea06..65c51337d2 100644
--- a/lib/bundler/cli/check.rb
+++ b/lib/bundler/cli/check.rb
@@ -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."
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index cfbf4bee6e..47c1da10e7 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -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)
diff --git a/lib/bundler/cli/lock.rb b/lib/bundler/cli/lock.rb
index 7dd078b1ef..7d613a6644 100644
--- a/lib/bundler/cli/lock.rb
+++ b/lib/bundler/cli/lock.rb
@@ -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)
diff --git a/lib/bundler/cli/outdated.rb b/lib/bundler/cli/outdated.rb
index e5d9af477c..d5183b060b 100644
--- a/lib/bundler/cli/outdated.rb
+++ b/lib/bundler/cli/outdated.rb
@@ -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)
diff --git a/lib/bundler/cli/update.rb b/lib/bundler/cli/update.rb
index 94699484d4..cf6a5b26d3 100644
--- a/lib/bundler/cli/update.rb
+++ b/lib/bundler/cli/update.rb
@@ -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
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index fc30dd5ca8..0d7630e20d 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -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
diff --git a/lib/bundler/feature_flag.rb b/lib/bundler/feature_flag.rb
index 36c18ead22..e441b941c2 100644
--- a/lib/bundler/feature_flag.rb
+++ b/lib/bundler/feature_flag.rb
@@ -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? }
diff --git a/lib/bundler/fetcher/compact_index.rb b/lib/bundler/fetcher/compact_index.rb
index 27969d74ec..aa828af6b1 100644
--- a/lib/bundler/fetcher/compact_index.rb
+++ b/lib/bundler/fetcher/compact_index.rb
@@ -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
diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb
index 5d30333158..f2aad3a500 100644
--- a/lib/bundler/fetcher/downloader.rb
+++ b/lib/bundler/fetcher/downloader.rb
@@ -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
diff --git a/lib/bundler/fetcher/index.rb b/lib/bundler/fetcher/index.rb
index 08b041897e..0d14c47aa7 100644
--- a/lib/bundler/fetcher/index.rb
+++ b/lib/bundler/fetcher/index.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
require_relative "base"
-require "rubygems/remote_fetcher"
module Bundler
class Fetcher
diff --git a/lib/bundler/friendly_errors.rb b/lib/bundler/friendly_errors.rb
index 5d0bb905bc..db43e0f654 100644
--- a/lib/bundler/friendly_errors.rb
+++ b/lib/bundler/friendly_errors.rb
@@ -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
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index f945176037..36520c0a43 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -122,10 +122,9 @@ module Bundler
names
end
- # returns a list of the dependencies
def unmet_dependency_names
dependency_names.select do |name|
- name != "bundler" && search(name).empty?
+ search(name).empty?
end
end
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index 09c8b1c157..a88fb91cb5 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -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
diff --git a/lib/bundler/man/bundle-add.1 b/lib/bundler/man/bundle-add.1
index ffcd63bbcc..4945747f42 100644
--- a/lib/bundler/man/bundle-add.1
+++ b/lib/bundler/man/bundle-add.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-ADD" "1" "April 2021" "" ""
+.TH "BUNDLE\-ADD" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
diff --git a/lib/bundler/man/bundle-binstubs.1 b/lib/bundler/man/bundle-binstubs.1
index 23c371b7de..dd43180b19 100644
--- a/lib/bundler/man/bundle-binstubs.1
+++ b/lib/bundler/man/bundle-binstubs.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-BINSTUBS" "1" "April 2021" "" ""
+.TH "BUNDLE\-BINSTUBS" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
diff --git a/lib/bundler/man/bundle-cache.1 b/lib/bundler/man/bundle-cache.1
index 9bb8011a8a..22ce1dfc76 100644
--- a/lib/bundler/man/bundle-cache.1
+++ b/lib/bundler/man/bundle-cache.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CACHE" "1" "April 2021" "" ""
+.TH "BUNDLE\-CACHE" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
diff --git a/lib/bundler/man/bundle-check.1 b/lib/bundler/man/bundle-check.1
index 6696479fef..6e1b38ab05 100644
--- a/lib/bundler/man/bundle-check.1
+++ b/lib/bundler/man/bundle-check.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CHECK" "1" "April 2021" "" ""
+.TH "BUNDLE\-CHECK" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
diff --git a/lib/bundler/man/bundle-clean.1 b/lib/bundler/man/bundle-clean.1
index 625d87c580..eb658e1c73 100644
--- a/lib/bundler/man/bundle-clean.1
+++ b/lib/bundler/man/bundle-clean.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CLEAN" "1" "April 2021" "" ""
+.TH "BUNDLE\-CLEAN" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
diff --git a/lib/bundler/man/bundle-config.1 b/lib/bundler/man/bundle-config.1
index 81cfaa7165..323fcc8121 100644
--- a/lib/bundler/man/bundle-config.1
+++ b/lib/bundler/man/bundle-config.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-CONFIG" "1" "April 2021" "" ""
+.TH "BUNDLE\-CONFIG" "1" "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
diff --git a/lib/bundler/man/bundle-config.1.ronn b/lib/bundler/man/bundle-config.1.ronn
index b759939d3c..05ba0dc255 100644
--- a/lib/bundler/man/bundle-config.1.ronn
+++ b/lib/bundler/man/bundle-config.1.ronn
@@ -47,10 +47,6 @@ configuration only from the local application.
Executing bundle with the `BUNDLE_IGNORE_CONFIG` environment variable set will
cause it to ignore all configuration.
-Executing `bundle config set --local disable_multisource true` upgrades the warning about
-the Gemfile containing multiple primary sources to an error. Executing `bundle
-config unset disable_multisource` downgrades this error to a warning.
-
## REMEMBERING OPTIONS
Flags passed to `bundle install` or the Bundler runtime, such as `--path foo` or
@@ -178,10 +174,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
* `disable_local_revision_check` (`BUNDLE_DISABLE_LOCAL_REVISION_CHECK`):
Allow Bundler to use a local git override without checking if the revision
present in the lockfile is present in the repository.
-* `disable_multisource` (`BUNDLE_DISABLE_MULTISOURCE`):
- When set, Gemfiles containing multiple sources will produce errors
- instead of warnings.
- Use `bundle config unset disable_multisource` to unset.
* `disable_shared_gems` (`BUNDLE_DISABLE_SHARED_GEMS`):
Stop Bundler from accessing gems installed to RubyGems' normal location.
* `disable_version_check` (`BUNDLE_DISABLE_VERSION_CHECK`):
@@ -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`.
diff --git a/lib/bundler/man/bundle-doctor.1 b/lib/bundler/man/bundle-doctor.1
index 8e4c47c683..84d1f4c9df 100644
--- a/lib/bundler/man/bundle-doctor.1
+++ b/lib/bundler/man/bundle-doctor.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-DOCTOR" "1" "April 2021" "" ""
+.TH "BUNDLE\-DOCTOR" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems
diff --git a/lib/bundler/man/bundle-exec.1 b/lib/bundler/man/bundle-exec.1
index 863b76e4b7..b3c60fbbfd 100644
--- a/lib/bundler/man/bundle-exec.1
+++ b/lib/bundler/man/bundle-exec.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-EXEC" "1" "April 2021" "" ""
+.TH "BUNDLE\-EXEC" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
diff --git a/lib/bundler/man/bundle-gem.1 b/lib/bundler/man/bundle-gem.1
index ae4e173008..3f711c2bed 100644
--- a/lib/bundler/man/bundle-gem.1
+++ b/lib/bundler/man/bundle-gem.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-GEM" "1" "April 2021" "" ""
+.TH "BUNDLE\-GEM" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
diff --git a/lib/bundler/man/bundle-info.1 b/lib/bundler/man/bundle-info.1
index 168d021112..337e7bdd38 100644
--- a/lib/bundler/man/bundle-info.1
+++ b/lib/bundler/man/bundle-info.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INFO" "1" "April 2021" "" ""
+.TH "BUNDLE\-INFO" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle
diff --git a/lib/bundler/man/bundle-init.1 b/lib/bundler/man/bundle-init.1
index 5d3e61d05b..0c5b8c7a39 100644
--- a/lib/bundler/man/bundle-init.1
+++ b/lib/bundler/man/bundle-init.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INIT" "1" "April 2021" "" ""
+.TH "BUNDLE\-INIT" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
diff --git a/lib/bundler/man/bundle-inject.1 b/lib/bundler/man/bundle-inject.1
index 37acabfa9a..f228ed247f 100644
--- a/lib/bundler/man/bundle-inject.1
+++ b/lib/bundler/man/bundle-inject.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INJECT" "1" "April 2021" "" ""
+.TH "BUNDLE\-INJECT" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
diff --git a/lib/bundler/man/bundle-install.1 b/lib/bundler/man/bundle-install.1
index 2dcb4d3ac6..ae9747bd83 100644
--- a/lib/bundler/man/bundle-install.1
+++ b/lib/bundler/man/bundle-install.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-INSTALL" "1" "April 2021" "" ""
+.TH "BUNDLE\-INSTALL" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
diff --git a/lib/bundler/man/bundle-list.1 b/lib/bundler/man/bundle-list.1
index 7c93b89dc3..cce8881059 100644
--- a/lib/bundler/man/bundle-list.1
+++ b/lib/bundler/man/bundle-list.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LIST" "1" "April 2021" "" ""
+.TH "BUNDLE\-LIST" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle
diff --git a/lib/bundler/man/bundle-lock.1 b/lib/bundler/man/bundle-lock.1
index a4dfda9c86..23388daaee 100644
--- a/lib/bundler/man/bundle-lock.1
+++ b/lib/bundler/man/bundle-lock.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-LOCK" "1" "April 2021" "" ""
+.TH "BUNDLE\-LOCK" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
diff --git a/lib/bundler/man/bundle-open.1 b/lib/bundler/man/bundle-open.1
index 0511bc655b..8cc104b81d 100644
--- a/lib/bundler/man/bundle-open.1
+++ b/lib/bundler/man/bundle-open.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OPEN" "1" "April 2021" "" ""
+.TH "BUNDLE\-OPEN" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
diff --git a/lib/bundler/man/bundle-outdated.1 b/lib/bundler/man/bundle-outdated.1
index 268b4b157c..bdd81a66af 100644
--- a/lib/bundler/man/bundle-outdated.1
+++ b/lib/bundler/man/bundle-outdated.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-OUTDATED" "1" "April 2021" "" ""
+.TH "BUNDLE\-OUTDATED" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available
diff --git a/lib/bundler/man/bundle-platform.1 b/lib/bundler/man/bundle-platform.1
index 77638b2b4b..dab5269c04 100644
--- a/lib/bundler/man/bundle-platform.1
+++ b/lib/bundler/man/bundle-platform.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PLATFORM" "1" "April 2021" "" ""
+.TH "BUNDLE\-PLATFORM" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information
diff --git a/lib/bundler/man/bundle-pristine.1 b/lib/bundler/man/bundle-pristine.1
index 0fcf9fdb39..e5b0dab334 100644
--- a/lib/bundler/man/bundle-pristine.1
+++ b/lib/bundler/man/bundle-pristine.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-PRISTINE" "1" "April 2021" "" ""
+.TH "BUNDLE\-PRISTINE" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
diff --git a/lib/bundler/man/bundle-remove.1 b/lib/bundler/man/bundle-remove.1
index ca366b81a9..8af691283d 100644
--- a/lib/bundler/man/bundle-remove.1
+++ b/lib/bundler/man/bundle-remove.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-REMOVE" "1" "April 2021" "" ""
+.TH "BUNDLE\-REMOVE" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile
diff --git a/lib/bundler/man/bundle-show.1 b/lib/bundler/man/bundle-show.1
index e403ae980f..c08c7205aa 100644
--- a/lib/bundler/man/bundle-show.1
+++ b/lib/bundler/man/bundle-show.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-SHOW" "1" "April 2021" "" ""
+.TH "BUNDLE\-SHOW" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
diff --git a/lib/bundler/man/bundle-update.1 b/lib/bundler/man/bundle-update.1
index 5546b51792..7da2ce3438 100644
--- a/lib/bundler/man/bundle-update.1
+++ b/lib/bundler/man/bundle-update.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-UPDATE" "1" "April 2021" "" ""
+.TH "BUNDLE\-UPDATE" "1" "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\.
diff --git a/lib/bundler/man/bundle-update.1.ronn b/lib/bundler/man/bundle-update.1.ronn
index 397fecadcb..3a16f29149 100644
--- a/lib/bundler/man/bundle-update.1.ronn
+++ b/lib/bundler/man/bundle-update.1.ronn
@@ -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
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
index 645c45b607..9683f0678b 100644
--- a/lib/bundler/man/bundle-viz.1
+++ b/lib/bundler/man/bundle-viz.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE\-VIZ" "1" "April 2021" "" ""
+.TH "BUNDLE\-VIZ" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
index 5c1bc96572..b741f7cf6a 100644
--- a/lib/bundler/man/bundle.1
+++ b/lib/bundler/man/bundle.1
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "BUNDLE" "1" "April 2021" "" ""
+.TH "BUNDLE" "1" "June 2021" "" ""
.
.SH "NAME"
\fBbundle\fR \- Ruby Dependency Management
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index c23c26ad7a..f30f71ac7c 100644
--- a/lib/bundler/man/gemfile.5
+++ b/lib/bundler/man/gemfile.5
@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
-.TH "GEMFILE" "5" "April 2021" "" ""
+.TH "GEMFILE" "5" "June 2021" "" ""
.
.SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index d70a16f4bc..f6f4ac4f0a 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -244,6 +244,20 @@ module Bundler
specs.unmet_dependency_names
end
+ # Used by definition.
+ #
+ # Note: Do not override if you don't know what you are doing.
+ def spec_names
+ specs.spec_names
+ end
+
+ # Used by definition.
+ #
+ # Note: Do not override if you don't know what you are doing.
+ def add_dependency_names(names)
+ @dependencies |= Array(names)
+ end
+
# Note: Do not override if you don't know what you are doing.
def can_lock?(spec)
spec.source == self
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 660385c2ff..a78b2db157 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -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
diff --git a/lib/bundler/rubygems_ext.rb b/lib/bundler/rubygems_ext.rb
index 2bd2dcb451..c95664965c 100644
--- a/lib/bundler/rubygems_ext.rb
+++ b/lib/bundler/rubygems_ext.rb
@@ -105,7 +105,7 @@ module Gem
end
class Dependency
- attr_accessor :source, :groups, :all_sources
+ attr_accessor :source, :groups
alias_method :eql?, :==
@@ -116,7 +116,7 @@ module Gem
end
def to_yaml_properties
- instance_variables.reject {|p| ["@source", "@groups", "@all_sources"].include?(p.to_s) }
+ instance_variables.reject {|p| ["@source", "@groups"].include?(p.to_s) }
end
def to_lock
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index d060e21f50..21ce12ecda 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -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)
diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb
index e9155acf48..95da31a765 100644
--- a/lib/bundler/settings.rb
+++ b/lib/bundler/settings.rb
@@ -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
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index a3f4b09cce..5388a7681e 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -7,6 +7,7 @@ module Bundler
autoload :Metadata, File.expand_path("source/metadata", __dir__)
autoload :Path, File.expand_path("source/path", __dir__)
autoload :Rubygems, File.expand_path("source/rubygems", __dir__)
+ autoload :RubygemsAggregate, File.expand_path("source/rubygems_aggregate", __dir__)
attr_accessor :dependency_names
@@ -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
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 2b7cfd53b9..b4bb3d1980 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -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
diff --git a/lib/bundler/source/rubygems_aggregate.rb b/lib/bundler/source/rubygems_aggregate.rb
new file mode 100644
index 0000000000..685bf7e90a
--- /dev/null
+++ b/lib/bundler/source/rubygems_aggregate.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module Bundler
+ class Source
+ class RubygemsAggregate
+ attr_reader :source_map, :sources
+
+ def initialize(sources, source_map)
+ @sources = sources
+ @source_map = source_map
+
+ @index = build_index
+ end
+
+ def specs
+ @index
+ end
+
+ def to_s
+ "any of the sources"
+ end
+
+ private
+
+ def build_index
+ Index.build do |idx|
+ dependency_names = source_map.pinned_spec_names
+
+ sources.all_sources.each do |source|
+ source.dependency_names = dependency_names - source_map.pinned_spec_names(source)
+ idx.add_source source.specs
+ dependency_names.concat(source.unmet_deps).uniq!
+ end
+
+ double_check_for_index(idx, dependency_names)
+ end
+ end
+
+ # Suppose the gem Foo depends on the gem Bar. Foo exists in Source A. Bar has some versions that exist in both
+ # sources A and B. At this point, the API request will have found all the versions of Bar in source A,
+ # but will not have found any versions of Bar from source B, which is a problem if the requested version
+ # of Foo specifically depends on a version of Bar that is only found in source B. This ensures that for
+ # each spec we found, we add all possible versions from all sources to the index.
+ def double_check_for_index(idx, dependency_names)
+ pinned_names = source_map.pinned_spec_names
+
+ names = :names # do this so we only have to traverse to get dependency_names from the index once
+ unmet_dependency_names = lambda do
+ return names unless names == :names
+ new_names = sources.all_sources.map(&:dependency_names_to_double_check)
+ return names = nil if new_names.compact!
+ names = new_names.flatten(1).concat(dependency_names)
+ names.uniq!
+ names -= pinned_names
+ names
+ end
+
+ sources.all_sources.each do |source|
+ source.double_check_for(unmet_dependency_names)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index 6f5636f41e..9a7f0ea0a2 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -21,15 +21,19 @@ module Bundler
@rubygems_sources = []
@metadata_source = Source::Metadata.new
- @disable_multisource = true
+ @merged_gem_lockfile_sections = false
end
- def disable_multisource?
- @disable_multisource
+ def merged_gem_lockfile_sections?
+ @merged_gem_lockfile_sections
end
def merged_gem_lockfile_sections!
- @disable_multisource = false
+ @merged_gem_lockfile_sections = true
+ end
+
+ def 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
diff --git a/lib/bundler/source_map.rb b/lib/bundler/source_map.rb
new file mode 100644
index 0000000000..a554f26f76
--- /dev/null
+++ b/lib/bundler/source_map.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Bundler
+ class SourceMap
+ attr_reader :sources, :dependencies
+
+ def initialize(sources, dependencies)
+ @sources = sources
+ @dependencies = dependencies
+ end
+
+ def pinned_spec_names(skip = nil)
+ direct_requirements.reject {|_, source| source == skip }.keys
+ end
+
+ def all_requirements
+ requirements = direct_requirements.dup
+
+ unmet_deps = sources.non_default_explicit_sources.map do |source|
+ (source.spec_names - pinned_spec_names).each do |indirect_dependency_name|
+ previous_source = requirements[indirect_dependency_name]
+ if previous_source.nil?
+ requirements[indirect_dependency_name] = source
+ else
+ no_ambiguous_sources = Bundler.feature_flag.bundler_3_mode?
+
+ msg = ["The gem '#{indirect_dependency_name}' was found in multiple relevant sources."]
+ msg.concat [previous_source, source].map {|s| " * #{s}" }.sort
+ msg << "You #{no_ambiguous_sources ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
+ msg = msg.join("\n")
+
+ raise SecurityError, msg if no_ambiguous_sources
+ Bundler.ui.warn "Warning: #{msg}"
+ end
+ end
+
+ source.unmet_deps
+ end
+
+ sources.default_source.add_dependency_names(unmet_deps.flatten - requirements.keys)
+
+ requirements
+ end
+
+ def direct_requirements
+ @direct_requirements ||= begin
+ requirements = {}
+ default = sources.default_source
+ dependencies.each do |dep|
+ dep_source = dep.source || default
+ dep_source.add_dependency_names(dep.name)
+ requirements[dep.name] = dep_source
+ end
+ requirements
+ end
+ end
+ end
+end
diff --git a/lib/bundler/spec_set.rb b/lib/bundler/spec_set.rb
index 67669cdd0e..af16984454 100644
--- a/lib/bundler/spec_set.rb
+++ b/lib/bundler/spec_set.rb
@@ -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) }
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index d961d615b4..eddb8b4a30 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -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."
diff --git a/lib/rubygems/command.rb b/lib/rubygems/command.rb
index 9f935e6285..303f54a7d7 100644
--- a/lib/rubygems/command.rb
+++ b/lib/rubygems/command.rb
@@ -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
diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb
index fff5f7c76f..842ec1855a 100644
--- a/lib/rubygems/commands/build_command.rb
+++ b/lib/rubygems/commands/build_command.rb
@@ -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
diff --git a/lib/rubygems/commands/cert_command.rb b/lib/rubygems/commands/cert_command.rb
index 998df0621b..3fc0daea7d 100644
--- a/lib/rubygems/commands/cert_command.rb
+++ b/lib/rubygems/commands/cert_command.rb
@@ -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
diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb
index 9dc41a2995..3746d7aab0 100644
--- a/lib/rubygems/config_file.rb
+++ b/lib/rubygems/config_file.rb
@@ -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
diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb
index fede270417..1f73796351 100644
--- a/lib/rubygems/ext/ext_conf_builder.rb
+++ b/lib/rubygems/ext/ext_conf_builder.rb
@@ -23,11 +23,11 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
# spaces do not work.
#
# Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940
- tmp_dest = get_relative_path(tmp_dest, extension_dir)
+ tmp_dest_relative = get_relative_path(tmp_dest.clone, extension_dir)
Tempfile.open %w[siteconf .rb], extension_dir do |siteconf|
siteconf.puts "require 'rbconfig'"
- siteconf.puts "dest_path = #{tmp_dest.dump}"
+ siteconf.puts "dest_path = #{tmp_dest_relative.dump}"
%w[sitearchdir sitelibdir].each do |dir|
siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
@@ -63,8 +63,8 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
make dest_path, results, extension_dir
- if tmp_dest
- full_tmp_dest = File.join(extension_dir, tmp_dest)
+ if tmp_dest_relative
+ full_tmp_dest = File.join(extension_dir, tmp_dest_relative)
# TODO remove in RubyGems 3
if Gem.install_extension_in_lib and lib_dir
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 7af51056b7..8c286605e1 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -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
diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb
index 1ed0fbcb99..5bda0b2e5e 100644
--- a/lib/rubygems/request.rb
+++ b/lib/rubygems/request.rb
@@ -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 =
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index 7206c3eaf0..23a37e966b 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -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"
diff --git a/lib/rubygems/specification_policy.rb b/lib/rubygems/specification_policy.rb
index 2b8b05635e..86277a2058 100644
--- a/lib/rubygems/specification_policy.rb
+++ b/lib/rubygems/specification_policy.rb
@@ -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
diff --git a/lib/rubygems/uninstaller.rb b/lib/rubygems/uninstaller.rb
index 51ac3494f3..3bc202863c 100644
--- a/lib/rubygems/uninstaller.rb
+++ b/lib/rubygems/uninstaller.rb
@@ -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
diff --git a/lib/rubygems/util/licenses.rb b/lib/rubygems/util/licenses.rb
index 29bf310ea0..98cbd8929b 100644
--- a/lib/rubygems/util/licenses.rb
+++ b/lib/rubygems/util/licenses.rb
@@ -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
diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb
index 5f8b88a101..78c7dc79b9 100644
--- a/spec/bundler/bundler/definition_spec.rb
+++ b/spec/bundler/bundler/definition_spec.rb
@@ -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
diff --git a/spec/bundler/bundler/fetcher/downloader_spec.rb b/spec/bundler/bundler/fetcher/downloader_spec.rb
index 667f484349..4d3dff3a89 100644
--- a/spec/bundler/bundler/fetcher/downloader_spec.rb
+++ b/spec/bundler/bundler/fetcher/downloader_spec.rb
@@ -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
diff --git a/spec/bundler/bundler/fetcher/index_spec.rb b/spec/bundler/bundler/fetcher/index_spec.rb
index b8ce46321e..f0db07583c 100644
--- a/spec/bundler/bundler/fetcher/index_spec.rb
+++ b/spec/bundler/bundler/fetcher/index_spec.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "rubygems/remote_fetcher"
+
RSpec.describe Bundler::Fetcher::Index do
let(:downloader) { nil }
let(:remote) { nil }
diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb
index 116a038445..0f1a9c2a6f 100644
--- a/spec/bundler/bundler/settings_spec.rb
+++ b/spec/bundler/bundler/settings_spec.rb
@@ -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")
diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb
index df027a497a..4f9c1c26c4 100644
--- a/spec/bundler/commands/cache_spec.rb
+++ b/spec/bundler/commands/cache_spec.rb
@@ -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)}"
diff --git a/spec/bundler/commands/check_spec.rb b/spec/bundler/commands/check_spec.rb
index 2fb03186be..2860c82a12 100644
--- a/spec/bundler/commands/check_spec.rb
+++ b/spec/bundler/commands/check_spec.rb
@@ -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
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index 264af30f6c..21eb6e5456 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -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
diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb
index b0f0448655..731d67af1b 100644
--- a/spec/bundler/commands/outdated_spec.rb
+++ b/spec/bundler/commands/outdated_spec.rb
@@ -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
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index 51a0b925a3..86314952ad 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -411,7 +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
+ 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"
@@ -419,10 +419,10 @@ RSpec.describe "bundle update" do
update_repo2 { build_gem "activesupport", "3.0" }
bundle "update --source activesupport"
- expect(the_bundle).to include_gem "activesupport 3.0"
+ expect(the_bundle).not_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"
@@ -430,22 +430,7 @@ RSpec.describe "bundle update" do
update_repo2 { build_gem "activesupport", "3.0" }
bundle "update --source activesupport"
- 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" }
-
- bundle "update --source activesupport"
- expect(the_bundle).not_to include_gems "activesupport 3.0"
- end
+ 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
diff --git a/spec/bundler/install/gemfile/groups_spec.rb b/spec/bundler/install/gemfile/groups_spec.rb
index f53315e766..c92b5dcc57 100644
--- a/spec/bundler/install/gemfile/groups_spec.rb
+++ b/spec/bundler/install/gemfile/groups_spec.rb
@@ -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
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index 4f931a493b..16c5b232da 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -20,23 +20,23 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
gemfile <<-G
- source "#{file_uri_for(gem_repo3)}"
- source "#{file_uri_for(gem_repo1)}"
+ source "https://gem.repo3"
+ source "https://gem.repo1"
gem "rack-obama"
gem "rack"
G
end
it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first", :bundler => "< 3" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(err).to include("Installed from: #{file_uri_for(gem_repo1)}")
+ expect(err).to include("Installed from: https://gem.repo1")
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", :source => "remote1")
end
it "fails", :bundler => "3" do
- bundle :instal, :raise_on_error => false
+ bundle :instal, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
@@ -47,22 +47,22 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
gemfile <<-G
- source "#{file_uri_for(gem_repo3)}"
- source "#{file_uri_for(gem_repo1)}"
+ source "https://gem.repo3"
+ source "https://gem.repo1"
gem "rack-obama"
gem "rack", "1.0.0" # force it to install the working version in repo1
G
end
it "warns about ambiguous gems, but installs anyway", :bundler => "< 3" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(err).to include("Installed from: #{file_uri_for(gem_repo1)}")
+ expect(err).to include("Installed from: https://gem.repo1")
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", :source => "remote1")
end
it "fails", :bundler => "3" do
- bundle :install, :raise_on_error => false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
@@ -85,8 +85,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo3)}"
- source "#{file_uri_for(gem_repo1)}" do
+ source "https://gem.repo3"
+ source "https://gem.repo1" do
gem "thin" # comes first to test name sorting
gem "rack"
end
@@ -95,20 +95,20 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs the gems without any warning" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("rack-obama 1.0.0")
expect(the_bundle).to include_gems("rack 1.0.0", :source => "remote1")
end
it "can cache and deploy" do
- bundle :cache
+ bundle :cache, :artifice => "compact_index"
expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist
expect(bundled_app("vendor/cache/rack-obama-1.0.gem")).to exist
bundle "config set --local deployment true"
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0")
end
@@ -128,10 +128,10 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo3)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo3"
gem "rack-obama" # should come from repo3!
- gem "rack", :source => "#{file_uri_for(gem_repo1)}"
+ gem "rack", :source => "https://gem.repo1"
G
end
@@ -155,8 +155,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo2"
+ source "https://gem.repo3" do
gem "depends_on_rack"
end
G
@@ -168,7 +168,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs from the same source without any warning" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
@@ -185,7 +185,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs from the same source without any warning" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
@@ -193,7 +193,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
@@ -218,9 +218,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "and not in any other sources" do
before do
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
- source "#{file_uri_for(gem_repo3)}" do
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo2"
+ source "https://gem.repo3" do
gem "depends_on_rack"
end
G
@@ -235,23 +235,49 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "and in yet another source" do
before do
gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- source "#{file_uri_for(gem_repo2)}"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo1"
+ source "https://gem.repo2"
+ source "https://gem.repo3" do
gem "depends_on_rack"
end
G
end
it "installs from the other source and warns about ambiguous gems", :bundler => "< 3" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).to include("Warning: the gem 'rack' was found in multiple sources.")
- expect(err).to include("Installed from: #{file_uri_for(gem_repo2)}")
+ expect(err).to include("Installed from: https://gem.repo2")
+
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo1/
+ remote: https://gem.repo2/
+ specs:
+ rack (1.0.0)
+
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ depends_on_rack (1.0.1)
+ rack
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ depends_on_rack!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ previous_lockfile = lockfile
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
+ expect(lockfile).to eq(previous_lockfile)
end
it "fails", :bundler => "3" do
- bundle :install, :raise_on_error => false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
@@ -267,16 +293,16 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo3)}" # contains depends_on_rack
- source "#{file_uri_for(gem_repo2)}" # contains broken rack
+ source "https://gem.repo3" # contains depends_on_rack
+ source "https://gem.repo2" # contains broken rack
gem "depends_on_rack" # installed from gem_repo3
- gem "rack", :source => "#{file_uri_for(gem_repo1)}"
+ gem "rack", :source => "https://gem.repo1"
G
end
it "installs the dependency from the pinned source without warning", :bundler => "< 3" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
@@ -284,14 +310,14 @@ RSpec.describe "bundle install with gems on multiple sources" do
# In https://github.com/rubygems/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
it "fails", :bundler => "3" do
- bundle :install, :raise_on_error => false
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
expect(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4)
end
@@ -308,360 +334,508 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
+ source "https://gem.repo2"
gem "private_gem_1"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo3" do
gem "private_gem_2"
end
G
end
it "fails" do
- bundle :install, :raise_on_error => false
- expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository #{file_uri_for(gem_repo2)}/ or installed locally.")
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/ or installed locally.")
expect(err).to include("The source does not contain any versions of 'private_gem_1'")
end
end
+ context "when an indirect dependency can't be found in the aggregate rubygems source", :bundler => "< 3" do
+ before do
+ build_repo2
+
+ build_repo gem_repo3 do
+ build_gem "depends_on_missing", "1.0.1" do |s|
+ s.add_dependency "missing"
+ end
+ end
+
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ source "https://gem.repo3"
+
+ gem "depends_on_missing"
+ G
+ end
+
+ it "fails" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include("Could not find gem 'missing', which is required by gem 'depends_on_missing', in any of the sources.")
+ end
+ end
+
context "when a top-level gem has an indirect dependency" do
- context "when disable_multisource is set" do
- before do
- bundle "config set disable_multisource true"
+ before do
+ build_repo gem_repo2 do
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
+ end
+ end
+
+ build_repo gem_repo3 do
+ build_gem "unrelated_gem", "1.0.0"
end
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ gem "depends_on_rack"
+
+ source "https://gem.repo3" do
+ gem "unrelated_gem"
+ end
+ G
+ end
+
+ context "and the dependency is only in the top-level source" do
before do
- build_repo gem_repo2 do
- build_gem "depends_on_rack", "1.0.1" do |s|
- s.add_dependency "rack"
- end
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
end
+ end
- build_repo gem_repo3 do
- build_gem "unrelated_gem", "1.0.0"
+ it "installs the dependency from the top-level source without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("unrelated_gem 1.0.0", :source => "remote3")
+ end
+ end
+
+ context "and the dependency is only in a pinned source" do
+ before do
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
+ end
end
+ end
- gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
+ it "does not find the dependency" do
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
+ expect(err).to include(
+ "Could not find gem 'rack', which is required by gem 'depends_on_rack', in rubygems repository https://gem.repo2/ or installed locally."
+ )
+ end
+ end
- gem "depends_on_rack"
+ context "and the dependency is in both the top-level and a pinned source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
+ end
- source "#{file_uri_for(gem_repo3)}" do
- gem "unrelated_gem"
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
end
- G
+ end
end
- context "and the dependency is only in the top-level source" do
- before do
- update_repo gem_repo2 do
- build_gem "rack", "1.0.0"
- end
+ it "installs the dependency from the top-level source without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).not_to include("Warning")
+ expect(run("require 'rack'; puts RACK")).to eq("1.0.0")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("unrelated_gem 1.0.0", :source => "remote3")
+ end
+ end
+ end
+
+ context "when a scoped gem has a deeply nested indirect dependency" do
+ before do
+ build_repo gem_repo3 do
+ build_gem "depends_on_depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "depends_on_rack"
end
- it "installs all gems without warning" do
- bundle :install
- expect(err).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ build_gem "depends_on_rack", "1.0.1" do |s|
+ s.add_dependency "rack"
end
end
- context "and the dependency is only in a pinned source" do
- before do
- update_repo gem_repo3 do
- build_gem "rack", "1.0.0" do |s|
- s.write "lib/rack.rb", "RACK = 'FAIL'"
- end
- end
+ gemfile <<-G
+ source "https://gem.repo2"
+
+ source "https://gem.repo3" do
+ gem "depends_on_depends_on_rack"
end
+ G
+ end
- it "does not find the dependency" do
- bundle :install, :raise_on_error => false
- expect(err).to include("Could not find gem 'rack', which is required by gem 'depends_on_rack', in any of the relevant sources")
+ context "and the dependency is only in the top-level source" do
+ before do
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0"
end
end
- context "and the dependency is in both the top-level and a pinned source" do
- before do
- update_repo gem_repo2 do
- build_gem "rack", "1.0.0"
- end
+ it "installs the dependency from the top-level source" do
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0")
+ expect(the_bundle).to include_gems("rack 1.0.0", :source => "remote2")
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", :source => "remote3")
+ end
+ end
- update_repo gem_repo3 do
- build_gem "rack", "1.0.0" do |s|
- s.write "lib/rack.rb", "RACK = 'FAIL'"
- end
- end
- end
+ context "and the dependency is only in a pinned source" do
+ before do
+ build_repo2
- it "installs the dependency from the top-level source without warning" do
- bundle :install
- expect(err).not_to include("Warning")
- expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0")
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0"
end
end
+
+ it "installs the dependency from the pinned source" do
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
end
- context "when the lockfile has aggregated rubygems sources and newer versions of dependencies are available" do
+ context "and the dependency is in both the top-level and a pinned source" do
before do
- build_repo gem_repo2 do
- build_gem "activesupport", "6.0.3.4" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
- s.add_dependency "i18n", ">= 0.7", "< 2"
- s.add_dependency "minitest", "~> 5.1"
- s.add_dependency "tzinfo", "~> 1.1"
- s.add_dependency "zeitwerk", "~> 2.2", ">= 2.2.2"
+ update_repo gem_repo2 do
+ build_gem "rack", "1.0.0" do |s|
+ s.write "lib/rack.rb", "RACK = 'FAIL'"
end
+ end
- build_gem "activesupport", "6.1.2.1" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
- s.add_dependency "i18n", ">= 1.6", "< 2"
- s.add_dependency "minitest", ">= 5.1"
- s.add_dependency "tzinfo", "~> 2.0"
- s.add_dependency "zeitwerk", "~> 2.3"
- end
+ update_repo gem_repo3 do
+ build_gem "rack", "1.0.0"
+ end
+ end
+
+ it "installs the dependency from the pinned source without warning" do
+ bundle :install, :artifice => "compact_index"
+ expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
+ end
+ end
+ end
- build_gem "concurrent-ruby", "1.1.8"
- build_gem "concurrent-ruby", "1.1.9"
- build_gem "connection_pool", "2.2.3"
+ context "when the lockfile has aggregated rubygems sources and newer versions of dependencies are available" do
+ before do
+ build_repo gem_repo2 do
+ build_gem "activesupport", "6.0.3.4" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
+ s.add_dependency "i18n", ">= 0.7", "< 2"
+ s.add_dependency "minitest", "~> 5.1"
+ s.add_dependency "tzinfo", "~> 1.1"
+ s.add_dependency "zeitwerk", "~> 2.2", ">= 2.2.2"
+ end
- build_gem "i18n", "1.8.9" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0"
- end
+ build_gem "activesupport", "6.1.2.1" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0", ">= 1.0.2"
+ s.add_dependency "i18n", ">= 1.6", "< 2"
+ s.add_dependency "minitest", ">= 5.1"
+ s.add_dependency "tzinfo", "~> 2.0"
+ s.add_dependency "zeitwerk", "~> 2.3"
+ end
- build_gem "minitest", "5.14.3"
- build_gem "rack", "2.2.3"
- build_gem "redis", "4.2.5"
+ build_gem "concurrent-ruby", "1.1.8"
+ build_gem "concurrent-ruby", "1.1.9"
+ build_gem "connection_pool", "2.2.3"
- build_gem "sidekiq", "6.1.3" do |s|
- s.add_dependency "connection_pool", ">= 2.2.2"
- s.add_dependency "rack", "~> 2.0"
- s.add_dependency "redis", ">= 4.2.0"
- end
+ build_gem "i18n", "1.8.9" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0"
+ end
- build_gem "thread_safe", "0.3.6"
+ build_gem "minitest", "5.14.3"
+ build_gem "rack", "2.2.3"
+ build_gem "redis", "4.2.5"
- build_gem "tzinfo", "1.2.9" do |s|
- s.add_dependency "thread_safe", "~> 0.1"
- end
+ build_gem "sidekiq", "6.1.3" do |s|
+ s.add_dependency "connection_pool", ">= 2.2.2"
+ s.add_dependency "rack", "~> 2.0"
+ s.add_dependency "redis", ">= 4.2.0"
+ end
- build_gem "tzinfo", "2.0.4" do |s|
- s.add_dependency "concurrent-ruby", "~> 1.0"
- end
+ build_gem "thread_safe", "0.3.6"
- build_gem "zeitwerk", "2.4.2"
+ build_gem "tzinfo", "1.2.9" do |s|
+ s.add_dependency "thread_safe", "~> 0.1"
end
- build_repo gem_repo3 do
- build_gem "sidekiq-pro", "5.2.1" do |s|
- s.add_dependency "connection_pool", ">= 2.2.3"
- s.add_dependency "sidekiq", ">= 6.1.0"
- end
+ build_gem "tzinfo", "2.0.4" do |s|
+ s.add_dependency "concurrent-ruby", "~> 1.0"
end
- gemfile <<-G
- # frozen_string_literal: true
+ build_gem "zeitwerk", "2.4.2"
+ end
- source "#{file_uri_for(gem_repo2)}"
+ build_repo gem_repo3 do
+ build_gem "sidekiq-pro", "5.2.1" do |s|
+ s.add_dependency "connection_pool", ">= 2.2.3"
+ s.add_dependency "sidekiq", ">= 6.1.0"
+ end
+ end
- gem "activesupport"
+ gemfile <<-G
+ # frozen_string_literal: true
- source "#{file_uri_for(gem_repo3)}" do
- gem "sidekiq-pro"
- end
- G
+ source "https://gem.repo2"
- lockfile <<~L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- remote: #{file_uri_for(gem_repo3)}/
- specs:
- activesupport (6.0.3.4)
- concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- zeitwerk (~> 2.2, >= 2.2.2)
- concurrent-ruby (1.1.8)
- connection_pool (2.2.3)
- i18n (1.8.9)
- concurrent-ruby (~> 1.0)
- minitest (5.14.3)
- rack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- rack (~> 2.0)
- redis (>= 4.2.0)
- sidekiq-pro (5.2.1)
- connection_pool (>= 2.2.3)
- sidekiq (>= 6.1.0)
- thread_safe (0.3.6)
- tzinfo (1.2.9)
- thread_safe (~> 0.1)
- zeitwerk (2.4.2)
+ gem "activesupport"
- PLATFORMS
- #{specific_local_platform}
+ source "https://gem.repo3" do
+ gem "sidekiq-pro"
+ end
+ G
- DEPENDENCIES
- activesupport
- sidekiq-pro!
+ lockfile <<~L
+ GEM
+ remote: https://gem.repo2/
+ remote: https://gem.repo3/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.8)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
+ PLATFORMS
+ #{specific_local_platform}
- it "does not install newer versions or generate lockfile changes when running bundle install, and warns", :bundler => "< 3" do
- initial_lockfile = lockfile
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
- bundle :install
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
- expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ it "does not install newer versions but updates the lockfile format when running bundle install in non frozen mode, and doesn't warn" do
+ bundle :install, :artifice => "compact_index"
+ expect(err).to be_empty
- expect(the_bundle).to include_gems("activesupport 6.0.3.4")
- expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
- expect(the_bundle).to include_gems("tzinfo 1.2.9")
- expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
- expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
- expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
- expect(lockfile).to eq(initial_lockfile)
- end
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.8)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
- it "fails when running bundle install", :bundler => "3" do
- initial_lockfile = lockfile
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
- bundle :install, :raise_on_error => false
+ PLATFORMS
+ #{specific_local_platform}
- expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
- expect(lockfile).to eq(initial_lockfile)
- end
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
- it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
- bundle "update --all"
- expect(err).to be_empty
+ it "does not install newer versions or generate lockfile changes when running bundle install in frozen mode, and warns", :bundler => "< 3" do
+ initial_lockfile = lockfile
- expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
- expect(the_bundle).to include_gems("activesupport 6.1.2.1")
- expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
- expect(the_bundle).to include_gems("tzinfo 2.0.4")
- expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
- expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
+ bundle "config set --local frozen true"
+ bundle :install, :artifice => "compact_index"
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- specs:
- activesupport (6.1.2.1)
- concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 1.6, < 2)
- minitest (>= 5.1)
- tzinfo (~> 2.0)
- zeitwerk (~> 2.3)
- concurrent-ruby (1.1.9)
- connection_pool (2.2.3)
- i18n (1.8.9)
- concurrent-ruby (~> 1.0)
- minitest (5.14.3)
- rack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- rack (~> 2.0)
- redis (>= 4.2.0)
- tzinfo (2.0.4)
- concurrent-ruby (~> 1.0)
- zeitwerk (2.4.2)
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
- GEM
- remote: #{file_uri_for(gem_repo3)}/
- specs:
- sidekiq-pro (5.2.1)
- connection_pool (>= 2.2.3)
- sidekiq (>= 6.1.0)
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.9")
- PLATFORMS
- #{specific_local_platform}
+ expect(lockfile).to eq(initial_lockfile)
+ end
- DEPENDENCIES
- activesupport
- sidekiq-pro!
+ it "fails when running bundle install in frozen mode", :bundler => "3" do
+ initial_lockfile = lockfile
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
+ bundle "config set --local frozen true"
+ bundle :install, :artifice => "compact_index", :raise_on_error => false
- it "it keeps the current lockfile format and upgrades the requested gem when running bundle update with an argument, and warns", :bundler => "< 3" do
- bundle "update concurrent-ruby"
- expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
- expect(the_bundle).to include_gems("activesupport 6.0.3.4")
- expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
- expect(the_bundle).to include_gems("tzinfo 1.2.9")
- expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
- expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
- expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
+ expect(lockfile).to eq(initial_lockfile)
+ end
- expect(lockfile).to eq <<~L
- GEM
- remote: #{file_uri_for(gem_repo2)}/
- remote: #{file_uri_for(gem_repo3)}/
- specs:
- activesupport (6.0.3.4)
- concurrent-ruby (~> 1.0, >= 1.0.2)
- i18n (>= 0.7, < 2)
- minitest (~> 5.1)
- tzinfo (~> 1.1)
- zeitwerk (~> 2.2, >= 2.2.2)
- concurrent-ruby (1.1.9)
- connection_pool (2.2.3)
- i18n (1.8.9)
- concurrent-ruby (~> 1.0)
- minitest (5.14.3)
- rack (2.2.3)
- redis (4.2.5)
- sidekiq (6.1.3)
- connection_pool (>= 2.2.2)
- rack (~> 2.0)
- redis (>= 4.2.0)
- sidekiq-pro (5.2.1)
- connection_pool (>= 2.2.3)
- sidekiq (>= 6.1.0)
- thread_safe (0.3.6)
- tzinfo (1.2.9)
- thread_safe (~> 0.1)
- zeitwerk (2.4.2)
+ it "splits sections and upgrades gems when running bundle update, and doesn't warn" do
+ bundle "update --all", :artifice => "compact_index"
+ expect(err).to be_empty
- PLATFORMS
- #{specific_local_platform}
+ expect(the_bundle).not_to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).not_to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
- DEPENDENCIES
- activesupport
- sidekiq-pro!
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ activesupport (6.1.2.1)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 1.6, < 2)
+ minitest (>= 5.1)
+ tzinfo (~> 2.0)
+ zeitwerk (~> 2.3)
+ concurrent-ruby (1.1.9)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ tzinfo (2.0.4)
+ concurrent-ruby (~> 1.0)
+ zeitwerk (2.4.2)
- BUNDLED WITH
- #{Bundler::VERSION}
- L
- end
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
- it "fails when running bundle update with an argument", :bundler => "3" do
- initial_lockfile = lockfile
+ it "upgrades the lockfile format and upgrades the requested gem when running bundle update with an argument" do
+ bundle "update concurrent-ruby", :artifice => "compact_index"
+ expect(err).to be_empty
- bundle "update concurrent-ruby", :raise_on_error => false
+ expect(the_bundle).to include_gems("activesupport 6.0.3.4")
+ expect(the_bundle).not_to include_gems("activesupport 6.1.2.1")
+ expect(the_bundle).to include_gems("tzinfo 1.2.9")
+ expect(the_bundle).not_to include_gems("tzinfo 2.0.4")
+ expect(the_bundle).to include_gems("concurrent-ruby 1.1.9")
+ expect(the_bundle).not_to include_gems("concurrent-ruby 1.1.8")
- expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
+ expect(lockfile).to eq <<~L
+ GEM
+ remote: https://gem.repo2/
+ specs:
+ activesupport (6.0.3.4)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (>= 0.7, < 2)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ zeitwerk (~> 2.2, >= 2.2.2)
+ concurrent-ruby (1.1.9)
+ connection_pool (2.2.3)
+ i18n (1.8.9)
+ concurrent-ruby (~> 1.0)
+ minitest (5.14.3)
+ rack (2.2.3)
+ redis (4.2.5)
+ sidekiq (6.1.3)
+ connection_pool (>= 2.2.2)
+ rack (~> 2.0)
+ redis (>= 4.2.0)
+ thread_safe (0.3.6)
+ tzinfo (1.2.9)
+ thread_safe (~> 0.1)
+ zeitwerk (2.4.2)
- expect(lockfile).to eq(initial_lockfile)
- end
+ GEM
+ remote: https://gem.repo3/
+ specs:
+ sidekiq-pro (5.2.1)
+ connection_pool (>= 2.2.3)
+ sidekiq (>= 6.1.0)
+
+ PLATFORMS
+ #{specific_local_platform}
+
+ DEPENDENCIES
+ activesupport
+ sidekiq-pro!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
end
end
- context "when a top-level gem has an indirect dependency present in the default source, but with a different version from the one resolved", :bundler => "< 3" do
+ context "when a top-level gem has an indirect dependency present in the default source, but with a different version from the one resolved" do
before do
build_lib "activesupport", "7.0.0.alpha", :path => lib_path("rails/activesupport")
build_lib "rails", "7.0.0.alpha", :path => lib_path("rails") do |s|
@@ -677,7 +851,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
+ source "https://gem.repo2"
gemspec :path => "#{lib_path("rails")}"
@@ -686,7 +860,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "installs all gems without warning" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", "rails 7.0.0.alpha")
expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", :source => "path@#{lib_path("rails/activesupport")}")
@@ -711,9 +885,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
+ source "https://gem.repo2"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo3" do
gem "handsoap"
end
@@ -724,14 +898,14 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "installs from the default source without any warnings or errors and generates a proper lockfile" do
expected_lockfile = <<~L
GEM
- remote: #{file_uri_for(gem_repo2)}/
+ remote: https://gem.repo2/
specs:
nokogiri (1.11.1)
racca (~> 1.4)
racca (1.5.2)
GEM
- remote: #{file_uri_for(gem_repo3)}/
+ remote: https://gem.repo3/
specs:
handsoap (0.2.5.5)
nokogiri (>= 1.2.3)
@@ -747,7 +921,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
#{Bundler::VERSION}
L
- bundle "install --verbose"
+ bundle "install --verbose", :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
@@ -756,7 +930,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
# Even if the gems are already installed
FileUtils.rm bundled_app_lock
- bundle "install --verbose"
+ bundle "install --verbose", :artifice => "compact_index"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
@@ -771,9 +945,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "not_in_repo1", "1.0.0"
end
- install_gemfile <<-G, :raise_on_error => false
- source "#{file_uri_for(gem_repo3)}"
- gem "not_in_repo1", :source => "#{file_uri_for(gem_repo1)}"
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
+ source "https://gem.repo3"
+ gem "not_in_repo1", :source => "https://gem.repo1"
G
end
@@ -788,24 +962,24 @@ RSpec.describe "bundle install with gems on multiple sources" do
lockfile <<-L
GEM
- remote: #{file_uri_for(gem_repo1)}
+ remote: https://gem.repo1
specs:
GEM
- remote: #{file_uri_for(gem_repo3)}
+ remote: https://gem.repo3
specs:
rack (0.9.1)
PLATFORMS
- ruby
+ #{specific_local_platform}
DEPENDENCIES
rack!
L
gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo1"
+ source "https://gem.repo3" do
gem 'rack'
end
G
@@ -821,8 +995,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
let(:aggregate_gem_section_lockfile) do
<<~L
GEM
- remote: #{file_uri_for(gem_repo1)}/
- remote: #{file_uri_for(gem_repo3)}/
+ remote: https://gem.repo1/
+ remote: https://gem.repo3/
specs:
rack (0.9.1)
@@ -840,11 +1014,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
let(:split_gem_section_lockfile) do
<<~L
GEM
- remote: #{file_uri_for(gem_repo1)}/
+ remote: https://gem.repo1/
specs:
GEM
- remote: #{file_uri_for(gem_repo3)}/
+ remote: https://gem.repo3/
specs:
rack (0.9.1)
@@ -865,8 +1039,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo1"
+ source "https://gem.repo3" do
gem 'rack'
end
G
@@ -877,7 +1051,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "installs the existing lockfile but prints a warning", :bundler => "< 3" do
bundle "config set --local deployment true"
- bundle "install"
+ bundle "install", :artifice => "compact_index"
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
@@ -887,7 +1061,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "refuses to install the existing lockfile and prints an error", :bundler => "3" do
bundle "config set --local deployment true"
- bundle "install", :raise_on_error =>false
+ bundle "install", :artifice => "compact_index", :raise_on_error =>false
expect(lockfile).to eq(aggregate_gem_section_lockfile)
expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.")
@@ -900,13 +1074,13 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_lib "foo"
gemfile <<-G
- gem "rack", :source => "#{file_uri_for(gem_repo1)}"
+ gem "rack", :source => "https://gem.repo1"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
end
it "does not unlock the non-path gem after install" do
- bundle :install
+ bundle :install, :artifice => "compact_index"
bundle %(exec ruby -e 'puts "OK"')
@@ -919,8 +1093,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
before do
system_gems "rack-0.9.1"
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
gem "rack" # should come from repo1!
G
end
@@ -941,14 +1115,14 @@ RSpec.describe "bundle install with gems on multiple sources" do
# Installing this gemfile...
gemfile <<-G
- source '#{file_uri_for(gem_repo1)}'
+ source 'https://gem.repo1'
gem 'rack'
- gem 'foo', '~> 0.1', :source => '#{file_uri_for(gem_repo4)}'
- gem 'bar', '~> 0.1', :source => '#{file_uri_for(gem_repo4)}'
+ gem 'foo', '~> 0.1', :source => 'https://gem.repo4'
+ gem 'bar', '~> 0.1', :source => 'https://gem.repo4'
G
bundle "config set --local path ../gems/system"
- bundle :install
+ bundle :install, :artifice => "compact_index"
# And then we add some new versions...
update_repo4 do
@@ -959,11 +1133,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "allows them to be unlocked separately" do
# And install this gemfile, updating only foo.
- install_gemfile <<-G
- source '#{file_uri_for(gem_repo1)}'
+ install_gemfile <<-G, :artifice => "compact_index"
+ source 'https://gem.repo1'
gem 'rack'
- gem 'foo', '~> 0.2', :source => '#{file_uri_for(gem_repo4)}'
- gem 'bar', '~> 0.1', :source => '#{file_uri_for(gem_repo4)}'
+ gem 'foo', '~> 0.2', :source => 'https://gem.repo4'
+ gem 'bar', '~> 0.1', :source => 'https://gem.repo4'
G
# It should update foo to 0.2, but not the (locked) bar 0.1
@@ -983,11 +1157,11 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_git "git1"
build_git "git2"
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
gem "rails"
- source "#{file_uri_for(gem_repo3)}" do
+ source "https://gem.repo3" do
gem "rack"
end
@@ -999,7 +1173,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
it "does not re-resolve" do
- bundle :install, :verbose => true
+ bundle :install, :artifice => "compact_index", :verbose => true
expect(out).to include("using resolution from the lockfile")
expect(out).not_to include("re-resolving dependencies")
end
@@ -1008,27 +1182,24 @@ RSpec.describe "bundle install with gems on multiple sources" do
context "when a gem is installed to system gems" do
before do
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
gem "rack"
G
end
context "and the gemfile changes" do
it "is still able to find that gem from remote sources" do
- source_uri = file_uri_for(gem_repo1)
- second_uri = file_uri_for(gem_repo4)
-
build_repo4 do
build_gem "rack", "2.0.1.1.forked"
build_gem "thor", "0.19.1.1.forked"
end
# When this gemfile is installed...
- install_gemfile <<-G
- source "#{source_uri}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
- source "#{second_uri}" do
+ source "https://gem.repo4" do
gem "rack", "2.0.1.1.forked"
gem "thor"
end
@@ -1037,9 +1208,9 @@ RSpec.describe "bundle install with gems on multiple sources" do
# Then we change the Gemfile by adding a version to thor
gemfile <<-G
- source "#{source_uri}"
+ source "https://gem.repo1"
- source "#{second_uri}" do
+ source "https://gem.repo4" do
gem "rack", "2.0.1.1.forked"
gem "thor", "0.19.1.1.forked"
end
@@ -1047,15 +1218,15 @@ RSpec.describe "bundle install with gems on multiple sources" do
G
# But we should still be able to find rack 2.0.1.1.forked and install it
- bundle :install
+ bundle :install, :artifice => "compact_index"
end
end
end
describe "source changed to one containing a higher version of a dependency" do
before do
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo1)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo1"
gem "rack"
G
@@ -1072,8 +1243,8 @@ RSpec.describe "bundle install with gems on multiple sources" do
s.add_dependency "bar", "=1.0.0"
end
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo2)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo2"
gem "rack"
gemspec :path => "#{tmp.join("gemspec_test")}"
G
@@ -1093,10 +1264,10 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "example", "1.0.2"
end
- install_gemfile <<-G
- source "#{file_uri_for(gem_repo4)}"
+ install_gemfile <<-G, :artifice => "compact_index"
+ source "https://gem.repo4"
- gem "example", :source => "#{file_uri_for(gem_repo2)}"
+ gem "example", :source => "https://gem.repo2"
G
bundle "info example"
@@ -1104,12 +1275,60 @@ RSpec.describe "bundle install with gems on multiple sources" do
system_gems "example-1.0.2", :path => default_bundle_path, :gem_repo => gem_repo4
- bundle "update example --verbose"
+ bundle "update example --verbose", :artifice => "compact_index"
expect(out).not_to include("Using example 1.0.2")
expect(out).to include("Using example 0.1.0")
end
- context "when a gem is available from multiple ambiguous sources", :bundler => "3" do
+ it "fails inmmediately with a helpful error when a non retriable network error happens while resolving sources" do
+ gemfile <<-G
+ source "https://gem.repo1"
+
+ source "https://gem.repo4" do
+ gem "example"
+ end
+ G
+
+ simulate_bundler_version_when_missing_prerelease_default_gem_activation do
+ ruby <<~R, :raise_on_error => false
+ require 'bundler/setup'
+ R
+ end
+
+ expect(last_command).to be_failure
+ expect(err).to include("Could not reach host gem.repo4. Check your network connection and try again.")
+ end
+
+ context "when an indirect dependency is available from multiple ambiguous sources", :bundler => "< 3" do
+ it "succeeds but warns, suggesting a source block" do
+ build_repo4 do
+ build_gem "depends_on_rack" do |s|
+ s.add_dependency "rack"
+ end
+ build_gem "rack"
+ end
+
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
+ source "https://gem.repo4" do
+ gem "depends_on_rack"
+ end
+
+ source "https://gem.repo1" do
+ gem "thin"
+ end
+ G
+ expect(err).to eq strip_whitespace(<<-EOS).strip
+ Warning: The gem 'rack' was found in multiple relevant sources.
+ * rubygems repository https://gem.repo1/ or installed locally
+ * rubygems repository https://gem.repo4/ or installed locally
+ You should add this gem to the source block for the source you wish it to be installed from.
+ EOS
+ expect(last_command).to be_success
+ expect(the_bundle).to be_locked
+ end
+ end
+
+ context "when an indirect dependency is available from multiple ambiguous sources", :bundler => "3" do
it "raises, suggesting a source block" do
build_repo4 do
build_gem "depends_on_rack" do |s|
@@ -1118,18 +1337,19 @@ RSpec.describe "bundle install with gems on multiple sources" do
build_gem "rack"
end
- install_gemfile <<-G, :raise_on_error => false
- source "#{file_uri_for(gem_repo4)}"
- source "#{file_uri_for(gem_repo1)}" do
+ install_gemfile <<-G, :artifice => "compact_index", :raise_on_error => false
+ source "https://gem.repo4" do
+ gem "depends_on_rack"
+ end
+ source "https://gem.repo1" do
gem "thin"
end
- gem "depends_on_rack"
G
expect(last_command).to be_failure
expect(err).to eq strip_whitespace(<<-EOS).strip
The gem 'rack' was found in multiple relevant sources.
- * rubygems repository #{file_uri_for(gem_repo1)}/ or installed locally
- * rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally
+ * rubygems repository https://gem.repo1/ or installed locally
+ * rubygems repository https://gem.repo4/ or installed locally
You must add this gem to the source block for the source you wish it to be installed from.
EOS
expect(the_bundle).not_to be_locked
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index a5b78443b9..c6e526a95e 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -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
diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb
index 9454508e41..8be97ed5d2 100644
--- a/spec/bundler/install/gems/compact_index_spec.rb
+++ b/spec/bundler/install/gems/compact_index_spec.rb
@@ -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
diff --git a/spec/bundler/install/gems/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_spec.rb
index d8d2ac1668..eae8daa682 100644
--- a/spec/bundler/install/gems/dependency_api_spec.rb
+++ b/spec/bundler/install/gems/dependency_api_spec.rb
@@ -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"
diff --git a/spec/bundler/install/global_cache_spec.rb b/spec/bundler/install/global_cache_spec.rb
index f3609715fb..68ebef2d89 100644
--- a/spec/bundler/install/global_cache_spec.rb
+++ b/spec/bundler/install/global_cache_spec.rb
@@ -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"
diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb
index d68410824e..0fbe9ee80d 100644
--- a/spec/bundler/lock/lockfile_spec.rb
+++ b/spec/bundler/lock/lockfile_spec.rb
@@ -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) }
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index 92b05d8b74..3ffb138104 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -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
diff --git a/spec/bundler/realworld/double_check_spec.rb b/spec/bundler/realworld/double_check_spec.rb
index 07697f080e..d7f28d10bb 100644
--- a/spec/bundler/realworld/double_check_spec.rb
+++ b/spec/bundler/realworld/double_check_spec.rb
@@ -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: "."
diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb
index 9f6ae399af..e0844bbeba 100644
--- a/spec/bundler/realworld/edgecases_spec.rb
+++ b/spec/bundler/realworld/edgecases_spec.rb
@@ -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)
diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb
index 57b7392608..cfcf556658 100644
--- a/spec/bundler/runtime/inline_spec.rb
+++ b/spec/bundler/runtime/inline_spec.rb
@@ -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
diff --git a/spec/bundler/runtime/load_spec.rb b/spec/bundler/runtime/load_spec.rb
index 0274ba18b8..96a22a46cc 100644
--- a/spec/bundler/runtime/load_spec.rb
+++ b/spec/bundler/runtime/load_spec.rb
@@ -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
diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb
index bec42e0f70..d81bccbdf8 100644
--- a/spec/bundler/runtime/platform_spec.rb
+++ b/spec/bundler/runtime/platform_spec.rb
@@ -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"
diff --git a/spec/bundler/runtime/require_spec.rb b/spec/bundler/runtime/require_spec.rb
index ad30529e86..a3fa4fbe47 100644
--- a/spec/bundler/runtime/require_spec.rb
+++ b/spec/bundler/runtime/require_spec.rb
@@ -192,7 +192,7 @@ RSpec.describe "Bundler.require" do
G
cmd = <<-RUBY
- require '#{lib_dir}/bundler'
+ require '#{entrypoint}'
Bundler.require
RUBY
ruby(cmd)
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index 4d5e1c616e..d8ba569f0a 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -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
diff --git a/spec/bundler/support/artifice/endpoint.rb b/spec/bundler/support/artifice/endpoint.rb
index e0650fa7d5..37ca378ef9 100644
--- a/spec/bundler/support/artifice/endpoint.rb
+++ b/spec/bundler/support/artifice/endpoint.rb
@@ -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
diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb
index 6fb0c6cb1c..2df41028fc 100644
--- a/spec/bundler/support/helpers.rb
+++ b/spec/bundler/support/helpers.rb
@@ -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
diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb
index 1f3c4ddaa6..bf4300edb2 100644
--- a/spec/bundler/support/indexes.rb
+++ b/spec/bundler/support/indexes.rb
@@ -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
diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb
index 1613662981..3c1014edc7 100644
--- a/spec/bundler/support/matchers.rb
+++ b/spec/bundler/support/matchers.rb
@@ -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?
diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb
index a9e9704cf9..000b3f87b8 100644
--- a/spec/bundler/support/path.rb
+++ b/spec/bundler/support/path.rb
@@ -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
diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb
index 6635481a9f..fbdc34e357 100644
--- a/test/rubygems/helper.rb
+++ b/test/rubygems/helper.rb
@@ -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'
diff --git a/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem b/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem
new file mode 100644
index 0000000000..58a13535c2
--- /dev/null
+++ b/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem
Binary files differ
diff --git a/test/rubygems/test_gem_bundler_version_finder.rb b/test/rubygems/test_gem_bundler_version_finder.rb
index 4ba3b9accf..e971e6ae29 100644
--- a/test/rubygems/test_gem_bundler_version_finder.rb
+++ b/test/rubygems/test_gem_bundler_version_finder.rb
@@ -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
diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb
index 669740fceb..43ce6ea39f 100644
--- a/test/rubygems/test_gem_command.rb
+++ b/test/rubygems/test_gem_command.rb
@@ -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
diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb
index ac315538cc..a70dd770e1 100644
--- a/test/rubygems/test_gem_commands_help_command.rb
+++ b/test/rubygems/test_gem_commands_help_command.rb
@@ -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
diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb
index e1bc22dbae..fa3968ffce 100644
--- a/test/rubygems/test_gem_commands_push_command.rb
+++ b/test/rubygems/test_gem_commands_push_command.rb
@@ -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
diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb
index 21e2e9e6e4..3aa6bfa2fe 100644
--- a/test/rubygems/test_gem_commands_setup_command.rb
+++ b/test/rubygems/test_gem_commands_setup_command.rb
@@ -175,7 +175,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
assert_path_exist File.join(dir, 'bundler.rb')
assert_path_exist File.join(dir, 'bundler/b.rb')
- assert_path_exist File.join(dir, 'bundler/templates/.circleci/config.yml') unless RUBY_ENGINE == "truffleruby" # https://github.com/oracle/truffleruby/issues/2116
+ assert_path_exist File.join(dir, 'bundler/templates/.circleci/config.yml')
assert_path_exist File.join(dir, 'bundler/templates/.travis.yml')
end
end
@@ -272,7 +272,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase
@cmd.remove_old_lib_files lib
- files_that_go.each {|file| assert_path_not_exist(file) unless file == old_bundler_ci && RUBY_ENGINE == "truffleruby" } # https://github.com/oracle/truffleruby/issues/2116
+ files_that_go.each {|file| assert_path_not_exist(file) unless file == old_bundler_ci }
files_that_stay.each {|file| assert_path_exist file }
end
diff --git a/test/rubygems/test_gem_commands_signin_command.rb b/test/rubygems/test_gem_commands_signin_command.rb
index 8f2477035c..eaf32886b3 100644
--- a/test/rubygems/test_gem_commands_signin_command.rb
+++ b/test/rubygems/test_gem_commands_signin_command.rb
@@ -26,6 +26,13 @@ class TestGemCommandsSigninCommand < Gem::TestCase
assert_match %r{Signed in.}, sign_in_ui.output
end
+ def test_execute_when_not_already_signed_in_and_not_preexisting_credentials_folder
+ FileUtils.rm Gem.configuration.credentials_path
+
+ sign_in_ui = util_capture { @cmd.execute }
+ assert_match %r{Signed in.}, sign_in_ui.output
+ end
+
def test_execute_when_already_signed_in_with_same_host
host = 'http://some-gemcutter-compatible-host.org'
diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb
index 828021c119..1ca0fc378c 100644
--- a/test/rubygems/test_gem_dependency.rb
+++ b/test/rubygems/test_gem_dependency.rb
@@ -3,6 +3,12 @@ require_relative 'helper'
require 'rubygems/dependency'
class TestGemDependency < Gem::TestCase
+ def setup
+ super
+
+ without_any_upwards_gemfiles
+ end
+
def test_initialize
d = dep "pkg", "> 1.0"
diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb
index b765c17ed1..165194510e 100644
--- a/test/rubygems/test_gem_ext_builder.rb
+++ b/test/rubygems/test_gem_ext_builder.rb
@@ -106,7 +106,7 @@ install:
end
def test_build_extensions
- skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
+ pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
@spec.extensions << 'ext/extconf.rb'
ext_dir = File.join @spec.gem_dir, 'ext'
@@ -142,7 +142,7 @@ install:
end
def test_build_extensions_with_gemhome_with_space
- skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
+ pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
new_gemhome = File.join @tempdir, 'gem home'
File.rename(@gemhome, new_gemhome)
@gemhome = new_gemhome
@@ -163,7 +163,7 @@ install:
false
end
end
- skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
+ pend if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning
@spec.extensions << 'ext/extconf.rb'
diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb
index 9279756d63..70833f35cf 100644
--- a/test/rubygems/test_gem_ext_ext_conf_builder.rb
+++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb
@@ -41,6 +41,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
assert_contains_make_command '', output[7]
assert_contains_make_command 'install', output[10]
assert_empty Dir.glob(File.join(@ext, 'siteconf*.rb'))
+ assert_empty Dir.glob(File.join(@ext, '.gem.*'))
end
def test_class_build_rbconfig_make_prog
diff --git a/test/rubygems/test_gem_ext_rake_builder.rb b/test/rubygems/test_gem_ext_rake_builder.rb
index 5dff29ff6e..3d8922eed5 100644
--- a/test/rubygems/test_gem_ext_rake_builder.rb
+++ b/test/rubygems/test_gem_ext_rake_builder.rb
@@ -48,6 +48,8 @@ class TestGemExtRakeBuilder < Gem::TestCase
end
def test_class_no_openssl_override
+ pend 'openssl is missing' unless Gem::HAVE_OPENSSL
+
create_temp_mkrf_file('task :default')
rake = util_spec 'rake' do |s|
diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb
index bb76fd2154..23aff00cbe 100644
--- a/test/rubygems/test_gem_gemcutter_utilities.rb
+++ b/test/rubygems/test_gem_gemcutter_utilities.rb
@@ -35,8 +35,6 @@ class TestGemGemcutterUtilities < Gem::TestCase
"http://rubygems.engineyard.com" => "EYKEY",
}
- FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
-
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end
@@ -50,7 +48,6 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_api_key
keys = { :rubygems_api_key => 'KEY' }
- FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
@@ -63,7 +60,6 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_api_key_override
keys = { :rubygems_api_key => 'KEY', :other => 'OTHER' }
- FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
@@ -168,7 +164,6 @@ class TestGemGemcutterUtilities < Gem::TestCase
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf'
- FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path)
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write Hash[:other_api_key, other_api_key].to_yaml
end
@@ -246,7 +241,6 @@ class TestGemGemcutterUtilities < Gem::TestCase
def test_verify_api_key
keys = {:other => 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'}
- FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path)
File.open Gem.configuration.credentials_path, 'w' do |f|
f.write keys.to_yaml
end
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index bb1126748e..a2b390d639 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -1776,6 +1776,26 @@ gem 'other', version
end
end
+ def test_pre_install_checks_malicious_platform_before_eval
+ gem_with_ill_formated_platform = File.expand_path("packages/ill-formatted-platform-1.0.0.10.gem", __dir__)
+
+ installer = Gem::Installer.at(
+ gem_with_ill_formated_platform,
+ :install_dir => @gem_home,
+ :user_install => false,
+ :force => true
+ )
+
+ use_ui @ui do
+ e = assert_raise Gem::InstallError do
+ installer.pre_install_checks
+ end
+
+ assert_equal "x86-mswin32\n system('id > /tmp/nyangawa')# is an invalid platform", e.message
+ assert_empty @ui.output
+ end
+ end
+
def test_shebang
installer = setup_base_installer
diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb
index e145310168..20509c8f3d 100644
--- a/test/rubygems/test_gem_specification.rb
+++ b/test/rubygems/test_gem_specification.rb
@@ -3612,7 +3612,7 @@ Did you mean 'Ruby'?
@m2.validate
end
- assert_equal "metadata key too large (129 > 128)", e.message
+ assert_equal "metadata key is too large (129 > 128)", e.message
end
end
@@ -3629,7 +3629,7 @@ Did you mean 'Ruby'?
@m2.validate
end
- assert_equal "metadata values must be a String", e.message
+ assert_equal "metadata['fail'] value must be a String", e.message
end
end
@@ -3646,7 +3646,7 @@ Did you mean 'Ruby'?
@m2.validate
end
- assert_equal "metadata value too large (1025 > 1024)", e.message
+ assert_equal "metadata['fail'] value is too large (1025 > 1024)", e.message
end
end
diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb
index 28dbe15006..dee36d05ee 100644
--- a/test/rubygems/test_kernel.rb
+++ b/test/rubygems/test_kernel.rb
@@ -8,6 +8,8 @@ class TestKernel < Gem::TestCase
@old_path = $:.dup
util_make_gems
+
+ without_any_upwards_gemfiles
end
def teardown
diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb
index 1c33dafbe2..07e412cc76 100644
--- a/test/rubygems/test_require.rb
+++ b/test/rubygems/test_require.rb
@@ -679,8 +679,6 @@ class TestGemRequire < Gem::TestCase
end
def test_no_crash_when_overriding_warn_with_warning_module
- pend "https://github.com/oracle/truffleruby/issues/2109" if RUBY_ENGINE == "truffleruby"
-
Dir.mktmpdir("warn_test") do |dir|
File.write(dir + "/main.rb", "module Warning; def warn(str); super; end; end; warn 'Foo Bar'")
_, err = capture_subprocess_io do