Merge the latest stable versions of RubyGems and Bundler to Ruby 3.2.x (#7061)

[Bug #19350]

* Merge RubyGems-3.4.2 and Bundler-2.4.2

* Merge RubyGems-3.4.3 and Bundler-2.4.3

* Generate parser-text.rb of racc when sync it

* Ignore LICENSE files of libraries vendored in rubygems [ci skip]

* Adjust spec of bundler like as `sync_default_gems` [ci skip]

* Fixed a typo

* Removed vendored LICENSE file.

* Update LEGAL sections for pub_grub

* Merge RubyGems-3.4.4 and Bundler-2.4.4

* Merge RubyGems-3.4.5 and Bundler-2.4.5

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
This commit is contained in:
Hiroshi SHIBATA 2023-01-25 23:32:01 +09:00 committed by GitHub
parent fee5b8f263
commit a22eca8231
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
105 changed files with 1337 additions and 752 deletions

10
LEGAL
View file

@ -979,7 +979,6 @@ mentioned below.
{MIT License}[rdoc-label:label-MIT+License] {MIT License}[rdoc-label:label-MIT+License]
[lib/rubygems/resolver/molinillo] [lib/rubygems/resolver/molinillo]
[lib/bundler/vendor/molinillo]
molinillo is under the following license. molinillo is under the following license.
@ -988,6 +987,15 @@ mentioned below.
{MIT License}[rdoc-label:label-MIT+License] {MIT License}[rdoc-label:label-MIT+License]
[lib/bundler/vendor/pub_grub]
pub_grub is under the following license.
>>>
Copyright (c) 2018 John Hawthorn
{MIT License}[rdoc-label:label-MIT+License]
[lib/bundler/vendor/connection_pool] [lib/bundler/vendor/connection_pool]
connection_pool is under the following license. connection_pool is under the following license.

View file

@ -509,6 +509,7 @@ module Bundler
subcommand "config", Config subcommand "config", Config
desc "open GEM", "Opens the source directory of the given bundled gem" desc "open GEM", "Opens the source directory of the given bundled gem"
method_option "path", :type => :string, :lazy_default => "", :banner => "Open relative path of the gem source."
def open(name) def open(name)
require_relative "cli/open" require_relative "cli/open"
Open.new(options, name).run Open.new(options, name).run

View file

@ -2,23 +2,25 @@
module Bundler module Bundler
class CLI::Open class CLI::Open
attr_reader :options, :name attr_reader :options, :name, :path
def initialize(options, name) def initialize(options, name)
@options = options @options = options
@name = name @name = name
@path = options[:path] unless options[:path].nil?
end end
def run def run
raise InvalidOption, "Cannot specify `--path` option without a value" if !@path.nil? && @path.empty?
editor = [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? } editor = [ENV["BUNDLER_EDITOR"], ENV["VISUAL"], ENV["EDITOR"]].find {|e| !e.nil? && !e.empty? }
return Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") unless editor return Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") unless editor
return unless spec = Bundler::CLI::Common.select_spec(name, :regex_match) return unless spec = Bundler::CLI::Common.select_spec(name, :regex_match)
if spec.default_gem? if spec.default_gem?
Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist." Bundler.ui.info "Unable to open #{name} because it's a default gem, so the directory it would normally be installed to does not exist."
else else
path = spec.full_gem_path root_path = spec.full_gem_path
Dir.chdir(path) do Dir.chdir(root_path) do
require "shellwords" require "shellwords"
command = Shellwords.split(editor) + [path] command = Shellwords.split(editor) << File.join([root_path, path].compact)
Bundler.with_original_env do Bundler.with_original_env do
system(*command) system(*command)
end || Bundler.ui.info("Could not run '#{command.join(" ")}'") end || Bundler.ui.info("Could not run '#{command.join(" ")}'")

View file

@ -79,6 +79,7 @@ module Bundler
@locked_bundler_version = nil @locked_bundler_version = nil
@locked_ruby_version = nil @locked_ruby_version = nil
@new_platform = nil @new_platform = nil
@removed_platform = nil
if lockfile && File.exist?(lockfile) if lockfile && File.exist?(lockfile)
@lockfile_contents = Bundler.read_file(lockfile) @lockfile_contents = Bundler.read_file(lockfile)
@ -129,7 +130,7 @@ module Bundler
end end
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version) @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
add_current_platform unless current_ruby_platform_locked? || Bundler.frozen_bundle? add_current_platform unless Bundler.frozen_bundle?
converge_path_sources_to_gemspec_sources converge_path_sources_to_gemspec_sources
@path_changes = converge_paths @path_changes = converge_paths
@ -158,13 +159,6 @@ module Bundler
resolve resolve
end end
def resolve_prefering_local!
@prefer_local = true
@remote = true
sources.remote!
resolve
end
def resolve_with_cache! def resolve_with_cache!
sources.cached! sources.cached!
resolve resolve
@ -176,6 +170,23 @@ module Bundler
resolve resolve
end end
def resolution_mode=(options)
if options["local"]
@remote = false
else
@remote = true
@prefer_local = options["prefer-local"]
end
end
def setup_sources_for_resolve
if @remote == false
sources.cached!
else
sources.remote!
end
end
# For given dependency list returns a SpecSet with Gemspec of all the required # For given dependency list returns a SpecSet with Gemspec of all the required
# dependencies. # dependencies.
# 1. The method first resolves the dependencies specified in Gemfile # 1. The method first resolves the dependencies specified in Gemfile
@ -267,7 +278,7 @@ module Bundler
SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps)) SpecSet.new(filter_specs(@locked_specs, @dependencies - deleted_deps))
else else
Bundler.ui.debug "Found no changes, using resolution from the lockfile" Bundler.ui.debug "Found no changes, using resolution from the lockfile"
if @locked_gems.may_include_redundant_platform_specific_gems? if @removed_platform || @locked_gems.may_include_redundant_platform_specific_gems?
SpecSet.new(filter_specs(@locked_specs, @dependencies)) SpecSet.new(filter_specs(@locked_specs, @dependencies))
else else
@locked_specs @locked_specs
@ -446,7 +457,9 @@ module Bundler
end end
def remove_platform(platform) def remove_platform(platform)
return if @platforms.delete(Gem::Platform.new(platform)) removed_platform = @platforms.delete(Gem::Platform.new(platform))
@removed_platform ||= removed_platform
return if removed_platform
raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}" raise InvalidOption, "Unable to remove the platform `#{platform}` since the only platforms are #{@platforms.join ", "}"
end end
@ -470,31 +483,19 @@ module Bundler
private private
def resolver def resolver
@resolver ||= begin @resolver ||= Resolver.new(resolution_packages, gem_version_promoter)
last_resolve = converge_locked_specs
remove_ruby_from_platforms_if_necessary!(current_dependencies)
Resolver.new(source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve(last_resolve))
end
end end
def expanded_dependencies def expanded_dependencies
@expanded_dependencies ||= dependencies + metadata_dependencies dependencies + metadata_dependencies
end end
def resolution_packages def resolution_packages
@resolution_packages ||= begin @resolution_packages ||= begin
packages = Hash.new do |h, k| last_resolve = converge_locked_specs
h[k] = Resolver::Package.new(k, @platforms, @originally_locked_specs, @unlock[:gems]) remove_ruby_from_platforms_if_necessary!(current_dependencies)
end packages = Resolver::Base.new(source_requirements, expanded_dependencies, last_resolve, @platforms, :locked_specs => @originally_locked_specs, :unlock => @unlock[:gems], :prerelease => gem_version_promoter.pre?)
additional_base_requirements_for_resolve(packages, last_resolve)
expanded_dependencies.each do |dep|
name = dep.name
platforms = dep.gem_platforms(@platforms)
packages[name] = Resolver::Package.new(name, platforms, @originally_locked_specs, @unlock[:gems], :dependency => dep)
end
packages
end end
end end
@ -528,13 +529,15 @@ module Bundler
break if incomplete_specs.empty? break if incomplete_specs.empty?
Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies") Bundler.ui.debug("The lockfile does not have all gems needed for the current platform though, Bundler will still re-resolve dependencies")
@resolve = start_resolution(:exclude_specs => incomplete_specs) setup_sources_for_resolve
resolution_packages.delete(incomplete_specs)
@resolve = start_resolution
specs = resolve.materialize(dependencies) specs = resolve.materialize(dependencies)
still_incomplete_specs = specs.incomplete_specs still_incomplete_specs = specs.incomplete_specs
if still_incomplete_specs == incomplete_specs if still_incomplete_specs == incomplete_specs
package = resolution_packages[incomplete_specs.first.name] package = resolution_packages.get_package(incomplete_specs.first.name)
resolver.raise_not_found! package resolver.raise_not_found! package
end end
@ -547,14 +550,14 @@ module Bundler
specs specs
end end
def start_resolution(exclude_specs: []) def start_resolution
result = resolver.start(expanded_dependencies, resolution_packages, :exclude_specs => exclude_specs) result = resolver.start
SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms)) SpecSet.new(SpecSet.new(result).for(dependencies, false, @platforms))
end end
def precompute_source_requirements_for_indirect_dependencies? def precompute_source_requirements_for_indirect_dependencies?
@remote && sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source? sources.non_global_rubygems_sources.all?(&:dependency_api_available?) && !sources.aggregate_global_source?
end end
def pin_locally_available_names(source_requirements) def pin_locally_available_names(source_requirements)
@ -584,6 +587,8 @@ module Bundler
end end
def add_current_platform def add_current_platform
return if current_ruby_platform_locked?
add_platform(local_platform) add_platform(local_platform)
end end
@ -880,11 +885,12 @@ module Bundler
current == proposed current == proposed
end end
def additional_base_requirements_for_resolve(last_resolve) def additional_base_requirements_for_resolve(resolution_packages, last_resolve)
return [] unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources) return resolution_packages unless @locked_gems && unlocking? && !sources.expired_sources?(@locked_gems.sources)
converge_specs(@originally_locked_specs - last_resolve).map do |locked_spec| converge_specs(@originally_locked_specs - last_resolve).each do |locked_spec|
Dependency.new(locked_spec.name, ">= #{locked_spec.version}") resolution_packages.base_requirements[locked_spec.name] = Gem::Requirement.new(">= #{locked_spec.version}")
end.uniq end
resolution_packages
end end
def remove_ruby_from_platforms_if_necessary!(dependencies) def remove_ruby_from_platforms_if_necessary!(dependencies)

View file

@ -277,8 +277,8 @@ module Bundler
if repo_name =~ GITHUB_PULL_REQUEST_URL if repo_name =~ GITHUB_PULL_REQUEST_URL
{ {
"git" => "https://github.com/#{$1}.git", "git" => "https://github.com/#{$1}.git",
"branch" => "refs/pull/#{$2}/head", "branch" => nil,
"ref" => nil, "ref" => "refs/pull/#{$2}/head",
"tag" => nil, "tag" => nil,
} }
else else

View file

@ -249,17 +249,13 @@ module Bundler
# returns whether or not a re-resolve was needed # returns whether or not a re-resolve was needed
def resolve_if_needed(options) def resolve_if_needed(options)
@definition.resolution_mode = options
if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file? if !@definition.unlocking? && !options["force"] && !Bundler.settings[:inline] && Bundler.default_lockfile.file?
return false if @definition.nothing_changed? && !@definition.missing_specs? return false if @definition.nothing_changed? && !@definition.missing_specs?
end end
if options["local"] @definition.setup_sources_for_resolve
@definition.resolve_with_cache!
elsif options["prefer-local"]
@definition.resolve_prefering_local!
else
@definition.resolve_remotely!
end
true true
end end

View file

@ -16,7 +16,6 @@ module Bundler
@dependencies = [] @dependencies = []
@platform = platform || Gem::Platform::RUBY @platform = platform || Gem::Platform::RUBY
@source = source @source = source
@specification = nil
@force_ruby_platform = default_force_ruby_platform @force_ruby_platform = default_force_ruby_platform
end end
@ -80,37 +79,46 @@ module Bundler
def materialize_for_installation def materialize_for_installation
source.local! source.local!
candidates = if source.is_a?(Source::Path) || !ruby_platform_materializes_to_ruby_platform? matching_specs = source.specs.search(use_exact_resolved_specifications? ? self : [name, version])
return self if matching_specs.empty?
candidates = if use_exact_resolved_specifications?
matching_specs
else
target_platform = ruby_platform_materializes_to_ruby_platform? ? platform : local_platform target_platform = ruby_platform_materializes_to_ruby_platform? ? platform : local_platform
GemHelpers.select_best_platform_match(source.specs.search([name, version]), target_platform) installable_candidates = GemHelpers.select_best_platform_match(matching_specs, target_platform)
else
source.specs.search(self)
end
return self if candidates.empty? specification = __materialize__(installable_candidates, :fallback_to_non_installable => false)
return specification unless specification.nil?
if target_platform != platform
installable_candidates = GemHelpers.select_best_platform_match(matching_specs, platform)
end
installable_candidates
end
__materialize__(candidates) __materialize__(candidates)
end end
def __materialize__(candidates) # If in frozen mode, we fallback to a non-installable candidate because by
@specification = begin # doing this we avoid re-resolving and potentially end up changing the
search = candidates.reverse.find do |spec| # lock file, which is not allowed. In that case, we will give a proper error
spec.is_a?(StubSpecification) || # about the mismatch higher up the stack, right before trying to install the
(spec.matches_current_ruby? && # bad gem.
spec.matches_current_rubygems?) def __materialize__(candidates, fallback_to_non_installable: Bundler.frozen_bundle?)
end search = candidates.reverse.find do |spec|
if search.nil? && Bundler.frozen_bundle? spec.is_a?(StubSpecification) ||
search = candidates.last (spec.matches_current_ruby? &&
else spec.matches_current_rubygems?)
search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
end
search
end end
end if search.nil? && fallback_to_non_installable
search = candidates.last
def respond_to?(*args) else
super || @specification ? @specification.respond_to?(*args) : nil search.dependencies = dependencies if search && search.full_name == full_name && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
end
search
end end
def to_s def to_s
@ -132,16 +140,8 @@ module Bundler
private private
def to_ary def use_exact_resolved_specifications?
nil @use_exact_resolved_specifications ||= !source.is_a?(Source::Path) && ruby_platform_materializes_to_ruby_platform?
end
def method_missing(method, *args, &blk)
raise "LazySpecification has not been materialized yet (calling :#{method} #{args.inspect})" unless @specification
return super unless respond_to?(method)
@specification.send(method, *args, &blk)
end end
# #

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-ADD" "1" "December 2022" "" "" .TH "BUNDLE\-ADD" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install \fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-BINSTUBS" "1" "December 2022" "" "" .TH "BUNDLE\-BINSTUBS" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems \fBbundle\-binstubs\fR \- Install the binstubs of the listed gems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-CACHE" "1" "December 2022" "" "" .TH "BUNDLE\-CACHE" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application \fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-CHECK" "1" "December 2022" "" "" .TH "BUNDLE\-CHECK" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems \fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-CLEAN" "1" "December 2022" "" "" .TH "BUNDLE\-CLEAN" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory \fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-CONFIG" "1" "December 2022" "" "" .TH "BUNDLE\-CONFIG" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options \fBbundle\-config\fR \- Set bundler configuration options
@ -39,7 +39,7 @@ Bundler default config
.IP "" 0 .IP "" 0
. .
.P .P
Executing \fBbundle config list\fR with will print a list of all bundler configuration for the current bundle, and where that configuration was set\. Executing \fBbundle config list\fR will print a list of all bundler configuration for the current bundle, and where that configuration was set\.
. .
.P .P
Executing \fBbundle config get <name>\fR will print the value of that configuration setting, and where it was set\. Executing \fBbundle config get <name>\fR will print the value of that configuration setting, and where it was set\.

View file

@ -19,7 +19,7 @@ Bundler loads configuration settings in this order:
3. Global config (`~/.bundle/config`) 3. Global config (`~/.bundle/config`)
4. Bundler default config 4. Bundler default config
Executing `bundle config list` with will print a list of all bundler Executing `bundle config list` will print a list of all bundler
configuration for the current bundle, and where that configuration configuration for the current bundle, and where that configuration
was set. was set.

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-CONSOLE" "1" "December 2022" "" "" .TH "BUNDLE\-CONSOLE" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-console\fR \- Deprecated way to open an IRB session with the bundle pre\-loaded \fBbundle\-console\fR \- Deprecated way to open an IRB session with the bundle pre\-loaded

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-DOCTOR" "1" "December 2022" "" "" .TH "BUNDLE\-DOCTOR" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-doctor\fR \- Checks the bundle for common problems \fBbundle\-doctor\fR \- Checks the bundle for common problems

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-EXEC" "1" "December 2022" "" "" .TH "BUNDLE\-EXEC" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-exec\fR \- Execute a command in the context of the bundle \fBbundle\-exec\fR \- Execute a command in the context of the bundle
@ -74,13 +74,13 @@ Finally, \fBbundle exec\fR also implicitly modifies \fBGemfile\.lock\fR if the l
By default, when attempting to \fBbundle exec\fR to a file with a ruby shebang, Bundler will \fBKernel\.load\fR that file instead of using \fBKernel\.exec\fR\. For the vast majority of cases, this is a performance improvement\. In a rare few cases, this could cause some subtle side\-effects (such as dependence on the exact contents of \fB$0\fR or \fB__FILE__\fR) and the optimization can be disabled by enabling the \fBdisable_exec_load\fR setting\. By default, when attempting to \fBbundle exec\fR to a file with a ruby shebang, Bundler will \fBKernel\.load\fR that file instead of using \fBKernel\.exec\fR\. For the vast majority of cases, this is a performance improvement\. In a rare few cases, this could cause some subtle side\-effects (such as dependence on the exact contents of \fB$0\fR or \fB__FILE__\fR) and the optimization can be disabled by enabling the \fBdisable_exec_load\fR setting\.
. .
.SS "Shelling out" .SS "Shelling out"
Any Ruby code that opens a subshell (like \fBsystem\fR, backticks, or \fB%x{}\fR) will automatically use the current Bundler environment\. If you need to shell out to a Ruby command that is not part of your current bundle, use the \fBwith_clean_env\fR method with a block\. Any subshells created inside the block will be given the environment present before Bundler was activated\. For example, Homebrew commands run Ruby, but don\'t work inside a bundle: Any Ruby code that opens a subshell (like \fBsystem\fR, backticks, or \fB%x{}\fR) will automatically use the current Bundler environment\. If you need to shell out to a Ruby command that is not part of your current bundle, use the \fBwith_unbundled_env\fR method with a block\. Any subshells created inside the block will be given the environment present before Bundler was activated\. For example, Homebrew commands run Ruby, but don\'t work inside a bundle:
. .
.IP "" 4 .IP "" 4
. .
.nf .nf
Bundler\.with_clean_env do Bundler\.with_unbundled_env do
`brew install wget` `brew install wget`
end end
. .
@ -89,13 +89,13 @@ end
.IP "" 0 .IP "" 0
. .
.P .P
Using \fBwith_clean_env\fR is also necessary if you are shelling out to a different bundle\. Any Bundler commands run in a subshell will inherit the current Gemfile, so commands that need to run in the context of a different bundle also need to use \fBwith_clean_env\fR\. Using \fBwith_unbundled_env\fR is also necessary if you are shelling out to a different bundle\. Any Bundler commands run in a subshell will inherit the current Gemfile, so commands that need to run in the context of a different bundle also need to use \fBwith_unbundled_env\fR\.
. .
.IP "" 4 .IP "" 4
. .
.nf .nf
Bundler\.with_clean_env do Bundler\.with_unbundled_env do
Dir\.chdir "/other/bundler/project" do Dir\.chdir "/other/bundler/project" do
`bundle exec \./script` `bundle exec \./script`
end end

View file

@ -84,20 +84,20 @@ the `disable_exec_load` setting.
Any Ruby code that opens a subshell (like `system`, backticks, or `%x{}`) will Any Ruby code that opens a subshell (like `system`, backticks, or `%x{}`) will
automatically use the current Bundler environment. If you need to shell out to automatically use the current Bundler environment. If you need to shell out to
a Ruby command that is not part of your current bundle, use the a Ruby command that is not part of your current bundle, use the
`with_clean_env` method with a block. Any subshells created inside the block `with_unbundled_env` method with a block. Any subshells created inside the block
will be given the environment present before Bundler was activated. For will be given the environment present before Bundler was activated. For
example, Homebrew commands run Ruby, but don't work inside a bundle: example, Homebrew commands run Ruby, but don't work inside a bundle:
Bundler.with_clean_env do Bundler.with_unbundled_env do
`brew install wget` `brew install wget`
end end
Using `with_clean_env` is also necessary if you are shelling out to a different Using `with_unbundled_env` is also necessary if you are shelling out to a different
bundle. Any Bundler commands run in a subshell will inherit the current bundle. Any Bundler commands run in a subshell will inherit the current
Gemfile, so commands that need to run in the context of a different bundle also Gemfile, so commands that need to run in the context of a different bundle also
need to use `with_clean_env`. need to use `with_unbundled_env`.
Bundler.with_clean_env do Bundler.with_unbundled_env do
Dir.chdir "/other/bundler/project" do Dir.chdir "/other/bundler/project" do
`bundle exec ./script` `bundle exec ./script`
end end

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-GEM" "1" "December 2022" "" "" .TH "BUNDLE\-GEM" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem \fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-HELP" "1" "December 2022" "" "" .TH "BUNDLE\-HELP" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-help\fR \- Displays detailed help for each subcommand \fBbundle\-help\fR \- Displays detailed help for each subcommand

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-INFO" "1" "December 2022" "" "" .TH "BUNDLE\-INFO" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-info\fR \- Show information for the given gem in your bundle \fBbundle\-info\fR \- Show information for the given gem in your bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-INIT" "1" "December 2022" "" "" .TH "BUNDLE\-INIT" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory \fBbundle\-init\fR \- Generates a Gemfile into the current working directory

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-INJECT" "1" "December 2022" "" "" .TH "BUNDLE\-INJECT" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile \fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-INSTALL" "1" "December 2022" "" "" .TH "BUNDLE\-INSTALL" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-LIST" "1" "December 2022" "" "" .TH "BUNDLE\-LIST" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-list\fR \- List all the gems in the bundle \fBbundle\-list\fR \- List all the gems in the bundle

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-LOCK" "1" "December 2022" "" "" .TH "BUNDLE\-LOCK" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing \fBbundle\-lock\fR \- Creates / Updates a lockfile without installing

View file

@ -1,13 +1,13 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-OPEN" "1" "December 2022" "" "" .TH "BUNDLE\-OPEN" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle \fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
. .
.SH "SYNOPSIS" .SH "SYNOPSIS"
\fBbundle open\fR [GEM] \fBbundle open\fR [GEM] [\-\-path=PATH]
. .
.SH "DESCRIPTION" .SH "DESCRIPTION"
Opens the source directory of the provided GEM in your editor\. Opens the source directory of the provided GEM in your editor\.
@ -30,3 +30,23 @@ bundle open \'rack\'
. .
.P .P
Will open the source directory for the \'rack\' gem in your bundle\. Will open the source directory for the \'rack\' gem in your bundle\.
.
.IP "" 4
.
.nf
bundle open \'rack\' \-\-path \'README\.md\'
.
.fi
.
.IP "" 0
.
.P
Will open the README\.md file of the \'rack\' gem source in your bundle\.
.
.SH "OPTIONS"
.
.TP
\fB\-\-path\fR
Specify GEM source relative path to open\.

View file

@ -3,7 +3,7 @@ bundle-open(1) -- Opens the source directory for a gem in your bundle
## SYNOPSIS ## SYNOPSIS
`bundle open` [GEM] `bundle open` [GEM] [--path=PATH]
## DESCRIPTION ## DESCRIPTION
@ -17,3 +17,11 @@ Example:
bundle open 'rack' bundle open 'rack'
Will open the source directory for the 'rack' gem in your bundle. Will open the source directory for the 'rack' gem in your bundle.
bundle open 'rack' --path 'README.md'
Will open the README.md file of the 'rack' gem source in your bundle.
## OPTIONS
* `--path`:
Specify GEM source relative path to open.

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-OUTDATED" "1" "December 2022" "" "" .TH "BUNDLE\-OUTDATED" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-outdated\fR \- List installed gems with newer versions available \fBbundle\-outdated\fR \- List installed gems with newer versions available

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-PLATFORM" "1" "December 2022" "" "" .TH "BUNDLE\-PLATFORM" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-platform\fR \- Displays platform compatibility information \fBbundle\-platform\fR \- Displays platform compatibility information

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-PLUGIN" "1" "December 2022" "" "" .TH "BUNDLE\-PLUGIN" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-plugin\fR \- Manage Bundler plugins \fBbundle\-plugin\fR \- Manage Bundler plugins

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-PRISTINE" "1" "December 2022" "" "" .TH "BUNDLE\-PRISTINE" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition \fBbundle\-pristine\fR \- Restores installed gems to their pristine condition

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-REMOVE" "1" "December 2022" "" "" .TH "BUNDLE\-REMOVE" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-remove\fR \- Removes gems from the Gemfile \fBbundle\-remove\fR \- Removes gems from the Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-SHOW" "1" "December 2022" "" "" .TH "BUNDLE\-SHOW" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem \fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-UPDATE" "1" "December 2022" "" "" .TH "BUNDLE\-UPDATE" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-update\fR \- Update your gems to the latest available versions \fBbundle\-update\fR \- Update your gems to the latest available versions

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-VERSION" "1" "December 2022" "" "" .TH "BUNDLE\-VERSION" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-version\fR \- Prints Bundler version information \fBbundle\-version\fR \- Prints Bundler version information

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE\-VIZ" "1" "December 2022" "" "" .TH "BUNDLE\-VIZ" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile \fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNDLE" "1" "December 2022" "" "" .TH "BUNDLE" "1" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\fR \- Ruby Dependency Management \fBbundle\fR \- Ruby Dependency Management

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "GEMFILE" "5" "December 2022" "" "" .TH "GEMFILE" "5" "January 2023" "" ""
. .
.SH "NAME" .SH "NAME"
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs

View file

@ -9,26 +9,21 @@ module Bundler
class Resolver class Resolver
require_relative "vendored_pub_grub" require_relative "vendored_pub_grub"
require_relative "resolver/base" require_relative "resolver/base"
require_relative "resolver/package"
require_relative "resolver/candidate" require_relative "resolver/candidate"
require_relative "resolver/incompatibility" require_relative "resolver/incompatibility"
require_relative "resolver/root" require_relative "resolver/root"
include GemHelpers include GemHelpers
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements) def initialize(base, gem_version_promoter)
@source_requirements = source_requirements @source_requirements = base.source_requirements
@base = Resolver::Base.new(base, additional_base_requirements) @base = base
@gem_version_promoter = gem_version_promoter @gem_version_promoter = gem_version_promoter
end end
def start(requirements, packages, exclude_specs: []) def start
exclude_specs.each do |spec| @requirements = @base.requirements
remove_from_candidates(spec) @packages = @base.packages
end
@requirements = requirements
@packages = packages
root, logger = setup_solver root, logger = setup_solver
@ -78,33 +73,26 @@ module Bundler
rescue PubGrub::SolveFailure => e rescue PubGrub::SolveFailure => e
incompatibility = e.incompatibility incompatibility = e.incompatibility
names_to_unlock = [] names_to_unlock, names_to_allow_prereleases_for, extended_explanation = find_names_to_relax(incompatibility)
extended_explanation = nil
while incompatibility.conflict? names_to_relax = names_to_unlock + names_to_allow_prereleases_for
cause = incompatibility.cause
incompatibility = cause.incompatibility
incompatibility.terms.each do |term| if names_to_relax.any?
name = term.package.name if names_to_unlock.any?
names_to_unlock << name if base_requirements[name] Bundler.ui.debug "Found conflicts with locked dependencies. Will retry with #{names_to_unlock.join(", ")} unlocked...", true
no_versions_incompat = [cause.incompatibility, cause.satisfier].find {|incompat| incompat.cause.is_a?(PubGrub::Incompatibility::NoVersions) } @base.unlock_names(names_to_unlock)
next unless no_versions_incompat
extended_explanation = no_versions_incompat.extended_explanation
end end
end
names_to_unlock.uniq! if names_to_allow_prereleases_for.any?
Bundler.ui.debug "Found conflicts with dependencies with prereleases. Will retrying considering prereleases for #{names_to_allow_prereleases_for.join(", ")}...", true
if names_to_unlock.any? @base.include_prereleases(names_to_allow_prereleases_for)
Bundler.ui.debug "Found conflicts with locked dependencies. Retrying with #{names_to_unlock.join(", ")} unlocked...", true end
@base.unlock_names(names_to_unlock)
root, logger = setup_solver root, logger = setup_solver
Bundler.ui.debug "Retrying resolution...", true
retry retry
end end
@ -118,6 +106,35 @@ module Bundler
raise SolveFailure.new(explanation) raise SolveFailure.new(explanation)
end end
def find_names_to_relax(incompatibility)
names_to_unlock = []
names_to_allow_prereleases_for = []
extended_explanation = nil
while incompatibility.conflict?
cause = incompatibility.cause
incompatibility = cause.incompatibility
incompatibility.terms.each do |term|
package = term.package
name = package.name
if base_requirements[name]
names_to_unlock << name
elsif package.ignores_prereleases?
names_to_allow_prereleases_for << name
end
no_versions_incompat = [cause.incompatibility, cause.satisfier].find {|incompat| incompat.cause.is_a?(PubGrub::Incompatibility::NoVersions) }
next unless no_versions_incompat
extended_explanation = no_versions_incompat.extended_explanation
end
end
[names_to_unlock.uniq, names_to_allow_prereleases_for.uniq, extended_explanation]
end
def parse_dependency(package, dependency) def parse_dependency(package, dependency)
range = if repository_for(package).is_a?(Source::Gemspec) range = if repository_for(package).is_a?(Source::Gemspec)
PubGrub::VersionRange.any PubGrub::VersionRange.any
@ -215,7 +232,7 @@ module Bundler
def all_versions_for(package) def all_versions_for(package)
name = package.name name = package.name
results = (@base[name] + @all_specs[name]).uniq(&:full_name) results = (@base[name] + filter_prereleases(@all_specs[name], package)).uniq {|spec| [spec.version.hash, spec.platform] }
locked_requirement = base_requirements[name] locked_requirement = base_requirements[name]
results = filter_matching_specs(results, locked_requirement) if locked_requirement results = filter_matching_specs(results, locked_requirement) if locked_requirement
@ -284,6 +301,12 @@ module Bundler
end end
end end
def filter_prereleases(specs, package)
return specs unless package.ignores_prereleases?
specs.reject {|s| s.version.prerelease? }
end
def requirement_satisfied_by?(requirement, spec) def requirement_satisfied_by?(requirement, spec)
requirement.satisfied_by?(spec.version) || spec.source.is_a?(Source::Gemspec) requirement.satisfied_by?(spec.version) || spec.source.is_a?(Source::Gemspec)
end end
@ -304,25 +327,20 @@ module Bundler
@base.base_requirements @base.base_requirements
end end
def remove_from_candidates(spec)
@base.delete(spec)
end
def prepare_dependencies(requirements, packages) def prepare_dependencies(requirements, packages)
to_dependency_hash(requirements, packages).map do |dep_package, dep_constraint| to_dependency_hash(requirements, packages).map do |dep_package, dep_constraint|
name = dep_package.name name = dep_package.name
# If a dependency is scoped to a platform different from the current
# one, we ignore it. However, it may reappear during resolution as a
# transitive dependency of another package, so we need to reset the
# package so the proper versions are considered if reintroduced later.
if dep_package.platforms.empty?
@packages.delete(name)
next
end
next [dep_package, dep_constraint] if name == "bundler" next [dep_package, dep_constraint] if name == "bundler"
next [dep_package, dep_constraint] unless versions_for(dep_package, dep_constraint.range).empty?
versions = versions_for(dep_package, dep_constraint.range)
if versions.empty? && dep_package.ignores_prereleases?
@sorted_versions.delete(dep_package)
dep_package.consider_prereleases!
versions = versions_for(dep_package, dep_constraint.range)
end
next [dep_package, dep_constraint] unless versions.empty?
next unless dep_package.current_platform? next unless dep_package.current_platform?
raise_not_found!(dep_package) raise_not_found!(dep_package)
@ -337,7 +355,8 @@ module Bundler
def requirement_to_range(requirement) def requirement_to_range(requirement)
ranges = requirement.requirements.map do |(op, version)| ranges = requirement.requirements.map do |(op, version)|
ver = Resolver::Candidate.new(version) ver = Resolver::Candidate.new(version).generic!
platform_ver = Resolver::Candidate.new(version).platform_specific!
case op case op
when "~>" when "~>"
@ -345,17 +364,17 @@ module Bundler
bump = Resolver::Candidate.new(version.bump.to_s + ".A") bump = Resolver::Candidate.new(version.bump.to_s + ".A")
PubGrub::VersionRange.new(:name => name, :min => ver, :max => bump, :include_min => true) PubGrub::VersionRange.new(:name => name, :min => ver, :max => bump, :include_min => true)
when ">" when ">"
PubGrub::VersionRange.new(:min => ver) PubGrub::VersionRange.new(:min => platform_ver)
when ">=" when ">="
PubGrub::VersionRange.new(:min => ver, :include_min => true) PubGrub::VersionRange.new(:min => ver, :include_min => true)
when "<" when "<"
PubGrub::VersionRange.new(:max => ver) PubGrub::VersionRange.new(:max => ver)
when "<=" when "<="
PubGrub::VersionRange.new(:max => ver, :include_max => true) PubGrub::VersionRange.new(:max => platform_ver, :include_max => true)
when "=" when "="
PubGrub::VersionRange.new(:min => ver, :max => ver, :include_min => true, :include_max => true) PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true)
when "!=" when "!="
PubGrub::VersionRange.new(:min => ver, :max => ver, :include_min => true, :include_max => true).invert PubGrub::VersionRange.new(:min => ver, :max => platform_ver, :include_min => true, :include_max => true).invert
else else
raise "bad version specifier: #{op}" raise "bad version specifier: #{op}"
end end

View file

@ -1,19 +1,47 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative "package"
module Bundler module Bundler
class Resolver class Resolver
class Base class Base
def initialize(base, additional_base_requirements) attr_reader :packages, :requirements, :source_requirements
def initialize(source_requirements, dependencies, base, platforms, options)
@source_requirements = source_requirements
@base = base @base = base
@additional_base_requirements = additional_base_requirements
@packages = Hash.new do |hash, name|
hash[name] = Package.new(name, platforms, **options)
end
@requirements = dependencies.map do |dep|
dep_platforms = dep.gem_platforms(platforms)
# Dependencies scoped to external platforms are ignored
next if dep_platforms.empty?
name = dep.name
@packages[name] = Package.new(name, dep_platforms, **options.merge(:dependency => dep))
dep
end.compact
end end
def [](name) def [](name)
@base[name] @base[name]
end end
def delete(spec) def delete(specs)
@base.delete(spec) specs.each do |spec|
@base.delete(spec)
end
end
def get_package(name)
@packages[name]
end end
def base_requirements def base_requirements
@ -24,10 +52,14 @@ module Bundler
names.each do |name| names.each do |name|
@base.delete_by_name(name) @base.delete_by_name(name)
@additional_base_requirements.reject! {|dep| dep.name == name } @base_requirements.delete(name)
end end
end
@base_requirements = nil def include_prereleases(names)
names.each do |name|
get_package(name).consider_prereleases!
end
end end
private private
@ -38,7 +70,6 @@ module Bundler
req = Gem::Requirement.new(ls.version) req = Gem::Requirement.new(ls.version)
base_requirements[ls.name] = req base_requirements[ls.name] = req
end end
@additional_base_requirements.each {|d| base_requirements[d.name] = d.requirement }
base_requirements base_requirements
end end
end end

View file

@ -26,9 +26,8 @@ module Bundler
def initialize(version, specs: []) def initialize(version, specs: [])
@spec_group = Resolver::SpecGroup.new(specs) @spec_group = Resolver::SpecGroup.new(specs)
@platforms = specs.map(&:platform).sort_by(&:to_s).uniq
@version = Gem::Version.new(version) @version = Gem::Version.new(version)
@ruby_only = @platforms == [Gem::Platform::RUBY] @ruby_only = specs.map(&:platform).uniq == [Gem::Platform::RUBY]
end end
def dependencies def dependencies
@ -41,6 +40,18 @@ module Bundler
@spec_group.to_specs(package.force_ruby_platform?) @spec_group.to_specs(package.force_ruby_platform?)
end end
def generic!
@ruby_only = true
self
end
def platform_specific!
@ruby_only = false
self
end
def prerelease? def prerelease?
@version.prerelease? @version.prerelease?
end end
@ -53,27 +64,20 @@ module Bundler
[@version, @ruby_only ? -1 : 1] [@version, @ruby_only ? -1 : 1]
end end
def canonical?
!@spec_group.empty?
end
def <=>(other) def <=>(other)
return unless other.is_a?(self.class) return unless other.is_a?(self.class)
return @version <=> other.version unless canonical? && other.canonical?
sort_obj <=> other.sort_obj sort_obj <=> other.sort_obj
end end
def ==(other) def ==(other)
return unless other.is_a?(self.class) return unless other.is_a?(self.class)
return @version == other.version unless canonical? && other.canonical?
sort_obj == other.sort_obj sort_obj == other.sort_obj
end end
def eql?(other) def eql?(other)
return unless other.is_a?(self.class) return unless other.is_a?(self.class)
return @version.eql?(other.version) unless canonical? || other.canonical?
sort_obj.eql?(other.sort_obj) sort_obj.eql?(other.sort_obj)
end end
@ -83,9 +87,7 @@ module Bundler
end end
def to_s def to_s
return @version.to_s if @platforms.empty? || @ruby_only @version.to_s
"#{@version} (#{@platforms.join(", ")})"
end end
end end
end end

View file

@ -15,12 +15,13 @@ module Bundler
class Package class Package
attr_reader :name, :platforms, :dependency, :locked_version attr_reader :name, :platforms, :dependency, :locked_version
def initialize(name, platforms, locked_specs, unlock, dependency: nil) def initialize(name, platforms, locked_specs:, unlock:, prerelease: false, dependency: nil)
@name = name @name = name
@platforms = platforms @platforms = platforms
@locked_version = locked_specs[name].first&.version @locked_version = locked_specs[name].first&.version
@unlock = unlock @unlock = unlock
@dependency = dependency || Dependency.new(name, @locked_version) @dependency = dependency || Dependency.new(name, @locked_version)
@prerelease = @dependency.prerelease? || @locked_version&.prerelease? || prerelease ? :consider_first : :ignore
end end
def to_s def to_s
@ -47,8 +48,16 @@ module Bundler
@unlock.empty? || @unlock.include?(name) @unlock.empty? || @unlock.include?(name)
end end
def ignores_prereleases?
@prerelease == :ignore
end
def prerelease_specified? def prerelease_specified?
@dependency.prerelease? @prerelease == :consider_first
end
def consider_prereleases!
@prerelease = :consider_last
end end
def force_ruby_platform? def force_ruby_platform?

View file

@ -284,7 +284,7 @@ module Bundler
Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file Bundler::SharedHelpers.set_env "BUNDLE_BIN_PATH", exe_file
Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", find_gemfile.to_s
Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION Bundler::SharedHelpers.set_env "BUNDLER_VERSION", Bundler::VERSION
Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__) Bundler::SharedHelpers.set_env "BUNDLER_SETUP", File.expand_path("setup", __dir__) unless RUBY_VERSION < "2.7"
end end
def set_path def set_path

View file

@ -292,7 +292,7 @@ module Bundler
end end
def dependency_api_available? def dependency_api_available?
api_fetchers.any? @allow_remote && api_fetchers.any?
end end
protected protected

View file

@ -1,5 +1,5 @@
# This Cargo.toml is here to let externals tools (IDEs, etc.) know that this is # This Cargo.toml is here to let externals tools (IDEs, etc.) know that this is
# a Rust project. Your extensions depedencies should be added to the Cargo.toml # a Rust project. Your extensions dependencies should be added to the Cargo.toml
# in the ext/ directory. # in the ext/ directory.
[workspace] [workspace]

View file

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2018 John Hawthorn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -20,6 +20,10 @@ module Bundler::PubGrub
range.eql?(other.range) range.eql?(other.range)
end end
def ==(other)
package == other.package && range == other.range
end
class << self class << self
def exact(package, version) def exact(package, version)
range = VersionRange.new(min: version, max: version, include_min: true, include_max: true) range = VersionRange.new(min: version, max: version, include_min: true, include_max: true)

View file

@ -397,7 +397,7 @@ module Bundler::PubGrub
def constraints def constraints
return ["any"] if any? return ["any"] if any?
return ["= #{min}"] if min == max return ["= #{min}"] if min.to_s == max.to_s
c = [] c = []
c << "#{include_min ? ">=" : ">"} #{min}" if min c << "#{include_min ? ">=" : ">"} #{min}" if min

View file

@ -148,7 +148,7 @@ module Bundler::PubGrub
while !ranges.empty? while !ranges.empty?
ne = [] ne = []
range = ranges.shift range = ranges.shift
while !ranges.empty? && ranges[0].min == range.max while !ranges.empty? && ranges[0].min.to_s == range.max.to_s
ne << range.max ne << range.max
range = range.span(ranges.shift) range = range.span(ranges.shift)
end end

View file

@ -1,7 +1,7 @@
# frozen_string_literal: false # frozen_string_literal: false
module Bundler module Bundler
VERSION = "2.4.1".freeze VERSION = "2.4.5".freeze
def self.bundler_major_version def self.bundler_major_version
@bundler_major_version ||= VERSION.split(".").first.to_i @bundler_major_version ||= VERSION.split(".").first.to_i

View file

@ -8,7 +8,7 @@
require "rbconfig" require "rbconfig"
module Gem module Gem
VERSION = "3.4.1".freeze VERSION = "3.4.5".freeze
end end
# Must be first since it unloads the prelude from 1.9.2 # Must be first since it unloads the prelude from 1.9.2
@ -119,10 +119,6 @@ module Gem
# to avoid deprecation warnings in Ruby 2.7. # to avoid deprecation warnings in Ruby 2.7.
UNTAINT = RUBY_VERSION < "2.7" ? :untaint.to_sym : proc {} UNTAINT = RUBY_VERSION < "2.7" ? :untaint.to_sym : proc {}
# When https://bugs.ruby-lang.org/issues/17259 is available, there is no need to override Kernel#warn
KERNEL_WARN_IGNORES_INTERNAL_ENTRIES = RUBY_ENGINE == "truffleruby" ||
(RUBY_ENGINE == "ruby" && RUBY_VERSION >= "3.0")
## ##
# An Array of Regexps that match windows Ruby platforms. # An Array of Regexps that match windows Ruby platforms.
@ -1349,7 +1345,16 @@ end
Gem::Specification.load_defaults Gem::Specification.load_defaults
require_relative "rubygems/core_ext/kernel_gem" require_relative "rubygems/core_ext/kernel_gem"
require_relative "rubygems/core_ext/kernel_require"
require_relative "rubygems/core_ext/kernel_warn" path = File.join(__dir__, "rubygems/core_ext/kernel_require.rb")
# When https://bugs.ruby-lang.org/issues/17259 is available, there is no need to override Kernel#warn
if RUBY_ENGINE == "truffleruby" ||
(RUBY_ENGINE == "ruby" && RUBY_VERSION >= "3.0")
file = "<internal:#{path}>"
else
require_relative "rubygems/core_ext/kernel_warn"
file = path
end
eval File.read(path), nil, file
require ENV["BUNDLER_SETUP"] if ENV["BUNDLER_SETUP"] && !defined?(Bundler) require ENV["BUNDLER_SETUP"] if ENV["BUNDLER_SETUP"] && !defined?(Bundler)

View file

@ -630,7 +630,11 @@ RubyGems is a package manager for Ruby.
Usage: Usage:
gem -h/--help gem -h/--help
gem -v/--version gem -v/--version
gem command [arguments...] [options...] gem [global options...] command [arguments...] [options...]
Global options:
-C PATH run as if gem was started in <PATH>
instead of the current working directory
Examples: Examples:
gem install rake gem install rake

View file

@ -175,14 +175,20 @@ class Gem::CommandManager
when "-v", "--version" then when "-v", "--version" then
say Gem::VERSION say Gem::VERSION
terminate_interaction 0 terminate_interaction 0
when "-C" then
args.shift
start_point = args.shift
if Dir.exist?(start_point)
Dir.chdir(start_point) { invoke_command(args, build_args) }
else
alert_error clean_text("#{start_point} isn't a directory.")
terminate_interaction 1
end
when /^-/ then when /^-/ then
alert_error clean_text("Invalid option: #{args.first}. See 'gem --help'.") alert_error clean_text("Invalid option: #{args.first}. See 'gem --help'.")
terminate_interaction 1 terminate_interaction 1
else else
cmd_name = args.shift.downcase invoke_command(args, build_args)
cmd = find_command cmd_name
cmd.deprecation_warning if cmd.deprecated?
cmd.invoke_with_build_args args, build_args
end end
end end
@ -237,4 +243,11 @@ class Gem::CommandManager
ui.backtrace e ui.backtrace e
end end
end end
def invoke_command(args, build_args)
cmd_name = args.shift.downcase
cmd = find_command cmd_name
cmd.deprecation_warning if cmd.deprecated?
cmd.invoke_with_build_args args, build_args
end
end end

View file

@ -26,6 +26,9 @@ class Gem::Commands::BuildCommand < Gem::Command
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 options[:build_path] = value
end end
deprecate_option "-C",
version: "4.0",
extra_msg: "-C is a global flag now. Use `gem -C PATH build GEMSPEC_FILE [options]` instead"
end end
def arguments # :nodoc: def arguments # :nodoc:

View file

@ -15,7 +15,7 @@ The owner command lets you add and remove owners of a gem on a push
server (the default is https://rubygems.org). Multiple owners can be server (the default is https://rubygems.org). Multiple owners can be
added or removed at the same time, if the flag is given multiple times. added or removed at the same time, if the flag is given multiple times.
The supported user identifiers are dependant on the push server. The supported user identifiers are dependent on the push server.
For rubygems.org, both e-mail and handle are supported, even though the For rubygems.org, both e-mail and handle are supported, even though the
user identifier field is called "email". user identifier field is called "email".

View file

@ -1,9 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
##
# RubyGems adds the #gem method to allow activation of specific gem versions
# and overrides the #require method on Kernel to make gems appear as if they
# live on the <code>$LOAD_PATH</code>. See the documentation of these methods
# for further detail.
module Kernel module Kernel

View file

@ -13,12 +13,12 @@ module Kernel
# Make sure we have a reference to Ruby's original Kernel#require # Make sure we have a reference to Ruby's original Kernel#require
unless defined?(gem_original_require) unless defined?(gem_original_require)
# :stopdoc:
alias gem_original_require require alias gem_original_require require
private :gem_original_require private :gem_original_require
# :startdoc:
end end
file = Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES ? "<internal:#{__FILE__}>" : __FILE__
module_eval <<'RUBY', file, __LINE__ + 1 # rubocop:disable Style/EvalWithLocation
## ##
# When RubyGems is required, Kernel#require is replaced with our own which # When RubyGems is required, Kernel#require is replaced with our own which
# is capable of loading gems on demand. # is capable of loading gems on demand.
@ -33,7 +33,7 @@ module Kernel
# The normal <tt>require</tt> functionality of returning false if # The normal <tt>require</tt> functionality of returning false if
# that file has already been loaded is preserved. # that file has already been loaded is preserved.
def require(path) def require(path) # :doc:
if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?) if RUBYGEMS_ACTIVATION_MONITOR.respond_to?(:mon_owned?)
monitor_owned = RUBYGEMS_ACTIVATION_MONITOR.mon_owned? monitor_owned = RUBYGEMS_ACTIVATION_MONITOR.mon_owned?
end end
@ -147,17 +147,17 @@ module Kernel
RUBYGEMS_ACTIVATION_MONITOR.exit RUBYGEMS_ACTIVATION_MONITOR.exit
return gem_original_require(path) return gem_original_require(path)
rescue LoadError => load_error rescue LoadError => load_error
RUBYGEMS_ACTIVATION_MONITOR.enter if load_error.path == path
RUBYGEMS_ACTIVATION_MONITOR.enter
begin begin
if load_error.path == path and Gem.try_activate(path) require_again = Gem.try_activate(path)
require_again = true ensure
RUBYGEMS_ACTIVATION_MONITOR.exit
end end
ensure
RUBYGEMS_ACTIVATION_MONITOR.exit
end
return gem_original_require(path) if require_again return gem_original_require(path) if require_again
end
raise load_error raise load_error
ensure ensure
@ -168,7 +168,6 @@ module Kernel
end end
end end
end end
RUBY
private :require private :require

View file

@ -1,53 +1,50 @@
# frozen_string_literal: true # frozen_string_literal: true
if !Gem::KERNEL_WARN_IGNORES_INTERNAL_ENTRIES module Kernel
rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path.
module Kernel original_warn = instance_method(:warn)
rubygems_path = "#{__dir__}/" # Frames to be skipped start with this path.
original_warn = instance_method(:warn) remove_method :warn
class << self
remove_method :warn remove_method :warn
end
class << self module_function define_method(:warn) {|*messages, **kw|
remove_method :warn unless uplevel = kw[:uplevel]
if Gem.java_platform? && RUBY_VERSION < "3.1"
return original_warn.bind(self).call(*messages)
else
return original_warn.bind(self).call(*messages, **kw)
end
end end
module_function define_method(:warn) {|*messages, **kw| # Ensure `uplevel` fits a `long`
unless uplevel = kw[:uplevel] uplevel, = [uplevel].pack("l!").unpack("l!")
if Gem.java_platform? && RUBY_VERSION < "3.1"
return original_warn.bind(self).call(*messages) if uplevel >= 0
else start = 0
return original_warn.bind(self).call(*messages, **kw) while uplevel >= 0
loc, = caller_locations(start, 1)
unless loc
# No more backtrace
start += uplevel
break
end end
end
# Ensure `uplevel` fits a `long` start += 1
uplevel, = [uplevel].pack("l!").unpack("l!")
if uplevel >= 0 if path = loc.path
start = 0 unless path.start_with?(rubygems_path) || path.start_with?("<internal:")
while uplevel >= 0 # Non-rubygems frames
loc, = caller_locations(start, 1) uplevel -= 1
unless loc
# No more backtrace
start += uplevel
break
end
start += 1
if path = loc.path
unless path.start_with?(rubygems_path) || path.start_with?("<internal:")
# Non-rubygems frames
uplevel -= 1
end
end end
end end
kw[:uplevel] = start
end end
kw[:uplevel] = start
end
original_warn.bind(self).call(*messages, **kw) original_warn.bind(self).call(*messages, **kw)
} }
end
end end

View file

@ -203,7 +203,7 @@ class Gem::Ext::CargoBuilder < Gem::Ext::Builder
!!Gem::WIN_PATTERNS.find {|r| target_platform =~ r } !!Gem::WIN_PATTERNS.find {|r| target_platform =~ r }
end end
# Interpolate substition vars in the arg (i.e. $(DEFFILE)) # Interpolate substitution vars in the arg (i.e. $(DEFFILE))
def maybe_resolve_ldflag_variable(input_arg, dest_dir) def maybe_resolve_ldflag_variable(input_arg, dest_dir)
var_matches = input_arg.match(/\$\((\w+)\)/) var_matches = input_arg.match(/\$\((\w+)\)/)

View file

@ -158,7 +158,7 @@ class Gem::Platform
# Of note, this method is not commutative. Indeed the OS 'linux' has a # Of note, this method is not commutative. Indeed the OS 'linux' has a
# special case: the version is the libc name, yet while "no version" stands # special case: the version is the libc name, yet while "no version" stands
# as a wildcard for a binary gem platform (as for other OSes), for the # as a wildcard for a binary gem platform (as for other OSes), for the
# runtime platform "no version" stands for 'gnu'. To be able to disinguish # runtime platform "no version" stands for 'gnu'. To be able to distinguish
# these, the method receiver is the gem platform, while the argument is # these, the method receiver is the gem platform, while the argument is
# the runtime platform. # the runtime platform.
# #

View file

@ -29,7 +29,7 @@ RSpec.describe Bundler::Dsl do
subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5") subject.gem("sparks", :github => "https://github.com/indirect/sparks/pull/5")
github_uri = "https://github.com/indirect/sparks.git" github_uri = "https://github.com/indirect/sparks.git"
expect(subject.dependencies.first.source.uri).to eq(github_uri) expect(subject.dependencies.first.source.uri).to eq(github_uri)
expect(subject.dependencies.first.source.branch).to eq("refs/pull/5/head") expect(subject.dependencies.first.source.ref).to eq("refs/pull/5/head")
end end
it "rejects :github PR URI with a branch, ref or tag" do it "rejects :github PR URI with a branch, ref or tag" do

View file

@ -16,6 +16,10 @@ RSpec.describe Bundler::GemVersionPromoter do
Bundler::SpecSet.new(build_spec(name, v)) Bundler::SpecSet.new(build_spec(name, v))
end end
def build_package(name, platforms, locked_specs, unlock)
Bundler::Resolver::Package.new(name, platforms, :locked_specs => locked_specs, :unlock => unlock)
end
# Rightmost (highest array index) in result is most preferred. # Rightmost (highest array index) in result is most preferred.
# Leftmost (lowest array index) in result is least preferred. # Leftmost (lowest array index) in result is least preferred.
# `build_candidates` has all versions of gem in index. # `build_candidates` has all versions of gem in index.
@ -35,7 +39,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when keeping build_spec, keep current, next release" do it "when keeping build_spec, keep current, next release" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), build_package("foo", [], build_spec_set("foo", "1.7.8"), []),
build_candidates(%w[1.7.8 1.7.9 1.8.0]) build_candidates(%w[1.7.8 1.7.9 1.8.0])
) )
expect(versions(res)).to eq %w[1.7.8 1.7.9] expect(versions(res)).to eq %w[1.7.8 1.7.9]
@ -43,7 +47,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking prefer next release first" do it "when unlocking prefer next release first" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), build_package("foo", [], build_spec_set("foo", "1.7.8"), []),
build_candidates(%w[1.7.8 1.7.9 1.8.0]) build_candidates(%w[1.7.8 1.7.9 1.8.0])
) )
expect(versions(res)).to eq %w[1.7.8 1.7.9] expect(versions(res)).to eq %w[1.7.8 1.7.9]
@ -51,7 +55,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking keep current when already at latest release" do it "when unlocking keep current when already at latest release" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.9"), []), build_package("foo", [], build_spec_set("foo", "1.7.9"), []),
build_candidates(%w[1.7.9 1.8.0 2.0.0]) build_candidates(%w[1.7.9 1.8.0 2.0.0])
) )
expect(versions(res)).to eq %w[1.7.9] expect(versions(res)).to eq %w[1.7.9]
@ -68,7 +72,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking favor next releases, remove minor and major increases" do it "when unlocking favor next releases, remove minor and major increases" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "0.2.0"), []), build_package("foo", [], build_spec_set("foo", "0.2.0"), []),
build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1])
) )
expect(versions(res)).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0] expect(versions(res)).to eq %w[0.2.0 0.3.0 0.3.1 0.9.0]
@ -76,7 +80,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when keep locked, keep current, then favor next release, remove minor and major increases" do it "when keep locked, keep current, then favor next release, remove minor and major increases" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "0.2.0"), ["bar"]), build_package("foo", [], build_spec_set("foo", "0.2.0"), ["bar"]),
build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1])
) )
expect(versions(res)).to eq %w[0.3.0 0.3.1 0.9.0 0.2.0] expect(versions(res)).to eq %w[0.3.0 0.3.1 0.9.0 0.2.0]
@ -93,7 +97,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when not unlocking, same order but make sure build_spec version is most preferred to stay put" do it "when not unlocking, same order but make sure build_spec version is most preferred to stay put" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.7"), ["bar"]), build_package("foo", [], build_spec_set("foo", "1.7.7"), ["bar"]),
build_candidates(%w[1.5.4 1.6.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 2.0.0 2.0.1]) build_candidates(%w[1.5.4 1.6.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 2.0.0 2.0.1])
) )
expect(versions(res)).to eq %w[1.5.4 1.6.5 1.7.6 2.0.0 2.0.1 1.8.0 1.8.1 1.7.8 1.7.9 1.7.7] expect(versions(res)).to eq %w[1.5.4 1.6.5 1.7.6 2.0.0 2.0.1 1.8.0 1.8.1 1.7.8 1.7.9 1.7.7]
@ -101,7 +105,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking favor next release, then current over minor increase" do it "when unlocking favor next release, then current over minor increase" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), build_package("foo", [], build_spec_set("foo", "1.7.8"), []),
build_candidates(%w[1.7.7 1.7.8 1.7.9 1.8.0]) build_candidates(%w[1.7.7 1.7.8 1.7.9 1.8.0])
) )
expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9] expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9]
@ -109,7 +113,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking do proper integer comparison, not string" do it "when unlocking do proper integer comparison, not string" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.8"), []), build_package("foo", [], build_spec_set("foo", "1.7.8"), []),
build_candidates(%w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0]) build_candidates(%w[1.7.7 1.7.8 1.7.9 1.7.15 1.8.0])
) )
expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9 1.7.15] expect(versions(res)).to eq %w[1.7.7 1.8.0 1.7.8 1.7.9 1.7.15]
@ -117,7 +121,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "leave current when unlocking but already at latest release" do it "leave current when unlocking but already at latest release" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "1.7.9"), []), build_package("foo", [], build_spec_set("foo", "1.7.9"), []),
build_candidates(%w[1.7.9 1.8.0 2.0.0]) build_candidates(%w[1.7.9 1.8.0 2.0.0])
) )
expect(versions(res)).to eq %w[2.0.0 1.8.0 1.7.9] expect(versions(res)).to eq %w[2.0.0 1.8.0 1.7.9]
@ -134,7 +138,7 @@ RSpec.describe Bundler::GemVersionPromoter do
it "when unlocking favor next release, then minor increase over current" do it "when unlocking favor next release, then minor increase over current" do
res = gvp.sort_versions( res = gvp.sort_versions(
Bundler::Resolver::Package.new("foo", [], build_spec_set("foo", "0.2.0"), []), build_package("foo", [], build_spec_set("foo", "0.2.0"), []),
build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1]) build_candidates(%w[0.2.0 0.3.0 0.3.1 0.9.0 1.0.0 2.0.0 2.0.1])
) )
expect(versions(res)).to eq %w[2.0.0 2.0.1 1.0.0 0.2.0 0.3.0 0.3.1 0.9.0] expect(versions(res)).to eq %w[2.0.0 2.0.1 1.0.0 0.2.0 0.3.0 0.3.1 0.9.0]

View file

@ -140,7 +140,7 @@ RSpec.describe Bundler::Plugin::Index do
describe "after conflict" do describe "after conflict" do
let(:commands) { ["foo"] } let(:commands) { ["foo"] }
let(:sources) { ["bar"] } let(:sources) { ["bar"] }
let(:hooks) { ["hoook"] } let(:hooks) { ["thehook"] }
shared_examples "it cleans up" do shared_examples "it cleans up" do
it "the path" do it "the path" do
@ -156,7 +156,7 @@ RSpec.describe Bundler::Plugin::Index do
end end
it "the hook" do it "the hook" do
expect(index.hook_plugins("xhoook")).to be_empty expect(index.hook_plugins("xthehook")).to be_empty
end end
end end
@ -164,7 +164,7 @@ RSpec.describe Bundler::Plugin::Index do
before do before do
expect do expect do
path = lib_path("cplugin") path = lib_path("cplugin")
index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["xbar"], ["xhoook"]) index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["xbar"], ["xthehook"])
end.to raise_error(Index::CommandConflict) end.to raise_error(Index::CommandConflict)
end end
@ -175,7 +175,7 @@ RSpec.describe Bundler::Plugin::Index do
before do before do
expect do expect do
path = lib_path("cplugin") path = lib_path("cplugin")
index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["xfoo"], ["bar"], ["xhoook"]) index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["xfoo"], ["bar"], ["xthehook"])
end.to raise_error(Index::SourceConflict) end.to raise_error(Index::SourceConflict)
end end
@ -186,7 +186,7 @@ RSpec.describe Bundler::Plugin::Index do
before do before do
expect do expect do
path = lib_path("cplugin") path = lib_path("cplugin")
index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["bar"], ["xhoook"]) index.register_plugin("cplugin", path.to_s, [path.join("lib").to_s], ["foo"], ["bar"], ["xthehook"])
end.to raise_error(Index::CommandConflict) end.to raise_error(Index::CommandConflict)
end end

View file

@ -3,8 +3,19 @@
RSpec.describe Bundler::Resolver::Candidate do RSpec.describe Bundler::Resolver::Candidate do
it "compares fine" do it "compares fine" do
version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }]) version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }])
version2 = described_class.new("1.12.5") version2 = described_class.new("1.12.5") # passing no specs creates a platform specific candidate, so sorts higher
expect(version1 >= version2).to be true expect(version2 >= version1).to be true
expect(version1.generic! == version2.generic!).to be true
expect(version1.platform_specific! == version2.platform_specific!).to be true
expect(version1.platform_specific! >= version2.generic!).to be true
expect(version2.platform_specific! >= version1.generic!).to be true
version1 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }])
version2 = described_class.new("1.12.5", :specs => [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::X64_LINUX }])
expect(version2 >= version1).to be true
end end
end end

View file

@ -27,7 +27,7 @@ RSpec.describe Bundler::Settings do
"gem.mit" => "false", "gem.mit" => "false",
"gem.test" => "minitest", "gem.test" => "minitest",
"thingy" => <<-EOS.tr("\n", " "), "thingy" => <<-EOS.tr("\n", " "),
--asdf --fdsa --ty=oh man i hope this doesnt break bundler because --asdf --fdsa --ty=oh man i hope this doesn't break bundler because
that would suck --ehhh=oh geez it looks like i might have broken bundler somehow that would suck --ehhh=oh geez it looks like i might have broken bundler somehow
--very-important-option=DontDeleteRoo --very-important-option=DontDeleteRoo
--very-important-option=DontDeleteRoo --very-important-option=DontDeleteRoo

View file

@ -248,6 +248,8 @@ RSpec.describe Bundler::SharedHelpers do
shared_examples_for "ENV['BUNDLER_SETUP'] gets set correctly" do shared_examples_for "ENV['BUNDLER_SETUP'] gets set correctly" do
it "ensures bundler/setup is set in ENV['BUNDLER_SETUP']" do it "ensures bundler/setup is set in ENV['BUNDLER_SETUP']" do
skip "Does not play well with DidYouMean being a bundled gem instead of a default gem in Ruby 2.6" if RUBY_VERSION < "2.7"
subject.set_bundle_environment subject.set_bundle_environment
expect(ENV["BUNDLER_SETUP"]).to eq("#{source_lib_dir}/bundler/setup") expect(ENV["BUNDLER_SETUP"]).to eq("#{source_lib_dir}/bundler/setup")
end end

View file

@ -144,7 +144,7 @@ RSpec.describe "bundle add" do
end end
describe "with --github" do describe "with --github" do
it "adds dependency with specified github source" do it "adds dependency with specified github source", :realworld do
bundle "add rake --github=ruby/rake" bundle "add rake --github=ruby/rake"
expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake"}) expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake"})
@ -152,7 +152,7 @@ RSpec.describe "bundle add" do
end end
describe "with --github and --branch" do describe "with --github and --branch" do
it "adds dependency with specified github source and branch" do it "adds dependency with specified github source and branch", :realworld do
bundle "add rake --github=ruby/rake --branch=master" bundle "add rake --github=ruby/rake --branch=master"
expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :branch => "master"}) expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :branch => "master"})
@ -160,7 +160,7 @@ RSpec.describe "bundle add" do
end end
describe "with --github and --ref" do describe "with --github and --ref" do
it "adds dependency with specified github source and ref" do it "adds dependency with specified github source and ref", :realworld do
bundle "add rake --github=ruby/rake --ref=5c60da8" bundle "add rake --github=ruby/rake --ref=5c60da8"
expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :ref => "5c60da8"}) expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.0", :github => "ruby\/rake", :ref => "5c60da8"})

View file

@ -188,7 +188,7 @@ RSpec.describe "bundle binstubs <gem>" do
lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.3.0") lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.3.0")
end end
it "installs and runs the exact version of bundler", :rubygems => ">= 3.3.0.dev" do it "installs and runs the exact version of bundler", :rubygems => ">= 3.3.0.dev", :realworld => true do
sys_exec "bin/bundle install --verbose", :artifice => "vcr" sys_exec "bin/bundle install --verbose", :artifice => "vcr"
expect(exitstatus).not_to eq(42) expect(exitstatus).not_to eq(42)
expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.") expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.")
@ -224,7 +224,7 @@ RSpec.describe "bundle binstubs <gem>" do
context "when update --bundler is called" do context "when update --bundler is called" do
before { lockfile.gsub(system_bundler_version, "1.1.1") } before { lockfile.gsub(system_bundler_version, "1.1.1") }
it "calls through to the latest bundler version" do it "calls through to the latest bundler version", :realworld do
sys_exec "bin/bundle update --bundler", :env => { "DEBUG" => "1" } sys_exec "bin/bundle update --bundler", :env => { "DEBUG" => "1" }
using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out) using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out)
expect(using_bundler_line).to_not be_nil expect(using_bundler_line).to_not be_nil

View file

@ -625,7 +625,7 @@ RSpec.describe "bundle clean" do
expect(out).to eq("1.0") expect(out).to eq("1.0")
end end
it "when using --force, it doesn't remove default gem binaries" do it "when using --force, it doesn't remove default gem binaries", :realworld do
skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0" skip "does not work on old rubies because the realworld gems that need to be installed don't support them" if RUBY_VERSION < "2.7.0"
skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2 skip "does not work on rubygems versions where `--install_dir` doesn't respect --default" unless Gem::Installer.for_spec(loaded_gemspec, :install_dir => "/foo").default_spec_file == "/foo/specifications/default/bundler-#{Bundler::VERSION}.gemspec" # Since rubygems 3.2.0.rc.2

View file

@ -134,7 +134,7 @@ RSpec.describe "bundle doctor" do
end end
end end
context "when home contains filesname with special characters" do context "when home contains filenames with special characters" do
it "escape filename before command execute" do it "escape filename before command execute" do
doctor = Bundler::CLI::Doctor.new({}) doctor = Bundler::CLI::Doctor.new({})
expect(doctor).to receive(:`).with("/usr/bin/otool -L \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string") expect(doctor).to receive(:`).with("/usr/bin/otool -L \\$\\(date\\)\\ \\\"\\'\\\\.bundle").and_return("dummy string")

View file

@ -1076,4 +1076,31 @@ RSpec.describe "bundle install with gem sources" do
G G
end end
end end
context "when a gem has equivalent versions with inconsistent dependencies" do
before do
build_repo4 do
build_gem "autobuild", "1.10.rc2" do |s|
s.add_dependency "utilrb", ">= 1.6.0"
end
build_gem "autobuild", "1.10.0.rc2" do |s|
s.add_dependency "utilrb", ">= 2.0"
end
end
end
it "does not crash unexpectedly" do
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "autobuild", "1.10.rc2"
G
bundle "install --jobs 1", :raise_on_error => false
expect(err).not_to include("ERROR REPORT TEMPLATE")
expect(err).to include("Could not find compatible versions")
end
end
end end

View file

@ -319,6 +319,61 @@ RSpec.describe "bundle lock" do
expect(lockfile.platforms).to match_array([x86_mingw32, specific_local_platform].uniq) expect(lockfile.platforms).to match_array([x86_mingw32, specific_local_platform].uniq)
end end
it "also cleans up redundant platform gems when removing platforms" do
build_repo4 do
build_gem "nokogiri", "1.12.0"
build_gem "nokogiri", "1.12.0" do |s|
s.platform = "x86_64-darwin"
end
end
simulate_platform "x86_64-darwin-22" do
install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "nokogiri"
G
end
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.12.0)
nokogiri (1.12.0-x86_64-darwin)
PLATFORMS
ruby
x86_64-darwin
DEPENDENCIES
nokogiri
BUNDLED WITH
#{Bundler::VERSION}
L
simulate_platform "x86_64-darwin-22" do
bundle "lock --remove-platform ruby"
end
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.12.0-x86_64-darwin)
PLATFORMS
x86_64-darwin
DEPENDENCIES
nokogiri
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "errors when removing all platforms" do it "errors when removing all platforms" do
bundle "lock --remove-platform #{specific_local_platform}", :raise_on_error => false bundle "lock --remove-platform #{specific_local_platform}", :raise_on_error => false
expect(err).to include("Removing all platforms from the bundle is not allowed") expect(err).to include("Removing all platforms from the bundle is not allowed")
@ -713,133 +768,212 @@ RSpec.describe "bundle lock" do
#{Bundler::VERSION} #{Bundler::VERSION}
L L
end end
end
it "properly shows resolution errors including OR requirements" do it "properly shows resolution errors including OR requirements" do
build_repo4 do build_repo4 do
build_gem "activeadmin", "2.13.1" do |s| build_gem "activeadmin", "2.13.1" do |s|
s.add_dependency "railties", ">= 6.1", "< 7.1" s.add_dependency "railties", ">= 6.1", "< 7.1"
end end
build_gem "actionpack", "6.1.4" build_gem "actionpack", "6.1.4"
build_gem "actionpack", "7.0.3.1" build_gem "actionpack", "7.0.3.1"
build_gem "actionpack", "7.0.4" build_gem "actionpack", "7.0.4"
build_gem "railties", "6.1.4" do |s| build_gem "railties", "6.1.4" do |s|
s.add_dependency "actionpack", "6.1.4" s.add_dependency "actionpack", "6.1.4"
end end
build_gem "rails", "7.0.3.1" do |s| build_gem "rails", "7.0.3.1" do |s|
s.add_dependency "railties", "7.0.3.1" s.add_dependency "railties", "7.0.3.1"
end end
build_gem "rails", "7.0.4" do |s| build_gem "rails", "7.0.4" do |s|
s.add_dependency "railties", "7.0.4" s.add_dependency "railties", "7.0.4"
end
end end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "rails", ">= 7.0.3.1"
gem "activeadmin", "2.13.1"
G
bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
Because rails >= 7.0.4 depends on railties = 7.0.4
and rails < 7.0.4 depends on railties = 7.0.3.1,
railties = 7.0.3.1 OR = 7.0.4 is required.
So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally,
version solving has failed.
ERR
end end
it "is able to display some explanation on crazy irresolvable cases" do gemfile <<~G
build_repo4 do source "#{file_uri_for(gem_repo4)}"
build_gem "activeadmin", "2.13.1" do |s|
s.add_dependency "ransack", "= 3.1.0"
end
# Activemodel is missing as a dependency in lockfile gem "rails", ">= 7.0.3.1"
build_gem "ransack", "3.1.0" do |s| gem "activeadmin", "2.13.1"
s.add_dependency "activemodel", ">= 6.0.4" G
s.add_dependency "activesupport", ">= 6.0.4"
end
%w[6.0.4 7.0.2.3 7.0.3.1 7.0.4].each do |version| bundle "lock", :raise_on_error => false
build_gem "activesupport", version
# Activemodel is only available on 6.0.4 expect(err).to eq <<~ERR.strip
if version == "6.0.4" Could not find compatible versions
build_gem "activemodel", version do |s|
s.add_dependency "activesupport", version Because rails >= 7.0.4 depends on railties = 7.0.4
end and rails < 7.0.4 depends on railties = 7.0.3.1,
railties = 7.0.3.1 OR = 7.0.4 is required.
So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally,
version solving has failed.
ERR
end
it "is able to display some explanation on crazy irresolvable cases" do
build_repo4 do
build_gem "activeadmin", "2.13.1" do |s|
s.add_dependency "ransack", "= 3.1.0"
end
# Activemodel is missing as a dependency in lockfile
build_gem "ransack", "3.1.0" do |s|
s.add_dependency "activemodel", ">= 6.0.4"
s.add_dependency "activesupport", ">= 6.0.4"
end
%w[6.0.4 7.0.2.3 7.0.3.1 7.0.4].each do |version|
build_gem "activesupport", version
# Activemodel is only available on 6.0.4
if version == "6.0.4"
build_gem "activemodel", version do |s|
s.add_dependency "activesupport", version
end end
end
build_gem "rails", version do |s| build_gem "rails", version do |s|
# Depednencies of Rails 7.0.2.3 are in reverse order # Depednencies of Rails 7.0.2.3 are in reverse order
if version == "7.0.2.3" if version == "7.0.2.3"
s.add_dependency "activesupport", version s.add_dependency "activesupport", version
s.add_dependency "activemodel", version s.add_dependency "activemodel", version
else else
s.add_dependency "activemodel", version s.add_dependency "activemodel", version
s.add_dependency "activesupport", version s.add_dependency "activesupport", version
end
end end
end end
end end
end
gemfile <<~G gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "rails", ">= 7.0.2.3"
gem "activeadmin", "= 2.13.1"
G
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
activeadmin (2.13.1)
ransack (= 3.1.0)
ransack (3.1.0)
activemodel (>= 6.0.4)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
activeadmin (= 2.13.1)
ransack (= 3.1.0)
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
Because every version of activemodel depends on activesupport = 6.0.4
and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3,
every version of activemodel is incompatible with rails >= 7.0.2.3, < 7.0.3.1.
And because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3,
rails >= 7.0.2.3, < 7.0.3.1 is forbidden.
(1) So, because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1
and rails >= 7.0.4 depends on activemodel = 7.0.4,
rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4.
Because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3
and rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1,
rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 or activesupport = 7.0.3.1.
And because rails >= 7.0.4 depends on activesupport = 7.0.4
and every version of activemodel depends on activesupport = 6.0.4,
activemodel != 7.0.2.3 is incompatible with rails >= 7.0.2.3.
And because rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4 (1),
rails >= 7.0.2.3 is forbidden.
So, because Gemfile depends on rails >= 7.0.2.3,
version solving has failed.
ERR
end
it "does not accidentally resolves to prereleases" do
build_repo4 do
build_gem "autoproj", "2.0.3" do |s|
s.add_dependency "autobuild", ">= 1.10.0.a"
s.add_dependency "tty-prompt"
end
build_gem "tty-prompt", "0.6.0"
build_gem "tty-prompt", "0.7.0"
build_gem "autobuild", "1.10.0.b3"
build_gem "autobuild", "1.10.1" do |s|
s.add_dependency "tty-prompt", "~> 0.6.0"
end
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "autoproj", ">= 2.0.0"
G
bundle "lock"
expect(lockfile).to_not include("autobuild (1.10.0.b3)")
expect(lockfile).to include("autobuild (1.10.1)")
end
it "deals with platform specific incompatibilities" do
build_repo4 do
build_gem "activerecord", "6.0.6"
build_gem "activerecord-jdbc-adapter", "60.4" do |s|
s.platform = "java"
s.add_dependency "activerecord", "~> 6.0.0"
end
build_gem "activerecord-jdbc-adapter", "61.0" do |s|
s.platform = "java"
s.add_dependency "activerecord", "~> 6.1.0"
end
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "activerecord", "6.0.6"
gem "activerecord-jdbc-adapter", "61.0"
G
simulate_platform "universal-java-19" do
bundle "lock", :raise_on_error => false
end
expect(err).to include("Could not find compatible versions")
expect(err).not_to include("ERROR REPORT TEMPLATE")
end
context "when re-resolving to include prereleases" do
before do
build_repo4 do
build_gem "tzinfo-data", "1.2022.7"
build_gem "rails", "7.1.0.alpha" do |s|
s.add_dependency "activesupport"
end
build_gem "activesupport", "7.1.0.alpha"
end
end
it "does not end up including gems scoped to other platforms in the lockfile" do
gemfile <<-G
source "#{file_uri_for(gem_repo4)}" source "#{file_uri_for(gem_repo4)}"
gem "rails"
gem "rails", ">= 7.0.2.3" gem "tzinfo-data", platform: :windows
gem "activeadmin", "= 2.13.1"
G G
lockfile <<~L simulate_platform "x86_64-darwin-22" do
GEM bundle "lock"
remote: #{file_uri_for(gem_repo4)}/ end
specs:
activeadmin (2.13.1)
ransack (= 3.1.0)
ransack (3.1.0)
activemodel (>= 6.0.4)
PLATFORMS expect(lockfile).not_to include("tzinfo-data (1.2022.7)")
#{lockfile_platforms}
DEPENDENCIES
activeadmin (= 2.13.1)
ransack (= 3.1.0)
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "lock", :raise_on_error => false
expect(err).to eq <<~ERR.strip
Could not find compatible versions
Because every version of activemodel depends on activesupport = 6.0.4
and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3,
every version of activemodel is incompatible with rails >= 7.0.2.3, < 7.0.3.1.
And because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3,
rails >= 7.0.2.3, < 7.0.3.1 is forbidden.
(1) So, because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1
and rails >= 7.0.4 depends on activemodel = 7.0.4,
rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4.
Because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3
and rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1,
rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 or activesupport = 7.0.3.1.
And because rails >= 7.0.4 depends on activesupport = 7.0.4
and every version of activemodel depends on activesupport = 6.0.4,
activemodel != 7.0.2.3 is incompatible with rails >= 7.0.2.3.
And because rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4 (1),
rails >= 7.0.2.3 is forbidden.
So, because Gemfile depends on rails >= 7.0.2.3,
version solving has failed.
ERR
end end
end end
end end

View file

@ -58,6 +58,64 @@ RSpec.describe "bundle open" do
expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}") expect(out).to include("bundler_editor #{default_bundle_path("gems", "activerecord-2.3.2")}")
end end
it "opens subpath of the gem" do
bundle "open activerecord --path lib/activerecord", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord")
end
it "opens subpath file of the gem" do
bundle "open activerecord --path lib/version.rb", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/version.rb")
end
it "opens deep subpath of the gem" do
bundle "open activerecord --path lib/active_record", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/active_record")
end
it "requires value for --path arg" do
bundle "open activerecord --path", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to eq "Cannot specify `--path` option without a value"
end
it "suggests alternatives for similar-sounding gems when using subpath" do
bundle "open Rails --path README.md", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to match(/did you mean rails\?/i)
end
it "suggests alternatives for similar-sounding gems when using deep subpath" do
bundle "open Rails --path some/path/here", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }, :raise_on_error => false
expect(err).to match(/did you mean rails\?/i)
end
it "opens subpath of the short worded gem" do
bundle "open rec --path CHANGELOG.md", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/CHANGELOG.md")
end
it "opens deep subpath of the short worded gem" do
bundle "open rec --path lib/activerecord", :env => { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" }
expect(out).to include("editor #{default_bundle_path("gems", "activerecord-2.3.2")}/lib/activerecord")
end
it "opens subpath of the selected matching gem", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
bundle "open active --path CHANGELOG.md", :env => env do |input, _, _|
input.puts "2"
end
expect(out).to match(%r{bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}/CHANGELOG\.md\z})
end
it "opens deep subpath of the selected matching gem", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
bundle "open active --path lib/activerecord/version.rb", :env => env do |input, _, _|
input.puts "2"
end
expect(out).to match(%r{bundler_editor #{default_bundle_path('gems', 'activerecord-2.3.2')}/lib/activerecord/version\.rb\z})
end
it "select the gem from many match gems", :readline do it "select the gem from many match gems", :readline do
env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" } env = { "EDITOR" => "echo editor", "VISUAL" => "echo visual", "BUNDLER_EDITOR" => "echo bundler_editor" }
bundle "open active", :env => env do |input, _, _| bundle "open active", :env => env do |input, _, _|

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot") do RSpec.describe "bundle viz", :bundler => "< 3", :if => Bundler.which("dot"), :realworld => true do
before do before do
realworld_system_gems "ruby-graphviz --version 1.2.5" realworld_system_gems "ruby-graphviz --version 1.2.5"
end end

View file

@ -1481,8 +1481,6 @@ In Gemfile:
describe "without git installed" do describe "without git installed" do
it "prints a better error message when installing" do it "prints a better error message when installing" do
build_git "foo"
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"

View file

@ -36,7 +36,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
end end
it "fails", :bundler => "3" do it "fails", :bundler => "3" do
bundle :instal, :artifice => "compact_index", :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(err).to include("Each source after the first must include a block")
expect(exitstatus).to eq(4) expect(exitstatus).to eq(4)
end end
@ -1320,7 +1320,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(out).to include("Using example 0.1.0") expect(out).to include("Using example 0.1.0")
end end
it "fails inmmediately with a helpful error when a rubygems source does not exist and bundler/setup is required" do it "fails immediately with a helpful error when a rubygems source does not exist and bundler/setup is required" do
gemfile <<-G gemfile <<-G
source "https://gem.repo1" source "https://gem.repo1"
@ -1339,7 +1339,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
expect(err).to include("Could not find gem 'example' in locally installed gems.") expect(err).to include("Could not find gem 'example' in locally installed gems.")
end end
it "fails inmmediately with a helpful error when a non retriable network error happens while resolving sources" do it "fails immediately with a helpful error when a non retriable network error happens while resolving sources" do
gemfile <<-G gemfile <<-G
source "https://gem.repo1" source "https://gem.repo1"

View file

@ -6,10 +6,8 @@ RSpec.describe "bundle install with specific platforms" do
gem "google-protobuf" gem "google-protobuf"
G G
context "when on a darwin machine" do it "locks to the specific darwin platform" do
before { simulate_platform "x86_64-darwin-15" } simulate_platform "x86_64-darwin-15" do
it "locks to the specific darwin platform" do
setup_multiplatform_gem setup_multiplatform_gem
install_gemfile(google_protobuf) install_gemfile(google_protobuf)
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
@ -19,8 +17,10 @@ RSpec.describe "bundle install with specific platforms" do
google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin google-protobuf-3.0.0.alpha.5.0.5.1-universal-darwin
]) ])
end end
end
it "understands that a non-platform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do it "understands that a non-platform specific gem in a old lockfile doesn't necessarily mean installing the non-specific variant" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem setup_multiplatform_gem
system_gems "bundler-2.1.4" system_gems "bundler-2.1.4"
@ -53,8 +53,10 @@ RSpec.describe "bundle install with specific platforms" do
# make sure the platform that got actually installed with the old bundler is used # make sure the platform that got actually installed with the old bundler is used
expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin") expect(the_bundle).to include_gem("google-protobuf 3.0.0.alpha.5.0.5.1 universal-darwin")
end end
end
it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem setup_multiplatform_gem
system_gems "bundler-2.1.4" system_gems "bundler-2.1.4"
@ -103,8 +105,59 @@ RSpec.describe "bundle install with specific platforms" do
#{Bundler::VERSION} #{Bundler::VERSION}
L L
end end
end
it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do context "when running on a legacy lockfile locked only to RUBY" do
around do |example|
build_repo4 do
build_gem "nokogiri", "1.3.10"
build_gem "nokogiri", "1.3.10" do |s|
s.platform = "arm64-darwin"
s.required_ruby_version = "< #{Gem.ruby_version}"
end
build_gem "bundler", "2.1.4"
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "nokogiri"
G
lockfile <<-L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.3.10)
PLATFORMS
ruby
DEPENDENCIES
nokogiri
RUBY VERSION
2.5.3p105
BUNDLED WITH
2.1.4
L
simulate_platform "arm64-darwin-22", &example
end
it "still installs the generic RUBY variant if necessary" do
bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
end
it "still installs the generic RUBY variant if necessary, even in frozen mode" do
bundle "update --bundler", :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" }
end
end
it "doesn't discard previously installed platform specific gem and fall back to ruby on subsequent bundles" do
simulate_platform "x86_64-darwin-15" do
build_repo2 do build_repo2 do
build_gem("libv8", "8.4.255.0") build_gem("libv8", "8.4.255.0")
build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" } build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" }
@ -147,8 +200,10 @@ RSpec.describe "bundle install with specific platforms" do
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)") expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)")
end end
end
it "chooses platform specific gems even when resolving upon materialization and the API returns more specific plaforms first" do it "chooses platform specific gems even when resolving upon materialization and the API returns more specific platforms first" do
simulate_platform "x86_64-darwin-15" do
build_repo4 do build_repo4 do
build_gem("grpc", "1.50.0") build_gem("grpc", "1.50.0")
build_gem("grpc", "1.50.0") {|s| s.platform = "universal-darwin" } build_gem("grpc", "1.50.0") {|s| s.platform = "universal-darwin" }
@ -179,8 +234,10 @@ RSpec.describe "bundle install with specific platforms" do
bundle "install --verbose", :artifice => "compact_index_precompiled_before", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } bundle "install --verbose", :artifice => "compact_index_precompiled_before", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
expect(out).to include("Installing grpc 1.50.0 (universal-darwin)") expect(out).to include("Installing grpc 1.50.0 (universal-darwin)")
end end
end
it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do it "caches the universal-darwin gem when --all-platforms is passed and properly picks it up on further bundler invocations" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem setup_multiplatform_gem
gemfile(google_protobuf) gemfile(google_protobuf)
bundle "cache --all-platforms" bundle "cache --all-platforms"
@ -189,8 +246,10 @@ RSpec.describe "bundle install with specific platforms" do
bundle "install --verbose" bundle "install --verbose"
expect(err).to be_empty expect(err).to be_empty
end end
end
it "caches the universal-darwin gem when cache_all_platforms is configured and properly picks it up on further bundler invocations" do it "caches the universal-darwin gem when cache_all_platforms is configured and properly picks it up on further bundler invocations" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem setup_multiplatform_gem
gemfile(google_protobuf) gemfile(google_protobuf)
bundle "config set --local cache_all_platforms true" bundle "config set --local cache_all_platforms true"
@ -200,44 +259,46 @@ RSpec.describe "bundle install with specific platforms" do
bundle "install --verbose" bundle "install --verbose"
expect(err).to be_empty expect(err).to be_empty
end end
end
it "caches multiplatform git gems with a single gemspec when --all-platforms is passed" do it "caches multiplatform git gems with a single gemspec when --all-platforms is passed" do
git = build_git "pg_array_parser", "1.0" git = build_git "pg_array_parser", "1.0"
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "pg_array_parser", :git => "#{lib_path("pg_array_parser-1.0")}" gem "pg_array_parser", :git => "#{lib_path("pg_array_parser-1.0")}"
G G
lockfile <<-L lockfile <<-L
GIT GIT
remote: #{lib_path("pg_array_parser-1.0")} remote: #{lib_path("pg_array_parser-1.0")}
revision: #{git.ref_for("main")} revision: #{git.ref_for("main")}
specs: specs:
pg_array_parser (1.0-java) pg_array_parser (1.0-java)
pg_array_parser (1.0) pg_array_parser (1.0)
GEM GEM
specs: specs:
PLATFORMS PLATFORMS
java java
#{lockfile_platforms} #{lockfile_platforms}
DEPENDENCIES DEPENDENCIES
pg_array_parser! pg_array_parser!
BUNDLED WITH BUNDLED WITH
#{Bundler::VERSION} #{Bundler::VERSION}
L L
bundle "config set --local cache_all true" bundle "config set --local cache_all true"
bundle "cache --all-platforms" bundle "cache --all-platforms"
expect(err).to be_empty expect(err).to be_empty
end end
it "uses the platform-specific gem with extra dependencies" do it "uses the platform-specific gem with extra dependencies" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem_with_different_dependencies_per_platform setup_multiplatform_gem_with_different_dependencies_per_platform
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo2)}"
@ -250,13 +311,15 @@ RSpec.describe "bundle install with specific platforms" do
expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(["CFPropertyList-1.0", expect(the_bundle.locked_gems.specs.map(&:full_name)).to eq(["CFPropertyList-1.0",
"facter-2.4.6-universal-darwin"]) "facter-2.4.6-universal-darwin"])
end end
end
context "when adding a platform via lock --add_platform" do context "when adding a platform via lock --add_platform" do
before do before do
allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile)
end end
it "adds the foreign platform" do it "adds the foreign platform" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem setup_multiplatform_gem
install_gemfile(google_protobuf) install_gemfile(google_protobuf)
bundle "lock --add-platform=#{x64_mingw32}" bundle "lock --add-platform=#{x64_mingw32}"
@ -267,8 +330,10 @@ RSpec.describe "bundle install with specific platforms" do
google-protobuf-3.0.0.alpha.5.0.5.1-x64-mingw32 google-protobuf-3.0.0.alpha.5.0.5.1-x64-mingw32
]) ])
end end
end
it "falls back on plain ruby when that version doesnt have a platform-specific gem" do it "falls back on plain ruby when that version doesn't have a platform-specific gem" do
simulate_platform "x86_64-darwin-15" do
setup_multiplatform_gem setup_multiplatform_gem
install_gemfile(google_protobuf) install_gemfile(google_protobuf)
bundle "lock --add-platform=#{java}" bundle "lock --add-platform=#{java}"
@ -483,6 +548,75 @@ RSpec.describe "bundle install with specific platforms" do
L L
end end
it "automatically fixes the lockfile if both RUBY platform and a more specific platform are locked, and some gem has no RUBY variant available" do
build_repo4 do
build_gem "nokogiri", "1.12.0"
build_gem "nokogiri", "1.12.0" do |s|
s.platform = "x86_64-darwin"
end
build_gem "nokogiri", "1.13.0"
build_gem "nokogiri", "1.13.0" do |s|
s.platform = "x86_64-darwin"
end
build_gem("sorbet-static", "0.5.10601") do |s|
s.platform = "x86_64-darwin"
end
end
simulate_platform "x86_64-darwin-22" do
install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "nokogiri"
gem "sorbet-static"
G
end
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.12.0)
nokogiri (1.12.0-x86_64-darwin)
sorbet-static (0.5.10601-x86_64-darwin)
PLATFORMS
ruby
x86_64-darwin
DEPENDENCIES
nokogiri
sorbet
BUNDLED WITH
#{Bundler::VERSION}
L
simulate_platform "x86_64-darwin-22" do
bundle "update --conservative nokogiri"
end
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
nokogiri (1.13.0-x86_64-darwin)
sorbet-static (0.5.10601-x86_64-darwin)
PLATFORMS
x86_64-darwin
DEPENDENCIES
nokogiri
sorbet-static
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically fixes the lockfile if only RUBY platform is locked and some gem has no RUBY variant available" do it "automatically fixes the lockfile if only RUBY platform is locked and some gem has no RUBY variant available" do
build_repo4 do build_repo4 do
build_gem("sorbet-static-and-runtime", "0.5.10160") do |s| build_gem("sorbet-static-and-runtime", "0.5.10160") do |s|
@ -554,6 +688,63 @@ RSpec.describe "bundle install with specific platforms" do
L L
end end
it "automatically fixes the lockfile without removing other variants if it's missing platform gems, but they are installed locally" do
simulate_platform "x86_64-darwin-21" do
build_repo4 do
build_gem("sorbet-static", "0.5.10549") do |s|
s.platform = "universal-darwin-20"
end
build_gem("sorbet-static", "0.5.10549") do |s|
s.platform = "universal-darwin-21"
end
end
# Make sure sorbet-static-0.5.10549-universal-darwin-21 is installed
install_gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "sorbet-static", "= 0.5.10549"
G
# Make sure the lockfile is missing sorbet-static-0.5.10549-universal-darwin-21
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
sorbet-static (0.5.10549-universal-darwin-20)
PLATFORMS
x86_64-darwin
DEPENDENCIES
sorbet-static (= 0.5.10549)
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
sorbet-static (0.5.10549-universal-darwin-20)
sorbet-static (0.5.10549-universal-darwin-21)
PLATFORMS
x86_64-darwin
DEPENDENCIES
sorbet-static (= 0.5.10549)
BUNDLED WITH
#{Bundler::VERSION}
L
end
end
it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do
build_repo4 do build_repo4 do
build_gem "nokogiri", "1.13.8" build_gem "nokogiri", "1.13.8"
@ -607,7 +798,7 @@ RSpec.describe "bundle install with specific platforms" do
G G
# simulate lockfile which includes both a precompiled gem with: # simulate lockfile which includes both a precompiled gem with:
# - Gem the current platform (with imcompatible ruby version) # - Gem the current platform (with incompatible ruby version)
# - A source gem with compatible ruby version # - A source gem with compatible ruby version
lockfile <<-L lockfile <<-L
GEM GEM

View file

@ -157,7 +157,7 @@ RSpec.shared_examples "bundle install --standalone" do
bundle "lock", :dir => cwd, :artifice => "compact_index" bundle "lock", :dir => cwd, :artifice => "compact_index"
end end
it "works and points to the vendored copies, not to the default copies" do it "works and points to the vendored copies, not to the default copies", :realworld do
bundle "config set --local path #{bundled_app("bundle")}" bundle "config set --local path #{bundled_app("bundle")}"
bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } bundle :install, :standalone => true, :dir => cwd, :artifice => "compact_index", :env => { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s }

View file

@ -587,7 +587,7 @@ RSpec.describe "major deprecations" do
pending "fails with a helpful message", :bundler => "3" pending "fails with a helpful message", :bundler => "3"
end end
context "bundle viz" do context "bundle viz", :realworld do
before do before do
realworld_system_gems "ruby-graphviz --version 1.2.5" realworld_system_gems "ruby-graphviz --version 1.2.5"
create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\"" create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\""

View file

@ -219,14 +219,14 @@ RSpec.describe "real world edgecases", :realworld => true do
end end
it "doesn't hang on big gemfile" do it "doesn't hang on big gemfile" do
skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM.include?("darwin") skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7")
gemfile <<~G gemfile <<~G
# frozen_string_literal: true # frozen_string_literal: true
source "https://rubygems.org" source "https://rubygems.org"
ruby "2.7.3" ruby "~> 2.7.7"
gem "rails" gem "rails"
gem "pg", ">= 0.18", "< 2.0" gem "pg", ">= 0.18", "< 2.0"
@ -321,17 +321,17 @@ RSpec.describe "real world edgecases", :realworld => true do
G G
if Bundler.feature_flag.bundler_3_mode? if Bundler.feature_flag.bundler_3_mode?
# Conflicts on bundler version, so fails earlier # Conflicts on bundler version, so we count attempts differently
bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }, :raise_on_error => false bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }, :raise_on_error => false
expect(out).to display_total_steps_of(435) expect(out.split("\n").grep(/backtracking to/).count).to eq(16)
else else
bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
expect(out).to display_total_steps_of(1025) expect(out).to include("Solution found after 7 attempts")
end end
end end
it "doesn't hang on tricky gemfile" do it "doesn't hang on tricky gemfile" do
skip "Only for ruby 2.7.3" if RUBY_VERSION != "2.7.3" || RUBY_PLATFORM.include?("darwin") skip "Only for ruby 2.7" unless RUBY_VERSION.start_with?("2.7")
gemfile <<~G gemfile <<~G
source 'https://rubygems.org' source 'https://rubygems.org'
@ -349,190 +349,168 @@ RSpec.describe "real world edgecases", :realworld => true do
bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
if Bundler.feature_flag.bundler_3_mode? expect(out).to include("Solution found after 6 attempts")
expect(out).to display_total_steps_of(890)
else
expect(out).to display_total_steps_of(891)
end
end end
it "doesn't hang on nix gemfile" do it "doesn't hang on nix gemfile" do
skip "Only for ruby 3.0.1" if RUBY_VERSION != "3.0.1" || RUBY_PLATFORM.include?("darwin") skip "Only for ruby 3.0" unless RUBY_VERSION.start_with?("3.0")
gemfile <<~G gemfile <<~G
source "https://rubygems.org" do source "https://rubygems.org"
gem "addressable"
gem "atk" gem "addressable"
gem "awesome_print" gem "atk"
gem "bacon" gem "awesome_print"
gem "byebug" gem "bacon"
gem "cairo" gem "byebug"
gem "cairo-gobject" gem "cairo"
gem "camping" gem "cairo-gobject"
gem "charlock_holmes" gem "camping"
gem "cld3" gem "charlock_holmes"
gem "cocoapods" gem "cld3"
gem "cocoapods-acknowledgements" gem "cocoapods"
gem "cocoapods-art" gem "cocoapods-acknowledgements"
gem "cocoapods-bin" gem "cocoapods-art"
gem "cocoapods-browser" gem "cocoapods-bin"
gem "cocoapods-bugsnag" gem "cocoapods-browser"
gem "cocoapods-check" gem "cocoapods-bugsnag"
gem "cocoapods-clean" gem "cocoapods-check"
gem "cocoapods-clean_build_phases_scripts" gem "cocoapods-clean"
gem "cocoapods-core" gem "cocoapods-clean_build_phases_scripts"
gem "cocoapods-coverage" gem "cocoapods-core"
gem "cocoapods-deintegrate" gem "cocoapods-coverage"
gem "cocoapods-dependencies" gem "cocoapods-deintegrate"
gem "cocoapods-deploy" gem "cocoapods-dependencies"
gem "cocoapods-downloader" gem "cocoapods-deploy"
gem "cocoapods-expert-difficulty" gem "cocoapods-downloader"
gem "cocoapods-fix-react-native" gem "cocoapods-expert-difficulty"
gem "cocoapods-generate" gem "cocoapods-fix-react-native"
gem "cocoapods-git_url_rewriter" gem "cocoapods-generate"
gem "cocoapods-keys" gem "cocoapods-git_url_rewriter"
gem "cocoapods-no-dev-schemes" gem "cocoapods-keys"
gem "cocoapods-open" gem "cocoapods-no-dev-schemes"
gem "cocoapods-packager" gem "cocoapods-open"
gem "cocoapods-playgrounds" gem "cocoapods-packager"
gem "cocoapods-plugins" gem "cocoapods-playgrounds"
gem "cocoapods-prune-localizations" gem "cocoapods-plugins"
gem "cocoapods-rome" gem "cocoapods-prune-localizations"
gem "cocoapods-search" gem "cocoapods-rome"
gem "cocoapods-sorted-search" gem "cocoapods-search"
gem "cocoapods-static-swift-framework" gem "cocoapods-sorted-search"
gem "cocoapods-stats" gem "cocoapods-static-swift-framework"
gem "cocoapods-tdfire-binary" gem "cocoapods-stats"
gem "cocoapods-testing" gem "cocoapods-tdfire-binary"
gem "cocoapods-trunk" gem "cocoapods-testing"
gem "cocoapods-try" gem "cocoapods-trunk"
gem "cocoapods-try-release-fix" gem "cocoapods-try"
gem "cocoapods-update-if-you-dare" gem "cocoapods-try-release-fix"
gem "cocoapods-whitelist" gem "cocoapods-update-if-you-dare"
gem "cocoapods-wholemodule" gem "cocoapods-whitelist"
gem "coderay" gem "cocoapods-wholemodule"
gem "concurrent-ruby" gem "coderay"
gem "curb" gem "concurrent-ruby"
gem "curses" gem "curb"
gem "daemons" gem "curses"
gem "dep-selector-libgecode" gem "daemons"
gem "digest-sha3" gem "dep-selector-libgecode"
gem "domain_name" gem "digest-sha3"
gem "do_sqlite3" gem "domain_name"
gem "ethon" gem "do_sqlite3"
gem "eventmachine" gem "ethon"
gem "excon" gem "eventmachine"
gem "faraday" gem "excon"
gem "ffi" gem "faraday"
gem "ffi-rzmq-core" gem "ffi"
gem "fog-dnsimple" gem "ffi-rzmq-core"
gem "gdk_pixbuf2" gem "fog-dnsimple"
gem "gio2" gem "gdk_pixbuf2"
gem "gitlab-markup" gem "gio2"
gem "glib2" gem "gitlab-markup"
gem "gpgme" gem "glib2"
gem "gtk2" gem "gpgme"
gem "hashie" gem "gtk2"
gem "highline" gem "hashie"
gem "hike" gem "highline"
gem "hitimes" gem "hike"
gem "hpricot" gem "hitimes"
gem "httpclient" gem "hpricot"
gem "http-cookie" gem "httpclient"
gem "iconv" gem "http-cookie"
gem "idn-ruby" gem "iconv"
gem "jbuilder" gem "idn-ruby"
gem "jekyll" gem "jbuilder"
gem "jmespath" gem "jekyll"
gem "jwt" gem "jmespath"
gem "libv8" gem "jwt"
gem "libxml-ruby" gem "libv8"
gem "magic" gem "libxml-ruby"
gem "markaby" gem "magic"
gem "method_source" gem "markaby"
gem "mini_magick" gem "method_source"
gem "msgpack" gem "mini_magick"
gem "mysql2" gem "msgpack"
gem "ncursesw" gem "mysql2"
gem "netrc" gem "ncursesw"
gem "net-scp" gem "netrc"
gem "net-ssh" gem "net-scp"
gem "nokogiri" gem "net-ssh"
gem "opus-ruby" gem "nokogiri"
gem "ovirt-engine-sdk" gem "opus-ruby"
gem "pango" gem "ovirt-engine-sdk"
gem "patron" gem "pango"
gem "pcaprub" gem "patron"
gem "pg" gem "pcaprub"
gem "pry" gem "pg"
gem "pry-byebug" gem "pry"
gem "pry-doc" gem "pry-byebug"
gem "public_suffix" gem "pry-doc"
gem "puma" gem "public_suffix"
gem "rails" gem "puma"
gem "rainbow" gem "rails"
gem "rbnacl" gem "rainbow"
gem "rb-readline" gem "rbnacl"
gem "re2" gem "rb-readline"
gem "redis" gem "re2"
gem "redis-rack" gem "redis"
gem "rest-client" gem "redis-rack"
gem "rmagick" gem "rest-client"
gem "rpam2" gem "rmagick"
gem "rspec" gem "rpam2"
gem "rubocop" gem "rspec"
gem "rubocop-performance" gem "rubocop"
gem "ruby-libvirt" gem "rubocop-performance"
gem "ruby-lxc" gem "ruby-libvirt"
gem "ruby-progressbar" gem "ruby-lxc"
gem "ruby-terminfo" gem "ruby-progressbar"
gem "ruby-vips" gem "ruby-terminfo"
gem "rubyzip" gem "ruby-vips"
gem "rugged" gem "rubyzip"
gem "sassc" gem "rugged"
gem "scrypt" gem "sassc"
gem "semian" gem "scrypt"
gem "sequel" gem "semian"
gem "sequel_pg" gem "sequel"
gem "simplecov" gem "sequel_pg"
gem "sinatra" gem "simplecov"
gem "slop" gem "sinatra"
gem "snappy" gem "slop"
gem "sqlite3" gem "snappy"
gem "taglib-ruby" gem "sqlite3"
gem "thrift" gem "taglib-ruby"
gem "tilt" gem "thrift"
gem "tiny_tds" gem "tilt"
gem "treetop" gem "tiny_tds"
gem "typhoeus" gem "treetop"
gem "tzinfo" gem "typhoeus"
gem "unf_ext" gem "tzinfo"
gem "uuid4r" gem "unf_ext"
gem "whois" gem "uuid4r"
gem "zookeeper" gem "whois"
end gem "zookeeper"
G G
bundle :lock, :env => { "DEBUG_RESOLVER" => "1" } bundle :lock, :env => { "DEBUG_RESOLVER" => "1" }
if Bundler.feature_flag.bundler_3_mode? expect(out).to include("Solution found after 4 attempts")
expect(out).to display_total_steps_of(1874)
else
expect(out).to display_total_steps_of(1922)
end
end
private
RSpec::Matchers.define :display_total_steps_of do |expected_steps|
match do |out|
out.include?("BUNDLER: Finished resolution (#{expected_steps} steps)")
end
failure_message do |out|
actual_steps = out.scan(/BUNDLER: Finished resolution \((\d+) steps\)/).first.first
"Expected resolution to finish in #{expected_steps} steps, but took #{actual_steps}"
end
end end
end end

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
RSpec.describe "loading dinamically linked library on a bundle exec context", :realworld => true do RSpec.describe "loading dynamically linked library on a bundle exec context", :realworld => true do
it "passes ENV right after argv in memory" do it "passes ENV right after argv in memory" do
create_file "foo.rb", <<~RUBY create_file "foo.rb", <<~RUBY
require 'ffi' require 'ffi'

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
RSpec.describe "github source", :realworld => true do
it "properly fetches PRs" do
install_gemfile <<-G
source "https://rubygems.org"
gem "reline", github: "https://github.com/ruby/reline/pull/488"
G
end
end

View file

@ -28,6 +28,6 @@ RSpec.describe "bundle install with complex dependencies", :realworld => true do
gem 'rspec-rails' gem 'rspec-rails'
G G
expect { bundle "lock" }.to take_less_than(18) # seconds expect { bundle "lock" }.to take_less_than(30) # seconds
end end
end end

View file

@ -155,21 +155,32 @@ RSpec.describe "Resolving platform craziness" do
end end
end end
it "takes the latest ruby gem if the platform specific gem doesn't match the required_ruby_version" do context "when the platform specific gem doesn't match the required_ruby_version" do
@index = build_index do before do
gem "foo", "1.0.0" @index = build_index do
gem "foo", "1.0.0", "x64-mingw32" gem "foo", "1.0.0"
gem "foo", "1.1.0" gem "foo", "1.0.0", "x64-mingw32"
gem "foo", "1.1.0", "x64-mingw32" do |s| gem "foo", "1.1.0"
s.required_ruby_version = [">= 2.0", "< 2.4"] gem "foo", "1.1.0", "x64-mingw32" do |s|
s.required_ruby_version = [">= 2.0", "< 2.4"]
end
gem "Ruby\0", "2.5.1"
end end
gem "Ruby\0", "2.5.1" dep "Ruby\0", "2.5.1"
platforms "x64-mingw32"
end end
dep "foo"
dep "Ruby\0", "2.5.1"
platforms "x64-mingw32"
should_resolve_as %w[foo-1.1.0] it "takes the latest ruby gem" do
dep "foo"
should_resolve_as %w[foo-1.1.0]
end
it "takes the latest ruby gem, even if requirement does not match previous versions with the same ruby requirement" do
dep "foo", "1.1.0"
should_resolve_as %w[foo-1.1.0]
end
end end
it "takes the latest ruby gem with required_ruby_version if the platform specific gem doesn't match the required_ruby_version" do it "takes the latest ruby gem with required_ruby_version if the platform specific gem doesn't match the required_ruby_version" do

View file

@ -168,6 +168,29 @@ RSpec.describe "bundler/inline#gemfile" do
expect(err).to be_empty expect(err).to be_empty
end end
it "installs subdependencies quietly if necessary when the install option is not set" do
build_repo4 do
build_gem "rack" do |s|
s.add_dependency "rackdep"
end
build_gem "rackdep", "1.0.0"
end
script <<-RUBY
gemfile do
source "#{file_uri_for(gem_repo4)}"
gem "rack"
end
require "rackdep"
puts RACKDEP
RUBY
expect(out).to eq("1.0.0")
expect(err).to be_empty
end
it "installs quietly from git if necessary when the install option is not set" do it "installs quietly from git if necessary when the install option is not set" do
build_git "foo", "1.0.0" build_git "foo", "1.0.0"
baz_ref = build_git("baz", "2.0.0").ref_for("HEAD") baz_ref = build_git("baz", "2.0.0").ref_for("HEAD")
@ -436,7 +459,7 @@ RSpec.describe "bundler/inline#gemfile" do
expect(err).to be_empty expect(err).to be_empty
end end
it "when requiring fileutils after does not show redefinition warnings" do it "when requiring fileutils after does not show redefinition warnings", :realworld do
dependency_installer_loads_fileutils = ruby "require 'rubygems/dependency_installer'; puts $LOADED_FEATURES.grep(/fileutils/)", :raise_on_error => false dependency_installer_loads_fileutils = ruby "require 'rubygems/dependency_installer'; puts $LOADED_FEATURES.grep(/fileutils/)", :raise_on_error => false
skip "does not work if rubygems/dependency_installer loads fileutils, which happens until rubygems 3.2.0" unless dependency_installer_loads_fileutils.empty? skip "does not work if rubygems/dependency_installer loads fileutils, which happens until rubygems 3.2.0" unless dependency_installer_loads_fileutils.empty?

View file

@ -91,7 +91,7 @@ RSpec.describe "Self management", :rubygems => ">= 3.3.0.dev", :realworld => tru
expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION) expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION)
end end
it "shows a discreet message if locked bundler does not exist" do it "shows a discrete message if locked bundler does not exist" do
missing_minor ="#{Bundler::VERSION[0]}.999.999" missing_minor ="#{Bundler::VERSION[0]}.999.999"
lockfile_bundled_with(missing_minor) lockfile_bundled_with(missing_minor)

View file

@ -556,12 +556,12 @@ RSpec.describe "Bundler.setup" do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "nonexistant" gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "nonexistent"
G G
bundle %(config set local.rack #{lib_path("local-rack")}) bundle %(config set local.rack #{lib_path("local-rack")})
run "require 'rack'", :raise_on_error => false run "require 'rack'", :raise_on_error => false
expect(err).to match(/is using branch main but Gemfile specifies nonexistant/) expect(err).to match(/is using branch main but Gemfile specifies nonexistent/)
end end
end end

View file

@ -4,6 +4,7 @@ require "net/http"
require_relative "../path" require_relative "../path"
CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes" CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes"
USED_CASSETTES_PATH = "#{Spec::Path.spec_dir}/support/artifice/used_cassettes.txt"
CASSETTE_NAME = ENV.fetch("BUNDLER_SPEC_VCR_CASSETTE_NAME") { "realworld" } CASSETTE_NAME = ENV.fetch("BUNDLER_SPEC_VCR_CASSETTE_NAME") { "realworld" }
class BundlerVCRHTTP < Net::HTTP class BundlerVCRHTTP < Net::HTTP
@ -22,6 +23,10 @@ class BundlerVCRHTTP < Net::HTTP
@__vcr_request_handler = handler @__vcr_request_handler = handler
end end
File.open(USED_CASSETTES_PATH, "a+") do |f|
f.puts request_pair_paths.map {|path| Pathname.new(path).relative_path_from(Spec::Path.source_root).to_s }.join("\n")
end
if recorded_response? if recorded_response?
recorded_response recorded_response
else else
@ -74,27 +79,10 @@ class BundlerVCRHTTP < Net::HTTP
def request_pair_paths def request_pair_paths
%w[request response].map do |kind| %w[request response].map do |kind|
File.join(CASSETTE_PATH, CASSETTE_NAME, file_name_for_key(key + [kind])) File.join(CASSETTE_PATH, CASSETTE_NAME, file_name_for_key(key), kind)
end end
end end
def read_stored_request(path)
contents = File.binread(path)
headers = {}
method = nil
path = nil
contents.lines.grep(/^> /).each do |line|
if line =~ /^> (GET|HEAD|POST|PATCH|PUT|DELETE) (.*)/
method = $1
path = $2.strip
elsif line =~ /^> (.*?): (.*)/
headers[$1] = $2
end
end
body = contents =~ /^([^>].*)/m && $1
Net::HTTP.const_get(method.capitalize).new(path, headers).tap {|r| r.body = body if body }
end
def request_to_string(request) def request_to_string(request)
request_string = [] request_string = []
request_string << "> #{request.method.upcase} #{request.path}" request_string << "> #{request.method.upcase} #{request.path}"

View file

@ -298,10 +298,6 @@ module Spec
end end
end end
def build_dep(name, requirements = Gem::Requirement.default, type = :runtime)
Bundler::Dependency.new(name, :version => requirements)
end
def build_lib(name, *args, &blk) def build_lib(name, *args, &blk)
build_with(LibBuilder, name, args, &blk) build_with(LibBuilder, name, args, &blk)
end end

View file

@ -18,22 +18,17 @@ module Spec
@platforms ||= ["ruby"] @platforms ||= ["ruby"]
default_source = instance_double("Bundler::Source::Rubygems", :specs => @index, :to_s => "locally install gems") default_source = instance_double("Bundler::Source::Rubygems", :specs => @index, :to_s => "locally install gems")
source_requirements = { :default => default_source } source_requirements = { :default => default_source }
args[0] ||= Bundler::SpecSet.new([]) # base base = args[0] || Bundler::SpecSet.new([])
args[0].each {|ls| ls.source = default_source } base.each {|ls| ls.source = default_source }
args[1] ||= Bundler::GemVersionPromoter.new # gem_version_promoter gem_version_promoter = args[1] || Bundler::GemVersionPromoter.new
args[2] ||= [] # additional_base_requirements originally_locked = args[2] || Bundler::SpecSet.new([])
originally_locked = args[3] || Bundler::SpecSet.new([]) unlock = args[3] || []
unlock = args[4] || []
packages = Hash.new do |h, k|
h[k] = Bundler::Resolver::Package.new(k, @platforms, originally_locked, unlock)
end
@deps.each do |d| @deps.each do |d|
name = d.name name = d.name
platforms = d.gem_platforms(@platforms)
source_requirements[name] = d.source = default_source source_requirements[name] = d.source = default_source
packages[name] = Bundler::Resolver::Package.new(name, platforms, originally_locked, unlock, :dependency => d)
end end
Bundler::Resolver.new(source_requirements, *args[0..2]).start(@deps, packages) packages = Bundler::Resolver::Base.new(source_requirements, @deps, base, @platforms, :locked_specs => originally_locked, :unlock => unlock)
Bundler::Resolver.new(packages, gem_version_promoter).start
end end
def should_not_resolve def should_not_resolve
@ -71,7 +66,7 @@ module Spec
s.level = opts.first s.level = opts.first
s.strict = opts.include?(:strict) s.strict = opts.include?(:strict)
end end
should_resolve_and_include specs, [@base, search, [], @locked, unlock] should_resolve_and_include specs, [@base, search, @locked, unlock]
end end
def an_awesome_index def an_awesome_index

View file

@ -126,6 +126,46 @@ class TestGemCommandManager < Gem::TestCase
@command_manager.unregister_command :crash @command_manager.unregister_command :crash
end end
def test_process_args_with_c_flag
custom_start_point = File.join @tempdir, "nice_folder"
FileUtils.mkdir_p custom_start_point
execution_path = nil
use_ui @ui do
@command_manager[:install].when_invoked do
execution_path = Dir.pwd
true
end
@command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local]
end
assert_equal custom_start_point, execution_path
end
def test_process_args_with_c_flag_without_path
use_ui @ui do
assert_raise Gem::MockGemUi::TermError do
@command_manager.process_args %w[-C install net-scp-4.0.0.gem --local]
end
end
assert_match(/install isn't a directory./i, @ui.error)
end
def test_process_args_with_c_flag_path_not_found
custom_start_point = File.join @tempdir, "nice_folder"
FileUtils.mkdir_p custom_start_point
custom_start_point.tr!("_", "-")
use_ui @ui do
assert_raise Gem::MockGemUi::TermError do
@command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local]
end
end
assert_match(/#{custom_start_point} isn't a directory./i, @ui.error)
end
def test_process_args_bad_arg def test_process_args_bad_arg
use_ui @ui do use_ui @ui do
assert_raise Gem::MockGemUi::TermError do assert_raise Gem::MockGemUi::TermError do

View file

@ -41,6 +41,16 @@ class TestGemCommandsBuildCommand < Gem::TestCase
assert_includes Gem.platforms, Gem::Platform.local assert_includes Gem.platforms, Gem::Platform.local
end end
def test_handle_deprecated_options
use_ui @ui do
@cmd.handle_options %w[-C ./test/dir]
end
assert_equal "WARNING: The \"-C\" option has been deprecated and will be removed in Rubygems 4.0. " \
"-C is a global flag now. Use `gem -C PATH build GEMSPEC_FILE [options]` instead\n",
@ui.error
end
def test_options_filename def test_options_filename
gemspec_file = File.join(@tempdir, @gem.spec_name) gemspec_file = File.join(@tempdir, @gem.spec_name)

View file

@ -151,18 +151,18 @@ dependencies = [
[[package]] [[package]]
name = "rb-sys" name = "rb-sys"
version = "0.9.52" version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fffdb0162fc4cc1b6509b2d9b32a75f7e7ed392f58bde639e0c33b23e74b97" checksum = "b3277448b8eee18de8bedb18883ae02dcd60d47922ddfc6ab408def77da0a9b4"
dependencies = [ dependencies = [
"rb-sys-build", "rb-sys-build",
] ]
[[package]] [[package]]
name = "rb-sys-build" name = "rb-sys-build"
version = "0.9.52" version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85d1a236755f879fc155d16d9ba4cd3b1975fd52ef6a28113702ae3881b73c03" checksum = "c9baae802c93180af02cccb21819589d109070f8e28e14e7070a9ffdeca9b464"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"regex", "regex",

View file

@ -7,4 +7,4 @@ edition = "2021"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
rb-sys = "0.9.52" rb-sys = "0.9.54"

View file

@ -144,18 +144,18 @@ dependencies = [
[[package]] [[package]]
name = "rb-sys" name = "rb-sys"
version = "0.9.52" version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02fffdb0162fc4cc1b6509b2d9b32a75f7e7ed392f58bde639e0c33b23e74b97" checksum = "b3277448b8eee18de8bedb18883ae02dcd60d47922ddfc6ab408def77da0a9b4"
dependencies = [ dependencies = [
"rb-sys-build", "rb-sys-build",
] ]
[[package]] [[package]]
name = "rb-sys-build" name = "rb-sys-build"
version = "0.9.52" version = "0.9.54"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85d1a236755f879fc155d16d9ba4cd3b1975fd52ef6a28113702ae3881b73c03" checksum = "c9baae802c93180af02cccb21819589d109070f8e28e14e7070a9ffdeca9b464"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"regex", "regex",

View file

@ -7,4 +7,4 @@ edition = "2021"
crate-type = ["cdylib"] crate-type = ["cdylib"]
[dependencies] [dependencies]
rb-sys = "0.9.52" rb-sys = "0.9.54"

View file

@ -1828,7 +1828,7 @@ gem 'other', version
installer = Gem::Installer.at( installer = Gem::Installer.at(
gem_with_ill_formated_platform, gem_with_ill_formated_platform,
:install_dir => @gem_home, :install_dir => @gemhome,
:user_install => false, :user_install => false,
:force => true :force => true
) )

View file

@ -275,7 +275,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set Gem::Resolver::LockSet === set
end end
refute lockfile_set, "fount a LockSet" refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set| git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set Gem::Resolver::GitSet === set
@ -318,7 +318,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set Gem::Resolver::LockSet === set
end end
refute lockfile_set, "fount a LockSet" refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set| git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set Gem::Resolver::GitSet === set
@ -355,7 +355,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set Gem::Resolver::LockSet === set
end end
refute lockfile_set, "fount a LockSet" refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set| git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set Gem::Resolver::GitSet === set
@ -392,7 +392,7 @@ DEPENDENCIES
Gem::Resolver::LockSet === set Gem::Resolver::LockSet === set
end end
refute lockfile_set, "fount a LockSet" refute lockfile_set, "found a LockSet"
git_set = @set.sets.find do |set| git_set = @set.sets.find do |set|
Gem::Resolver::GitSet === set Gem::Resolver::GitSet === set

View file

@ -680,8 +680,7 @@ class TestGemRequire < Gem::TestCase
require "json" require "json"
RUBY RUBY
out = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, "-e", cmd) out = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, "-e", cmd)
puts out assert_predicate $?, :success?, "Require failed due to #{out}"
assert $?.success?
end end
private private

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