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

Merge prepare version of Bundler 2.2.0

This commit is contained in:
Hiroshi SHIBATA 2020-12-08 16:36:29 +09:00
parent 4aca77edde
commit 473f9d2df0
Notes: git 2020-12-08 17:30:30 +09:00
135 changed files with 1326 additions and 901 deletions

View file

@ -602,6 +602,10 @@ EOF
reset_rubygems! reset_rubygems!
end end
def reset_settings!
@settings = nil
end
def reset_paths! def reset_paths!
@bin_path = nil @bin_path = nil
@bundler_major_version = nil @bundler_major_version = nil

View file

@ -57,7 +57,7 @@ module Bundler
custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile] custom_gemfile = options[:gemfile] || Bundler.settings[:gemfile]
if custom_gemfile && !custom_gemfile.empty? if custom_gemfile && !custom_gemfile.empty?
Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile) Bundler::SharedHelpers.set_env "BUNDLE_GEMFILE", File.expand_path(custom_gemfile)
Bundler.reset_paths! Bundler.reset_settings!
end end
Bundler.settings.set_command_option_if_given :retry, options[:retry] Bundler.settings.set_command_option_if_given :retry, options[:retry]
@ -134,7 +134,8 @@ module Bundler
if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+} if Bundler.which("man") && man_path !~ %r{^file:/.+!/META-INF/jruby.home/.+}
Kernel.exec "man #{man_page}" Kernel.exec "man #{man_page}"
else else
puts File.read("#{File.dirname(man_page)}/#{File.basename(man_page)}.ronn") fallback_man_path = File.expand_path("../man", __FILE__)
puts File.read("#{fallback_man_path}/#{File.basename(man_page)}.ronn")
end end
elsif command_path = Bundler.which("bundler-#{cli}") elsif command_path = Bundler.which("bundler-#{cli}")
Kernel.exec(command_path, "--help") Kernel.exec(command_path, "--help")
@ -380,6 +381,8 @@ module Bundler
"Make binstubs that can work without the Bundler runtime" "Make binstubs that can work without the Bundler runtime"
method_option "all", :type => :boolean, :banner => method_option "all", :type => :boolean, :banner =>
"Install binstubs for all gems" "Install binstubs for all gems"
method_option "all-platforms", :type => :boolean, :default => false, :banner =>
"Install binstubs for all platforms"
def binstubs(*gems) def binstubs(*gems)
require_relative "cli/binstubs" require_relative "cli/binstubs"
Binstubs.new(options, gems).run Binstubs.new(options, gems).run

View file

@ -16,7 +16,11 @@ module Bundler
Bundler.settings.set_command_option_if_given :shebang, options["shebang"] Bundler.settings.set_command_option_if_given :shebang, options["shebang"]
installer = Installer.new(Bundler.root, Bundler.definition) installer = Installer.new(Bundler.root, Bundler.definition)
installer_opts = { :force => options[:force], :binstubs_cmd => true } installer_opts = {
:force => options[:force],
:binstubs_cmd => true,
:all_platforms => options["all-platforms"],
}
if options[:all] if options[:all]
raise InvalidOption, "Cannot specify --all with specific gems" unless gems.empty? raise InvalidOption, "Cannot specify --all with specific gems" unless gems.empty?
@ -38,7 +42,7 @@ module Bundler
if options[:standalone] if options[:standalone]
next Bundler.ui.warn("Sorry, Bundler can only be run via RubyGems.") if gem_name == "bundler" next Bundler.ui.warn("Sorry, Bundler can only be run via RubyGems.") if gem_name == "bundler"
Bundler.settings.temporary(:path => (Bundler.settings[:path] || Bundler.root)) do Bundler.settings.temporary(:path => (Bundler.settings[:path] || Bundler.root)) do
installer.generate_standalone_bundler_executable_stubs(spec) installer.generate_standalone_bundler_executable_stubs(spec, installer_opts)
end end
else else
installer.generate_bundler_executable_stubs(spec, installer_opts) installer.generate_bundler_executable_stubs(spec, installer_opts)

View file

@ -63,10 +63,10 @@ module Bundler
Kernel.load(file) Kernel.load(file)
rescue SystemExit, SignalException rescue SystemExit, SignalException
raise raise
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception # rubocop:disable Lint/RescueException
Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})" Bundler.ui.error "bundler: failed to load command: #{cmd} (#{file})"
backtrace = e.backtrace ? e.backtrace.take_while {|bt| !bt.start_with?(__FILE__) } : [] Bundler::FriendlyErrors.disable!
abort "#{e.class}: #{e.message}\n #{backtrace.join("\n ")}" raise
end end
def process_title(file, args) def process_title(file, args)

View file

@ -76,8 +76,6 @@ module Bundler
next unless gems.empty? || gems.include?(current_spec.name) next unless gems.empty? || gems.include?(current_spec.name)
active_spec = retrieve_active_spec(definition, current_spec) active_spec = retrieve_active_spec(definition, current_spec)
next unless active_spec
next unless filter_options_patch.empty? || update_present_via_semver_portions(current_spec, active_spec, options) next unless filter_options_patch.empty? || update_present_via_semver_portions(current_spec, active_spec, options)
gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version) gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
@ -146,8 +144,6 @@ module Bundler
end end
def retrieve_active_spec(definition, current_spec) def retrieve_active_spec(definition, current_spec)
return unless current_spec.match_platform(Bundler.local_platform)
if strict if strict
active_spec = definition.find_resolved_spec(current_spec) active_spec = definition.find_resolved_spec(current_spec)
else else
@ -233,6 +229,8 @@ module Bundler
end end
def update_present_via_semver_portions(current_spec, active_spec, options) def update_present_via_semver_portions(current_spec, active_spec, options)
return false if active_spec.nil?
current_major = current_spec.version.segments.first current_major = current_spec.version.segments.first
active_major = active_spec.version.segments.first active_major = active_spec.version.segments.first

View file

@ -22,13 +22,13 @@ module Bundler
def initialize(fetcher) def initialize(fetcher)
@fetcher = fetcher @fetcher = fetcher
require "tmpdir" require_relative "../vendored_tmpdir"
end end
def update(local_path, remote_path, retrying = nil) def update(local_path, remote_path, retrying = nil)
headers = {} headers = {}
Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir| Bundler::Dir.mktmpdir("bundler-compact-index-") do |local_temp_dir|
local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename) local_temp_path = Pathname.new(local_temp_dir).join(local_path.basename)
# first try to fetch any new bytes on the existing file # first try to fetch any new bytes on the existing file
@ -66,8 +66,8 @@ module Bundler
end end
end end
response_etag = (response["ETag"] || "").gsub(%r{\AW/}, "") etag = (response["ETag"] || "").gsub(%r{\AW/}, "")
if etag_for(local_temp_path) == response_etag if etag.length.zero? || etag_for(local_temp_path) == etag
SharedHelpers.filesystem_access(local_path) do SharedHelpers.filesystem_access(local_path) do
FileUtils.mv(local_temp_path, local_path) FileUtils.mv(local_temp_path, local_path)
end end
@ -75,7 +75,7 @@ module Bundler
end end
if retrying if retrying
raise MisMatchedChecksumError.new(remote_path, response_etag, etag_for(local_temp_path)) raise MisMatchedChecksumError.new(remote_path, etag, etag_for(local_temp_path))
end end
update(local_path, remote_path, :retrying) update(local_path, remote_path, :retrying)

View file

@ -118,7 +118,7 @@ module Bundler
end end
@unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version) @unlocking ||= @unlock[:ruby] ||= (!@locked_ruby_version ^ !@ruby_version)
add_platforms unless 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
@ -547,17 +547,12 @@ module Bundler
private private
def add_platforms def add_current_platform
(@dependencies.flat_map(&:expanded_platforms) + current_platforms).uniq.each do |platform| current_platforms.each {|platform| add_platform(platform) }
add_platform(platform)
end
end end
def current_platforms def current_platforms
[].tap do |platforms| [local_platform, generic_local_platform].uniq
platforms << local_platform if Bundler.feature_flag.specific_platform?
platforms << generic_local_platform
end
end end
def change_reason def change_reason

View file

@ -105,7 +105,7 @@ module Bundler
out << [" User Home", Gem.user_home] out << [" User Home", Gem.user_home]
out << [" User Path", Gem.user_dir] out << [" User Path", Gem.user_dir]
out << [" Bin Dir", Gem.bindir] out << [" Bin Dir", Gem.bindir]
if defined?(OpenSSL) if defined?(OpenSSL::SSL)
out << ["OpenSSL"] out << ["OpenSSL"]
out << [" Compiled", OpenSSL::OPENSSL_VERSION] if defined?(OpenSSL::OPENSSL_VERSION) out << [" Compiled", OpenSSL::OPENSSL_VERSION] if defined?(OpenSSL::OPENSSL_VERSION)
out << [" Loaded", OpenSSL::OPENSSL_LIBRARY_VERSION] if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION) out << [" Loaded", OpenSSL::OPENSSL_LIBRARY_VERSION] if defined?(OpenSSL::OPENSSL_LIBRARY_VERSION)

View file

@ -41,7 +41,6 @@ module Bundler
settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") } settings_flag(:plugins) { @bundler_version >= Gem::Version.new("1.14") }
settings_flag(:print_only_version_number) { bundler_3_mode? } settings_flag(:print_only_version_number) { bundler_3_mode? }
settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? } settings_flag(:setup_makes_kernel_gem_public) { !bundler_3_mode? }
settings_flag(:specific_platform) { bundler_3_mode? }
settings_flag(:suppress_install_using_messages) { bundler_3_mode? } settings_flag(:suppress_install_using_messages) { bundler_3_mode? }
settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? } settings_flag(:unlock_source_unlocks_spec) { !bundler_3_mode? }
settings_flag(:update_requires_all_flag) { bundler_4_mode? } settings_flag(:update_requires_all_flag) { bundler_4_mode? }

View file

@ -8,7 +8,7 @@ module Bundler
class Index < Base class Index < Base
def specs(_gem_names) def specs(_gem_names)
Bundler.rubygems.fetch_all_remote_specs(remote) Bundler.rubygems.fetch_all_remote_specs(remote)
rescue Gem::RemoteFetcher::FetchError, OpenSSL::SSL::SSLError, Net::HTTPFatalError => e rescue Gem::RemoteFetcher::FetchError => e
case e.message case e.message
when /certificate verify failed/ when /certificate verify failed/
raise CertificateFailureError.new(display_uri) raise CertificateFailureError.new(display_uri)
@ -19,8 +19,7 @@ module Bundler
raise BadAuthenticationError, remote_uri if remote_uri.userinfo raise BadAuthenticationError, remote_uri if remote_uri.userinfo
raise AuthenticationRequiredError, remote_uri raise AuthenticationRequiredError, remote_uri
else else
Bundler.ui.trace e raise HTTPError, "Could not fetch specs from #{display_uri} due to underlying error <#{e.message}>"
raise HTTPError, "Could not fetch specs from #{display_uri}"
end end
end end

View file

@ -6,6 +6,18 @@ module Bundler
module FriendlyErrors module FriendlyErrors
module_function module_function
def enable!
@disabled = false
end
def disabled?
@disabled
end
def disable!
@disabled = true
end
def log_error(error) def log_error(error)
case error case error
when YamlSyntaxError when YamlSyntaxError
@ -114,10 +126,13 @@ module Bundler
end end
def self.with_friendly_errors def self.with_friendly_errors
FriendlyErrors.enable!
yield yield
rescue SignalException rescue SignalException
raise raise
rescue Exception => e # rubocop:disable Lint/RescueException rescue Exception => e # rubocop:disable Lint/RescueException
raise if FriendlyErrors.disabled?
FriendlyErrors.log_error(e) FriendlyErrors.log_error(e)
exit FriendlyErrors.exit_status(e) exit FriendlyErrors.exit_status(e)
end end

View file

@ -195,7 +195,11 @@ module Bundler
if base # allow all platforms when searching from a lockfile if base # allow all platforms when searching from a lockfile
dependency.matches_spec?(spec) dependency.matches_spec?(spec)
else else
dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform) if Gem::Platform.respond_to? :match_spec?
dependency.matches_spec?(spec) && Gem::Platform.match_spec?(spec)
else
dependency.matches_spec?(spec) && Gem::Platform.match(spec.platform)
end
end end
end end

View file

@ -179,11 +179,11 @@ module Bundler
# @param [Pathname] gemfile_path The Gemfile from which to remove dependencies. # @param [Pathname] gemfile_path The Gemfile from which to remove dependencies.
def remove_gems_from_gemfile(gems, gemfile_path) def remove_gems_from_gemfile(gems, gemfile_path)
patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/ patterns = /gem\s+(['"])#{Regexp.union(gems)}\1|gem\s*\((['"])#{Regexp.union(gems)}\2\)/
new_gemfile = [] new_gemfile = []
multiline_removal = false multiline_removal = false
IO.readlines(gemfile_path).each do |line| IO.readlines(gemfile_path).each do |line|
if line.match(patterns) match_data = line.match(patterns)
if match_data && is_not_within_comment?(line, match_data)
multiline_removal = line.rstrip.end_with?(",") multiline_removal = line.rstrip.end_with?(",")
# skip lines which match the regex # skip lines which match the regex
next next
@ -207,6 +207,13 @@ module Bundler
new_gemfile.join.chomp new_gemfile.join.chomp
end end
# @param [String] line Individual line of gemfile content.
# @param [MatchData] match_data Data about Regex match.
def is_not_within_comment?(line, match_data)
match_start_index = match_data.offset(0).first
!line[0..match_start_index].include?("#")
end
# @param [Array] gemfile Array of gemfile contents. # @param [Array] gemfile Array of gemfile contents.
# @param [String] block_name Name of block name to look for. # @param [String] block_name Name of block name to look for.
def remove_nested_blocks(gemfile, block_name) def remove_nested_blocks(gemfile, block_name)

View file

@ -1,6 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require "erb"
require "rubygems/dependency_installer" require "rubygems/dependency_installer"
require_relative "worker" require_relative "worker"
require_relative "installer/parallel_installer" require_relative "installer/parallel_installer"
@ -136,6 +135,7 @@ module Bundler
end end
mode = Bundler::WINDOWS ? "wb:UTF-8" : "w" mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
require "erb"
content = if RUBY_VERSION >= "2.6" content = if RUBY_VERSION >= "2.6"
ERB.new(template, :trim_mode => "-").result(binding) ERB.new(template, :trim_mode => "-").result(binding)
else else
@ -143,7 +143,7 @@ module Bundler
end end
File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask) File.write(binstub_path, content, :mode => mode, :perm => 0o777 & ~File.umask)
if Bundler::WINDOWS if Bundler::WINDOWS || options[:all_platforms]
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n" prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
File.write("#{binstub_path}.cmd", prefix + content, :mode => mode) File.write("#{binstub_path}.cmd", prefix + content, :mode => mode)
end end
@ -164,7 +164,7 @@ module Bundler
end end
end end
def generate_standalone_bundler_executable_stubs(spec) def generate_standalone_bundler_executable_stubs(spec, options = {})
# double-assignment to avoid warnings about variables that will be used by ERB # double-assignment to avoid warnings about variables that will be used by ERB
bin_path = Bundler.bin_path bin_path = Bundler.bin_path
unless path = Bundler.settings[:path] unless path = Bundler.settings[:path]
@ -182,6 +182,7 @@ module Bundler
executable_path = executable_path executable_path = executable_path
mode = Bundler::WINDOWS ? "wb:UTF-8" : "w" mode = Bundler::WINDOWS ? "wb:UTF-8" : "w"
require "erb"
content = if RUBY_VERSION >= "2.6" content = if RUBY_VERSION >= "2.6"
ERB.new(template, :trim_mode => "-").result(binding) ERB.new(template, :trim_mode => "-").result(binding)
else else
@ -189,7 +190,7 @@ module Bundler
end end
File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755) File.write("#{bin_path}/#{executable}", content, :mode => mode, :perm => 0o755)
if Bundler::WINDOWS if Bundler::WINDOWS || options[:all_platforms]
prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n" prefix = "@ruby -x \"%~f0\" %*\n@exit /b %ERRORLEVEL%\n\n"
File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode) File.write("#{bin_path}/#{executable}.cmd", prefix + content, :mode => mode)
end end
@ -243,6 +244,7 @@ module Bundler
end end
end.flatten end.flatten
Bundler.rubygems.load_plugin_files(path_plugin_files) Bundler.rubygems.load_plugin_files(path_plugin_files)
Bundler.rubygems.load_env_plugins
end end
def ensure_specs_are_compatible! def ensure_specs_are_compatible!
@ -297,7 +299,7 @@ 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)
if !@definition.unlocking? && !options["force"] && !options["all-platforms"] && !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

View file

@ -79,19 +79,17 @@ module Bundler
@specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name @specification = if source.is_a?(Source::Gemspec) && source.gemspec.name == name
source.gemspec.tap {|s| s.source = source } source.gemspec.tap {|s| s.source = source }
else else
search_object = Bundler.feature_flag.specific_platform? || Bundler.settings[:force_ruby_platform] ? self : Dependency.new(name, version) search_object = if source.is_a?(Source::Path)
Dependency.new(name, version)
else
self
end
platform_object = Gem::Platform.new(platform) platform_object = Gem::Platform.new(platform)
candidates = source.specs.search(search_object) candidates = source.specs.search(search_object)
same_platform_candidates = candidates.select do |spec| same_platform_candidates = candidates.select do |spec|
MatchPlatform.platforms_match?(spec.platform, platform_object) MatchPlatform.platforms_match?(spec.platform, platform_object)
end end
search = same_platform_candidates.last || candidates.last search = same_platform_candidates.last || candidates.last
if search && Gem::Platform.new(search.platform) != platform_object && !search.runtime_dependencies.-(dependencies.reject {|d| d.type == :development }).empty?
Bundler.ui.warn "Unable to use the platform-specific (#{search.platform}) version of #{name} (#{version}) " \
"because it has different dependencies from the #{platform} version. " \
"To use the platform-specific version of the gem, run `bundle config set --local specific_platform true` and install again."
search = source.specs.search(self).last
end
search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification)) search.dependencies = dependencies if search && (search.is_a?(RemoteSpecification) || search.is_a?(EndpointSpecification))
search search
end end

View file

@ -0,0 +1 @@
# Ignore all files in this directory

View file

@ -250,14 +250,6 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
be changed in the next major version. be changed in the next major version.
* `silence_root_warning` (`BUNDLE_SILENCE_ROOT_WARNING`): * `silence_root_warning` (`BUNDLE_SILENCE_ROOT_WARNING`):
Silence the warning Bundler prints when installing gems as root. Silence the warning Bundler prints when installing gems as root.
* `specific_platform` (`BUNDLE_SPECIFIC_PLATFORM`):
Allow bundler to resolve for the specific running platform and store it in
the lockfile, instead of only using a generic platform.
A specific platform is the exact platform triple reported by
`Gem::Platform.local`, such as `x86_64-darwin-16` or `universal-java-1.8`.
On the other hand, generic platforms are those such as `ruby`, `mswin`, or
`java`. In this example, `x86_64-darwin-16` would map to `ruby` and
`universal-java-1.8` to `java`.
* `ssl_ca_cert` (`BUNDLE_SSL_CA_CERT`): * `ssl_ca_cert` (`BUNDLE_SSL_CA_CERT`):
Path to a designated CA certificate file or folder containing multiple Path to a designated CA certificate file or folder containing multiple
certificates for trusted CAs in PEM format. certificates for trusted CAs in PEM format.
@ -371,7 +363,7 @@ Or you can set the credentials as an environment variable like this:
For gems with a git source with HTTP(S) URL you can specify credentials like so: For gems with a git source with HTTP(S) URL you can specify credentials like so:
bundle config set --global https://github.com/bundler/bundler.git username:password bundle config set --global https://github.com/rubygems/rubygems.git username:password
Or you can set the credentials as an environment variable like so: Or you can set the credentials as an environment variable like so:

View file

@ -105,7 +105,7 @@ automatically and that requires `bundler` to silently remember them. Since
* `--local`: * `--local`:
Do not attempt to connect to `rubygems.org`. Instead, Bundler will use the Do not attempt to connect to `rubygems.org`. Instead, Bundler will use the
gems already present in Rubygems' cache or in `vendor/cache`. Note that if a gems already present in Rubygems' cache or in `vendor/cache`. Note that if an
appropriate platform-specific gem exists on `rubygems.org` it will not be appropriate platform-specific gem exists on `rubygems.org` it will not be
found. found.

View file

@ -260,7 +260,7 @@ module Bundler
end end
def to_s def to_s
"plugin source for #{options[:type]} with uri #{uri}" "plugin source for #{@type} with uri #{@uri}"
end end
# Note: Do not override if you don't know what you are doing. # Note: Do not override if you don't know what you are doing.

View file

@ -10,7 +10,7 @@ module Bundler
# So that we don't have to override all there methods to dummy ones # So that we don't have to override all there methods to dummy ones
# explicitly. # explicitly.
# They will be handled by method_missing # They will be handled by method_missing
[:gemspec, :gem, :path, :install_if, :platforms, :env].each {|m| undef_method m } [:gemspec, :gem, :install_if, :platforms, :env].each {|m| undef_method m }
# This lists the plugins that was added automatically and not specified by # This lists the plugins that was added automatically and not specified by
# the user. # the user.

View file

@ -158,9 +158,8 @@ module Bundler
# spec group. # spec group.
sg_ruby = sg.copy_for(Gem::Platform::RUBY) sg_ruby = sg.copy_for(Gem::Platform::RUBY)
selected_sgs << sg_ruby if sg_ruby selected_sgs << sg_ruby if sg_ruby
all_platforms = @platforms + [platform]
next if all_platforms.to_a == [Gem::Platform::RUBY]
sg_all_platforms = nil sg_all_platforms = nil
all_platforms = @platforms + [platform]
self.class.sort_platforms(all_platforms).reverse_each do |other_platform| self.class.sort_platforms(all_platforms).reverse_each do |other_platform|
if sg_all_platforms.nil? if sg_all_platforms.nil?
sg_all_platforms = sg.copy_for(other_platform) sg_all_platforms = sg.copy_for(other_platform)
@ -302,7 +301,7 @@ module Bundler
versions_with_platforms = specs.map {|s| [s.version, s.platform] } versions_with_platforms = specs.map {|s| [s.version, s.platform] }
message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n") message = String.new("Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in #{source}#{cache_message}.\n")
message << if versions_with_platforms.any? message << if versions_with_platforms.any?
"The source contains '#{name}' at: #{formatted_versions_with_platforms(versions_with_platforms)}" "The source contains the following versions of '#{name}': #{formatted_versions_with_platforms(versions_with_platforms)}"
else else
"The source does not contain any versions of '#{name}'" "The source does not contain any versions of '#{name}'"
end end

View file

@ -227,6 +227,10 @@ module Bundler
Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files) Gem.load_plugin_files(files) if Gem.respond_to?(:load_plugin_files)
end end
def load_env_plugins
Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)
end
def ui=(obj) def ui=(obj)
Gem::DefaultUserInteraction.ui = obj Gem::DefaultUserInteraction.ui = obj
end end

View file

@ -42,7 +42,6 @@ module Bundler
setup_makes_kernel_gem_public setup_makes_kernel_gem_public
silence_deprecations silence_deprecations
silence_root_warning silence_root_warning
specific_platform
suppress_install_using_messages suppress_install_using_messages
unlock_source_unlocks_spec unlock_source_unlocks_spec
update_requires_all_flag update_requires_all_flag

View file

@ -118,7 +118,7 @@ module Bundler
git_retry %(clone --no-checkout --quiet "#{path}" "#{destination}") git_retry %(clone --no-checkout --quiet "#{path}" "#{destination}")
File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination) File.chmod(((File.stat(destination).mode | 0o777) & ~File.umask), destination)
rescue Errno::EEXIST => e rescue Errno::EEXIST => e
file_path = e.message[%r{.*?(/.*)}, 1] file_path = e.message[%r{.*?((?:[a-zA-Z]:)?/.*)}, 1]
raise GitError, "Bundler could not install a gem because it needs to " \ raise GitError, "Bundler could not install a gem because it needs to " \
"create a directory, but a file exists - #{file_path}. Please delete " \ "create a directory, but a file exists - #{file_path}. Please delete " \
"this file and try again." "this file and try again."

View file

@ -100,6 +100,7 @@ module Bundler
@specs.map do |s| @specs.map do |s|
next s unless s.is_a?(LazySpecification) next s unless s.is_a?(LazySpecification)
s.source.dependency_names = names if s.source.respond_to?(:dependency_names=) s.source.dependency_names = names if s.source.respond_to?(:dependency_names=)
s.source.remote!
spec = s.__materialize__ spec = s.__materialize__
raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec raise GemNotFound, "Could not find #{s.full_name} in any of the sources" unless spec
spec spec

View file

@ -33,7 +33,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
## Contributing ## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).<% end %> Bug reports and pull requests are welcome on GitHub at https://github.com/<%= config[:github_username] %>/<%= config[:name] %>.<% if config[:coc] %> This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).<% end %>
<% if config[:mit] -%> <% if config[:mit] -%>
## License ## License

View file

@ -1,8 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
require "<%= config[:namespaced_path] %>/version" require_relative "<%= File.basename(config[:namespaced_path]) %>/version"
<%- if config[:ext] -%> <%- if config[:ext] -%>
require "<%= config[:namespaced_path] %>/<%= config[:underscored_name] %>" require_relative "<%= File.basename(config[:namespaced_path]) %>/<%= config[:underscored_name] %>"
<%- end -%> <%- end -%>
<%- config[:constant_array].each_with_index do |c, i| -%> <%- config[:constant_array].each_with_index do |c, i| -%>

View file

@ -33,4 +33,10 @@ Gem::Specification.new do |spec|
<%- if config[:ext] -%> <%- if config[:ext] -%>
spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"] spec.extensions = ["ext/<%= config[:underscored_name] %>/extconf.rb"]
<%- end -%> <%- end -%>
# Uncomment to register a new dependency of your gem
# spec.add_dependency "example-gem", "~> 1.0"
# For more information and examples about making a new gem, checkout our
# guide at: https://bundler.io/guides/creating_gem.html
end end

View file

@ -8,6 +8,8 @@ module Bundler
return uri_to_anonymize if uri_to_anonymize.nil? return uri_to_anonymize if uri_to_anonymize.nil?
uri = uri_to_anonymize.dup uri = uri_to_anonymize.dup
if uri.is_a?(String) if uri.is_a?(String)
return uri if File.exist?(uri)
require_relative "vendored_uri" require_relative "vendored_uri"
uri = Bundler::URI(uri) uri = Bundler::URI(uri)
end end

View file

@ -1,6 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require_relative 'molinillo/compatibility'
require_relative 'molinillo/gem_metadata' require_relative 'molinillo/gem_metadata'
require_relative 'molinillo/errors' require_relative 'molinillo/errors'
require_relative 'molinillo/resolver' require_relative 'molinillo/resolver'

View file

@ -1,26 +0,0 @@
# frozen_string_literal: true
module Bundler::Molinillo
# Hacks needed for old Ruby versions.
module Compatibility
module_function
if [].respond_to?(:flat_map)
# Flat map
# @param [Enumerable] enum an enumerable object
# @block the block to flat-map with
# @return The enum, flat-mapped
def flat_map(enum, &blk)
enum.flat_map(&blk)
end
else
# Flat map
# @param [Enumerable] enum an enumerable object
# @block the block to flat-map with
# @return The enum, flat-mapped
def flat_map(enum, &blk)
enum.map(&blk).flatten(1)
end
end
end
end

View file

@ -124,6 +124,7 @@ module Bundler::Molinillo
dot.join("\n") dot.join("\n")
end end
# @param [DependencyGraph] other
# @return [Boolean] whether the two dependency graphs are equal, determined # @return [Boolean] whether the two dependency graphs are equal, determined
# by a recursive traversal of each {#root_vertices} and its # by a recursive traversal of each {#root_vertices} and its
# {Vertex#successors} # {Vertex#successors}
@ -190,7 +191,7 @@ module Bundler::Molinillo
# @return [Edge] the added edge # @return [Edge] the added edge
def add_edge(origin, destination, requirement) def add_edge(origin, destination, requirement)
if destination.path_to?(origin) if destination.path_to?(origin)
raise CircularDependencyError.new([origin, destination]) raise CircularDependencyError.new(path(destination, origin))
end end
add_edge_no_circular(origin, destination, requirement) add_edge_no_circular(origin, destination, requirement)
end end
@ -219,5 +220,37 @@ module Bundler::Molinillo
def add_edge_no_circular(origin, destination, requirement) def add_edge_no_circular(origin, destination, requirement)
log.add_edge_no_circular(self, origin.name, destination.name, requirement) log.add_edge_no_circular(self, origin.name, destination.name, requirement)
end end
# Returns the path between two vertices
# @raise [ArgumentError] if there is no path between the vertices
# @param [Vertex] from
# @param [Vertex] to
# @return [Array<Vertex>] the shortest path from `from` to `to`
def path(from, to)
distances = Hash.new(vertices.size + 1)
distances[from.name] = 0
predecessors = {}
each do |vertex|
vertex.successors.each do |successor|
if distances[successor.name] > distances[vertex.name] + 1
distances[successor.name] = distances[vertex.name] + 1
predecessors[successor] = vertex
end
end
end
path = [to]
while before = predecessors[to]
path << before
to = before
break if to == from
end
unless path.last.equal?(from)
raise ArgumentError, "There is no path from #{from.name} to #{to.name}"
end
path.reverse
end
end end
end end

View file

@ -14,11 +14,11 @@ module Bundler::Molinillo
end end
# (see Action#up) # (see Action#up)
def up(_graph) def up(graph)
end end
# (see Action#down) # (see Action#down)
def down(_graph) def down(graph)
end end
# @!group Tag # @!group Tag

View file

@ -65,7 +65,7 @@ module Bundler::Molinillo
# @param [SpecificationProvider] specification_provider see {#specification_provider} # @param [SpecificationProvider] specification_provider see {#specification_provider}
def initialize(conflicts, specification_provider) def initialize(conflicts, specification_provider)
pairs = [] pairs = []
Compatibility.flat_map(conflicts.values.flatten, &:requirements).each do |conflicting| conflicts.values.flat_map(&:requirements).each do |conflicting|
conflicting.each do |source, conflict_requirements| conflicting.each do |source, conflict_requirements|
conflict_requirements.each do |c| conflict_requirements.each do |c|
pairs << [c, source] pairs << [c, source]

View file

@ -2,5 +2,5 @@
module Bundler::Molinillo module Bundler::Molinillo
# The version of Bundler::Molinillo. # The version of Bundler::Molinillo.
VERSION = '0.6.6'.freeze VERSION = '0.7.0'.freeze
end end

View file

@ -207,7 +207,7 @@ module Bundler::Molinillo
def start_resolution def start_resolution
@started_at = Time.now @started_at = Time.now
handle_missing_or_push_dependency_state(initial_state) push_initial_state
debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" } debug { "Starting resolution (#{@started_at})\nUser-requested dependencies: #{original_requested}" }
resolver_ui.before_resolution resolver_ui.before_resolution
@ -273,10 +273,10 @@ module Bundler::Molinillo
states.last states.last
end end
# Creates the initial state for the resolution, based upon the # Creates and pushes the initial state for the resolution, based upon the
# {#requested} dependencies # {#requested} dependencies
# @return [DependencyState] the initial state for the resolution # @return [void]
def initial_state def push_initial_state
graph = DependencyGraph.new.tap do |dg| graph = DependencyGraph.new.tap do |dg|
original_requested.each do |requested| original_requested.each do |requested|
vertex = dg.add_vertex(name_for(requested), nil, true) vertex = dg.add_vertex(name_for(requested), nil, true)
@ -285,18 +285,7 @@ module Bundler::Molinillo
dg.tag(:initial_state) dg.tag(:initial_state)
end end
requirements = sort_dependencies(original_requested, graph, {}) push_state_for_requirements(original_requested, true, graph)
initial_requirement = requirements.shift
DependencyState.new(
initial_requirement && name_for(initial_requirement),
requirements,
graph,
initial_requirement,
possibilities_for_requirement(initial_requirement, graph),
0,
{},
[]
)
end end
# Unwinds the states stack because a conflict has been encountered # Unwinds the states stack because a conflict has been encountered
@ -361,7 +350,7 @@ module Bundler::Molinillo
current_detail current_detail
end end
# @param [Array<Object>] array of requirements that combine to create a conflict # @param [Array<Object>] binding_requirements array of requirements that combine to create a conflict
# @return [Array<UnwindDetails>] array of UnwindDetails that have a chance # @return [Array<UnwindDetails>] array of UnwindDetails that have a chance
# of resolving the passed requirements # of resolving the passed requirements
def unwind_options_for_requirements(binding_requirements) def unwind_options_for_requirements(binding_requirements)
@ -429,7 +418,7 @@ module Bundler::Molinillo
end end
# @param [DependencyState] state # @param [DependencyState] state
# @param [Array] array of requirements # @param [Array] binding_requirements array of requirements
# @return [Boolean] whether or not the given state has any possibilities # @return [Boolean] whether or not the given state has any possibilities
# that could satisfy the given requirements # that could satisfy the given requirements
def conflict_fixing_possibilities?(state, binding_requirements) def conflict_fixing_possibilities?(state, binding_requirements)
@ -444,7 +433,8 @@ module Bundler::Molinillo
# Filter's a state's possibilities to remove any that would not fix the # Filter's a state's possibilities to remove any that would not fix the
# conflict we've just rewound from # conflict we've just rewound from
# @param [UnwindDetails] details of the conflict just unwound from # @param [UnwindDetails] unwind_details details of the conflict just
# unwound from
# @return [void] # @return [void]
def filter_possibilities_after_unwind(unwind_details) def filter_possibilities_after_unwind(unwind_details)
return unless state && !state.possibilities.empty? return unless state && !state.possibilities.empty?
@ -458,7 +448,7 @@ module Bundler::Molinillo
# Filter's a state's possibilities to remove any that would not satisfy # Filter's a state's possibilities to remove any that would not satisfy
# the requirements in the conflict we've just rewound from # the requirements in the conflict we've just rewound from
# @param [UnwindDetails] details of the conflict just unwound from # @param [UnwindDetails] unwind_details details of the conflict just unwound from
# @return [void] # @return [void]
def filter_possibilities_for_primary_unwind(unwind_details) def filter_possibilities_for_primary_unwind(unwind_details)
unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index } unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
@ -491,7 +481,7 @@ module Bundler::Molinillo
# Filter's a state's possibilities to remove any that would (eventually) # Filter's a state's possibilities to remove any that would (eventually)
# create a requirement in the conflict we've just rewound from # create a requirement in the conflict we've just rewound from
# @param [UnwindDetails] details of the conflict just unwound from # @param [UnwindDetails] unwind_details details of the conflict just unwound from
# @return [void] # @return [void]
def filter_possibilities_for_parent_unwind(unwind_details) def filter_possibilities_for_parent_unwind(unwind_details)
unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index } unwinds_to_state = unused_unwind_options.select { |uw| uw.state_index == unwind_details.state_index }
@ -500,7 +490,7 @@ module Bundler::Molinillo
primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq primary_unwinds = unwinds_to_state.select(&:unwinding_to_primary_requirement?).uniq
parent_unwinds = unwinds_to_state.uniq - primary_unwinds parent_unwinds = unwinds_to_state.uniq - primary_unwinds
allowed_possibility_sets = Compatibility.flat_map(primary_unwinds) do |unwind| allowed_possibility_sets = primary_unwinds.flat_map do |unwind|
states[unwind.state_index].possibilities.select do |possibility_set| states[unwind.state_index].possibilities.select do |possibility_set|
possibility_set.possibilities.any? do |poss| possibility_set.possibilities.any? do |poss|
possibility_satisfies_requirements?(poss, unwind.conflicting_requirements) possibility_satisfies_requirements?(poss, unwind.conflicting_requirements)
@ -508,7 +498,7 @@ module Bundler::Molinillo
end end
end end
requirements_to_avoid = Compatibility.flat_map(parent_unwinds, &:sub_dependencies_to_avoid) requirements_to_avoid = parent_unwinds.flat_map(&:sub_dependencies_to_avoid)
state.possibilities.reject! do |possibility_set| state.possibilities.reject! do |possibility_set|
!allowed_possibility_sets.include?(possibility_set) && !allowed_possibility_sets.include?(possibility_set) &&
@ -524,12 +514,12 @@ module Bundler::Molinillo
possible_binding_requirements = conflict.requirements.values.flatten(1).uniq possible_binding_requirements = conflict.requirements.values.flatten(1).uniq
# When theres a `CircularDependency` error the conflicting requirement # When there's a `CircularDependency` error the conflicting requirement
# (the one causing the circular) wont be `conflict.requirement` # (the one causing the circular) won't be `conflict.requirement`
# (which wont be for the right state, because we wont have created it, # (which won't be for the right state, because we won't have created it,
# because its circular). # because it's circular).
# We need to make sure we have that requirement in the conflicts list, # We need to make sure we have that requirement in the conflict's list,
# otherwise we wont be able to unwind properly, so we just return all # otherwise we won't be able to unwind properly, so we just return all
# the requirements for the conflict. # the requirements for the conflict.
return possible_binding_requirements if conflict.underlying_error return possible_binding_requirements if conflict.underlying_error
@ -558,8 +548,8 @@ module Bundler::Molinillo
end end
# @param [Object] requirement we wish to check # @param [Object] requirement we wish to check
# @param [Array] array of requirements # @param [Array] possible_binding_requirements array of requirements
# @param [Array] array of possibilities the requirements will be used to filter # @param [Array] possibilities array of possibilities the requirements will be used to filter
# @return [Boolean] whether or not the given requirement is required to filter # @return [Boolean] whether or not the given requirement is required to filter
# out all elements of the array of possibilities. # out all elements of the array of possibilities.
def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities) def binding_requirement_in_set?(requirement, possible_binding_requirements, possibilities)
@ -568,6 +558,7 @@ module Bundler::Molinillo
end end
end end
# @param [Object] requirement
# @return [Object] the requirement that led to `requirement` being added # @return [Object] the requirement that led to `requirement` being added
# to the list of requirements. # to the list of requirements.
def parent_of(requirement) def parent_of(requirement)
@ -577,6 +568,7 @@ module Bundler::Molinillo
parent_state.requirement parent_state.requirement
end end
# @param [String] name
# @return [Object] the requirement that led to a version of a possibility # @return [Object] the requirement that led to a version of a possibility
# with the given name being activated. # with the given name being activated.
def requirement_for_existing_name(name) def requirement_for_existing_name(name)
@ -585,6 +577,7 @@ module Bundler::Molinillo
states.find { |s| s.name == name }.requirement states.find { |s| s.name == name }.requirement
end end
# @param [Object] requirement
# @return [ResolutionState] the state whose `requirement` is the given # @return [ResolutionState] the state whose `requirement` is the given
# `requirement`. # `requirement`.
def find_state_for(requirement) def find_state_for(requirement)
@ -592,6 +585,7 @@ module Bundler::Molinillo
states.find { |i| requirement == i.requirement } states.find { |i| requirement == i.requirement }
end end
# @param [Object] underlying_error
# @return [Conflict] a {Conflict} that reflects the failure to activate # @return [Conflict] a {Conflict} that reflects the failure to activate
# the {#possibility} in conjunction with the current {#state} # the {#possibility} in conjunction with the current {#state}
def create_conflict(underlying_error = nil) def create_conflict(underlying_error = nil)
@ -628,6 +622,7 @@ module Bundler::Molinillo
vertex.requirements.map { |r| requirement_tree_for(r) } vertex.requirements.map { |r| requirement_tree_for(r) }
end end
# @param [Object] requirement
# @return [Array<Object>] the list of requirements that led to # @return [Array<Object>] the list of requirements that led to
# `requirement` being required. # `requirement` being required.
def requirement_tree_for(requirement) def requirement_tree_for(requirement)
@ -673,9 +668,8 @@ module Bundler::Molinillo
attempt_to_filter_existing_spec(existing_vertex) attempt_to_filter_existing_spec(existing_vertex)
else else
latest = possibility.latest_version latest = possibility.latest_version
# use reject!(!satisfied) for 1.8.7 compatibility possibility.possibilities.select! do |possibility|
possibility.possibilities.reject! do |possibility| requirement_satisfied_by?(requirement, activated, possibility)
!requirement_satisfied_by?(requirement, activated, possibility)
end end
if possibility.latest_version.nil? if possibility.latest_version.nil?
# ensure there's a possibility for better error messages # ensure there's a possibility for better error messages
@ -705,7 +699,7 @@ module Bundler::Molinillo
# Generates a filtered version of the existing vertex's `PossibilitySet` using the # Generates a filtered version of the existing vertex's `PossibilitySet` using the
# current state's `requirement` # current state's `requirement`
# @param [Object] existing vertex # @param [Object] vertex existing vertex
# @return [PossibilitySet] filtered possibility set # @return [PossibilitySet] filtered possibility set
def filtered_possibility_set(vertex) def filtered_possibility_set(vertex)
PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities) PossibilitySet.new(vertex.payload.dependencies, vertex.payload.possibilities & possibility.possibilities)
@ -730,7 +724,7 @@ module Bundler::Molinillo
end end
# Requires the dependencies that the recently activated spec has # Requires the dependencies that the recently activated spec has
# @param [Object] activated_possibility the PossibilitySet that has just been # @param [Object] possibility_set the PossibilitySet that has just been
# activated # activated
# @return [void] # @return [void]
def require_nested_dependencies_for(possibility_set) def require_nested_dependencies_for(possibility_set)
@ -749,6 +743,8 @@ module Bundler::Molinillo
# Pushes a new {DependencyState} that encapsulates both existing and new # Pushes a new {DependencyState} that encapsulates both existing and new
# requirements # requirements
# @param [Array] new_requirements # @param [Array] new_requirements
# @param [Boolean] requires_sort
# @param [Object] new_activated
# @return [void] # @return [void]
def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated) def push_state_for_requirements(new_requirements, requires_sort = true, new_activated = activated)
new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort new_requirements = sort_dependencies(new_requirements.uniq, new_activated, conflicts) if requires_sort
@ -767,7 +763,8 @@ module Bundler::Molinillo
# Checks a proposed requirement with any existing locked requirement # Checks a proposed requirement with any existing locked requirement
# before generating an array of possibilities for it. # before generating an array of possibilities for it.
# @param [Object] the proposed requirement # @param [Object] requirement the proposed requirement
# @param [Object] activated
# @return [Array] possibilities # @return [Array] possibilities
def possibilities_for_requirement(requirement, activated = self.activated) def possibilities_for_requirement(requirement, activated = self.activated)
return [] unless requirement return [] unless requirement
@ -778,7 +775,8 @@ module Bundler::Molinillo
group_possibilities(search_for(requirement)) group_possibilities(search_for(requirement))
end end
# @param [Object] the proposed requirement # @param [Object] requirement the proposed requirement
# @param [Object] activated
# @return [Array] possibility set containing only the locked requirement, if any # @return [Array] possibility set containing only the locked requirement, if any
def locked_requirement_possibility_set(requirement, activated = self.activated) def locked_requirement_possibility_set(requirement, activated = self.activated)
all_possibilities = search_for(requirement) all_possibilities = search_for(requirement)
@ -797,8 +795,8 @@ module Bundler::Molinillo
# Build an array of PossibilitySets, with each element representing a group of # Build an array of PossibilitySets, with each element representing a group of
# dependency versions that all have the same sub-dependency version constraints # dependency versions that all have the same sub-dependency version constraints
# and are contiguous. # and are contiguous.
# @param [Array] an array of possibilities # @param [Array] possibilities an array of possibilities
# @return [Array] an array of possibility sets # @return [Array<PossibilitySet>] an array of possibility sets
def group_possibilities(possibilities) def group_possibilities(possibilities)
possibility_sets = [] possibility_sets = []
current_possibility_set = nil current_possibility_set = nil

View file

@ -3,6 +3,8 @@ require_relative '../../../../uri/lib/uri'
require 'cgi' # for escaping require 'cgi' # for escaping
require_relative '../../../../connection_pool/lib/connection_pool' require_relative '../../../../connection_pool/lib/connection_pool'
autoload :OpenSSL, 'openssl'
## ##
# Persistent connections for Net::HTTP # Persistent connections for Net::HTTP
# #
@ -147,14 +149,9 @@ class Bundler::Persistent::Net::HTTP::Persistent
EPOCH = Time.at 0 # :nodoc: EPOCH = Time.at 0 # :nodoc:
## ##
# Is OpenSSL available? # Is OpenSSL available? This test works with autoload
HAVE_OPENSSL = begin # :nodoc: HAVE_OPENSSL = defined? OpenSSL::SSL # :nodoc:
require 'openssl'
true
rescue LoadError
false
end
## ##
# The default connection pool size is 1/4 the allowed open files # The default connection pool size is 1/4 the allowed open files

154
lib/bundler/vendor/tmpdir/lib/tmpdir.rb vendored Normal file
View file

@ -0,0 +1,154 @@
# frozen_string_literal: true
#
# tmpdir - retrieve temporary directory path
#
# $Id$
#
require_relative '../../fileutils/lib/fileutils'
begin
require 'etc.so'
rescue LoadError # rescue LoadError for miniruby
end
class Bundler::Dir < Dir
@systmpdir ||= defined?(Etc.systmpdir) ? Etc.systmpdir : '/tmp'
##
# Returns the operating system's temporary file path.
def self.tmpdir
tmp = nil
['TMPDIR', 'TMP', 'TEMP', ['system temporary path', @systmpdir], ['/tmp']*2, ['.']*2].each do |name, dir = ENV[name]|
next if !dir
dir = File.expand_path(dir)
stat = File.stat(dir) rescue next
case
when !stat.directory?
warn "#{name} is not a directory: #{dir}"
when !stat.writable?
warn "#{name} is not writable: #{dir}"
when stat.world_writable? && !stat.sticky?
warn "#{name} is world-writable: #{dir}"
else
tmp = dir
break
end
end
raise ArgumentError, "could not find a temporary directory" unless tmp
tmp
end
# Bundler::Dir.mktmpdir creates a temporary directory.
#
# The directory is created with 0700 permission.
# Application should not change the permission to make the temporary directory accessible from other users.
#
# The prefix and suffix of the name of the directory is specified by
# the optional first argument, <i>prefix_suffix</i>.
# - If it is not specified or nil, "d" is used as the prefix and no suffix is used.
# - If it is a string, it is used as the prefix and no suffix is used.
# - If it is an array, first element is used as the prefix and second element is used as a suffix.
#
# Bundler::Dir.mktmpdir {|dir| dir is ".../d..." }
# Bundler::Dir.mktmpdir("foo") {|dir| dir is ".../foo..." }
# Bundler::Dir.mktmpdir(["foo", "bar"]) {|dir| dir is ".../foo...bar" }
#
# The directory is created under Bundler::Dir.tmpdir or
# the optional second argument <i>tmpdir</i> if non-nil value is given.
#
# Bundler::Dir.mktmpdir {|dir| dir is "#{Bundler::Dir.tmpdir}/d..." }
# Bundler::Dir.mktmpdir(nil, "/var/tmp") {|dir| dir is "/var/tmp/d..." }
#
# If a block is given,
# it is yielded with the path of the directory.
# The directory and its contents are removed
# using Bundler::FileUtils.remove_entry before Bundler::Dir.mktmpdir returns.
# The value of the block is returned.
#
# Bundler::Dir.mktmpdir {|dir|
# # use the directory...
# open("#{dir}/foo", "w") { ... }
# }
#
# If a block is not given,
# The path of the directory is returned.
# In this case, Bundler::Dir.mktmpdir doesn't remove the directory.
#
# dir = Bundler::Dir.mktmpdir
# begin
# # use the directory...
# open("#{dir}/foo", "w") { ... }
# ensure
# # remove the directory.
# Bundler::FileUtils.remove_entry dir
# end
#
def self.mktmpdir(prefix_suffix=nil, *rest, **options)
base = nil
path = Tmpname.create(prefix_suffix || "d", *rest, **options) {|p, _, _, d|
base = d
mkdir(p, 0700)
}
if block_given?
begin
yield path.dup
ensure
unless base
stat = File.stat(File.dirname(path))
if stat.world_writable? and !stat.sticky?
raise ArgumentError, "parent directory is world writable but not sticky"
end
end
Bundler::FileUtils.remove_entry path
end
else
path
end
end
module Tmpname # :nodoc:
module_function
def tmpdir
Bundler::Dir.tmpdir
end
UNUSABLE_CHARS = [File::SEPARATOR, File::ALT_SEPARATOR, File::PATH_SEPARATOR, ":"].uniq.join("").freeze
class << (RANDOM = Random.new)
MAX = 36**6 # < 0x100000000
def next
rand(MAX).to_s(36)
end
end
private_constant :RANDOM
def create(basename, tmpdir=nil, max_try: nil, **opts)
origdir = tmpdir
tmpdir ||= tmpdir()
n = nil
prefix, suffix = basename
prefix = (String.try_convert(prefix) or
raise ArgumentError, "unexpected prefix: #{prefix.inspect}")
prefix = prefix.delete(UNUSABLE_CHARS)
suffix &&= (String.try_convert(suffix) or
raise ArgumentError, "unexpected suffix: #{suffix.inspect}")
suffix &&= suffix.delete(UNUSABLE_CHARS)
begin
t = Time.now.strftime("%Y%m%d")
path = "#{prefix}#{t}-#{$$}-#{RANDOM.next}"\
"#{n ? %[-#{n}] : ''}#{suffix||''}"
path = File.join(tmpdir, path)
yield(path, n, opts, origdir)
rescue Errno::EEXIST
n ||= 0
n += 1
retry if !max_try or n < max_try
raise "cannot generate temporary name using `#{basename}' under `#{tmpdir}'"
end
path
end
end
end

View file

@ -0,0 +1,4 @@
# frozen_string_literal: true
module Bundler; end
require_relative "vendor/tmpdir/lib/tmpdir"

View file

@ -1,7 +1,7 @@
# frozen_string_literal: false # frozen_string_literal: false
module Bundler module Bundler
VERSION = "2.2.0.rc.2".freeze VERSION = "2.2.0".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

@ -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" "October 2020" "" "" .TH "BUNDLE\-ADD" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-BINSTUBS" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-CACHE" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-CHECK" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-CLEAN" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-CONFIG" "1" "November 2020" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-config\fR \- Set bundler configuration options \fBbundle\-config\fR \- Set bundler configuration options
@ -262,9 +262,6 @@ The following is a list of all configuration keys and their purpose\. You can le
\fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\. \fBsilence_root_warning\fR (\fBBUNDLE_SILENCE_ROOT_WARNING\fR): Silence the warning Bundler prints when installing gems as root\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
\fBspecific_platform\fR (\fBBUNDLE_SPECIFIC_PLATFORM\fR): Allow bundler to resolve for the specific running platform and store it in the lockfile, instead of only using a generic platform\. A specific platform is the exact platform triple reported by \fBGem::Platform\.local\fR, such as \fBx86_64\-darwin\-16\fR or \fBuniversal\-java\-1\.8\fR\. On the other hand, generic platforms are those such as \fBruby\fR, \fBmswin\fR, or \fBjava\fR\. In this example, \fBx86_64\-darwin\-16\fR would map to \fBruby\fR and \fBuniversal\-java\-1\.8\fR to \fBjava\fR\.
.
.IP "\(bu" 4
\fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\. \fBssl_ca_cert\fR (\fBBUNDLE_SSL_CA_CERT\fR): Path to a designated CA certificate file or folder containing multiple certificates for trusted CAs in PEM format\.
. .
.IP "\(bu" 4 .IP "\(bu" 4
@ -441,7 +438,7 @@ For gems with a git source with HTTP(S) URL you can specify credentials like so:
. .
.nf .nf
bundle config set \-\-global https://github\.com/bundler/bundler\.git username:password bundle config set \-\-global https://github\.com/rubygems/rubygems\.git username:password
. .
.fi .fi
. .

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" "October 2020" "" "" .TH "BUNDLE\-DOCTOR" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-EXEC" "1" "November 2020" "" ""
. .
.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

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" "October 2020" "" "" .TH "BUNDLE\-GEM" "1" "November 2020" "" ""
. .
.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\-INFO" "1" "October 2020" "" "" .TH "BUNDLE\-INFO" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-INIT" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-INJECT" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-INSTALL" "1" "November 2020" "" ""
. .
.SH "NAME" .SH "NAME"
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
@ -67,7 +67,7 @@ The maximum number of parallel download and install jobs\. The default is \fB1\f
. .
.TP .TP
\fB\-\-local\fR \fB\-\-local\fR
Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if a appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\. Do not attempt to connect to \fBrubygems\.org\fR\. Instead, Bundler will use the gems already present in Rubygems\' cache or in \fBvendor/cache\fR\. Note that if an appropriate platform\-specific gem exists on \fBrubygems\.org\fR it will not be found\.
. .
.TP .TP
\fB\-\-no\-cache\fR \fB\-\-no\-cache\fR

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" "October 2020" "" "" .TH "BUNDLE\-LIST" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-LOCK" "1" "November 2020" "" ""
. .
.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,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\-OPEN" "1" "October 2020" "" "" .TH "BUNDLE\-OPEN" "1" "November 2020" "" ""
. .
.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

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" "October 2020" "" "" .TH "BUNDLE\-OUTDATED" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-PLATFORM" "1" "November 2020" "" ""
. .
.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\-PRISTINE" "1" "October 2020" "" "" .TH "BUNDLE\-PRISTINE" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-REMOVE" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-SHOW" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE\-UPDATE" "1" "November 2020" "" ""
. .
.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\-VIZ" "1" "October 2020" "" "" .TH "BUNDLE\-VIZ" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "BUNDLE" "1" "November 2020" "" ""
. .
.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" "October 2020" "" "" .TH "GEMFILE" "5" "November 2020" "" ""
. .
.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

@ -32,49 +32,49 @@ RSpec.describe "bundle executable" do
it "aliases e to exec" do it "aliases e to exec" do
bundle "e --help" bundle "e --help"
expect(out).to include("BUNDLE-EXEC") expect(out).to include("bundle-exec")
end end
it "aliases ex to exec" do it "aliases ex to exec" do
bundle "ex --help" bundle "ex --help"
expect(out).to include("BUNDLE-EXEC") expect(out).to include("bundle-exec")
end end
it "aliases exe to exec" do it "aliases exe to exec" do
bundle "exe --help" bundle "exe --help"
expect(out).to include("BUNDLE-EXEC") expect(out).to include("bundle-exec")
end end
it "aliases c to check" do it "aliases c to check" do
bundle "c --help" bundle "c --help"
expect(out).to include("BUNDLE-CHECK") expect(out).to include("bundle-check")
end end
it "aliases i to install" do it "aliases i to install" do
bundle "i --help" bundle "i --help"
expect(out).to include("BUNDLE-INSTALL") expect(out).to include("bundle-install")
end end
it "aliases ls to list" do it "aliases ls to list" do
bundle "ls --help" bundle "ls --help"
expect(out).to include("BUNDLE-LIST") expect(out).to include("bundle-list")
end end
it "aliases package to cache" do it "aliases package to cache" do
bundle "package --help" bundle "package --help"
expect(out).to include("BUNDLE-CACHE") expect(out).to include("bundle-cache")
end end
it "aliases pack to cache" do it "aliases pack to cache" do
bundle "pack --help" bundle "pack --help"
expect(out).to include("BUNDLE-CACHE") expect(out).to include("bundle-cache")
end end
end end

View file

@ -3,28 +3,25 @@
require "net/http" require "net/http"
require "bundler/compact_index_client" require "bundler/compact_index_client"
require "bundler/compact_index_client/updater" require "bundler/compact_index_client/updater"
require "tmpdir"
RSpec.describe Bundler::CompactIndexClient::Updater do RSpec.describe Bundler::CompactIndexClient::Updater do
let(:fetcher) { double(:fetcher) } let(:fetcher) { double(:fetcher) }
let(:local_path) { Pathname("/tmp/localpath") } let(:local_path) { Pathname.new Dir.mktmpdir("localpath") }
let(:remote_path) { double(:remote_path) } let(:remote_path) { double(:remote_path) }
let!(:updater) { described_class.new(fetcher) } let!(:updater) { described_class.new(fetcher) }
context "when the ETag header is missing" do context "when the ETag header is missing" do
# Regression test for https://github.com/rubygems/bundler/issues/5463 # Regression test for https://github.com/rubygems/bundler/issues/5463
let(:response) { double(:response, :body => "abc123") }
let(:response) { double(:response, :body => "") } it "treats the response as an update" do
expect(response).to receive(:[]).with("Content-Encoding") { "" }
expect(response).to receive(:[]).with("ETag") { nil }
expect(fetcher).to receive(:call) { response }
it "MisMatchedChecksumError is raised" do updater.update(local_path, remote_path)
# Twice: #update retries on failure
expect(response).to receive(:[]).with("Content-Encoding").twice { "" }
expect(response).to receive(:[]).with("ETag").twice { nil }
expect(fetcher).to receive(:call).twice { response }
expect do
updater.update(local_path, remote_path)
end.to raise_error(Bundler::CompactIndexClient::Updater::MisMatchedChecksumError)
end end
end end
@ -43,7 +40,8 @@ RSpec.describe Bundler::CompactIndexClient::Updater do
context "when bundler doesn't have permissions on Dir.tmpdir" do context "when bundler doesn't have permissions on Dir.tmpdir" do
it "Errno::EACCES is raised" do it "Errno::EACCES is raised" do
allow(Dir).to receive(:mktmpdir) { raise Errno::EACCES } local_path # create local path before stubbing mktmpdir
allow(Bundler::Dir).to receive(:mktmpdir) { raise Errno::EACCES }
expect do expect do
updater.update(local_path, remote_path) updater.update(local_path, remote_path)

View file

@ -1,6 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require "openssl"
require "bundler/settings" require "bundler/settings"
RSpec.describe Bundler::Env do RSpec.describe Bundler::Env do

View file

@ -17,100 +17,81 @@ RSpec.describe Bundler::Fetcher::Index do
end end
context "error handling" do context "error handling" do
shared_examples_for "the error is properly handled" do let(:remote_uri) { Bundler::URI("http://remote-uri.org") }
let(:remote_uri) { Bundler::URI("http://remote-uri.org") } before do
allow(rubygems).to receive(:fetch_all_remote_specs) { raise Gem::RemoteFetcher::FetchError.new(error_message, display_uri) }
allow(subject).to receive(:remote_uri).and_return(remote_uri)
end
context "when certificate verify failed" do
let(:error_message) { "certificate verify failed" }
it "should raise a Bundler::Fetcher::CertificateFailureError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::CertificateFailureError,
%r{Could not verify the SSL certificate for http://sample_uri.com})
end
end
context "when a 401 response occurs" do
let(:error_message) { "401" }
before do before do
allow(subject).to receive(:remote_uri).and_return(remote_uri) allow(remote_uri).to receive(:userinfo).and_return(userinfo)
end end
context "when certificate verify failed" do context "and there was userinfo" do
let(:error_message) { "certificate verify failed" } let(:userinfo) { double(:userinfo) }
it "should raise a Bundler::Fetcher::CertificateFailureError" do it "should raise a Bundler::Fetcher::BadAuthenticationError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::CertificateFailureError, expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
%r{Could not verify the SSL certificate for http://sample_uri.com}) %r{Bad username or password for http://remote-uri.org})
end end
end end
context "when a 401 response occurs" do context "and there was no userinfo" do
let(:error_message) { "401" } let(:userinfo) { nil }
before do it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
allow(remote_uri).to receive(:userinfo).and_return(userinfo) expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
end %r{Authentication is required for http://remote-uri.org})
context "and there was userinfo" do
let(:userinfo) { double(:userinfo) }
it "should raise a Bundler::Fetcher::BadAuthenticationError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
%r{Bad username or password for http://remote-uri.org})
end
end
context "and there was no userinfo" do
let(:userinfo) { nil }
it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
%r{Authentication is required for http://remote-uri.org})
end
end
end
context "when a 403 response occurs" do
let(:error_message) { "403" }
before do
allow(remote_uri).to receive(:userinfo).and_return(userinfo)
end
context "and there was userinfo" do
let(:userinfo) { double(:userinfo) }
it "should raise a Bundler::Fetcher::BadAuthenticationError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
%r{Bad username or password for http://remote-uri.org})
end
end
context "and there was no userinfo" do
let(:userinfo) { nil }
it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
%r{Authentication is required for http://remote-uri.org})
end
end
end
context "any other message is returned" do
let(:error_message) { "You get an error, you get an error!" }
before { allow(Bundler).to receive(:ui).and_return(double(:trace => nil)) }
it "should raise a Bundler::HTTPError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::HTTPError, "Could not fetch specs from http://sample_uri.com")
end end
end end
end end
context "when a Gem::RemoteFetcher::FetchError occurs" do context "when a 403 response occurs" do
before { allow(rubygems).to receive(:fetch_all_remote_specs) { raise Gem::RemoteFetcher::FetchError.new(error_message, nil) } } let(:error_message) { "403" }
it_behaves_like "the error is properly handled" before do
allow(remote_uri).to receive(:userinfo).and_return(userinfo)
end
context "and there was userinfo" do
let(:userinfo) { double(:userinfo) }
it "should raise a Bundler::Fetcher::BadAuthenticationError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError,
%r{Bad username or password for http://remote-uri.org})
end
end
context "and there was no userinfo" do
let(:userinfo) { nil }
it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do
expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError,
%r{Authentication is required for http://remote-uri.org})
end
end
end end
context "when a OpenSSL::SSL::SSLError occurs" do context "any other message is returned" do
before { allow(rubygems).to receive(:fetch_all_remote_specs) { raise OpenSSL::SSL::SSLError.new(error_message) } } let(:error_message) { "You get an error, you get an error!" }
it_behaves_like "the error is properly handled" before { allow(Bundler).to receive(:ui).and_return(double(:trace => nil)) }
end
context "when a Net::HTTPFatalError occurs" do it "should raise a Bundler::HTTPError" do
before { allow(rubygems).to receive(:fetch_all_remote_specs) { raise Net::HTTPFatalError.new(error_message, 404) } } expect { subject.specs(gem_names) }.to raise_error(Bundler::HTTPError, "Could not fetch specs from http://sample_uri.com due to underlying error <You get an error, you get an error! (http://sample_uri.com)>")
end
it_behaves_like "the error is properly handled"
end end
end end
end end

View file

@ -79,4 +79,10 @@ RSpec.describe Bundler::Plugin::API::Source do
end end
end end
end end
describe "to_s" do
it "returns the string with type and uri" do
expect(source.to_s).to eq("plugin source for spec_type with uri uri://to/test")
end
end
end end

View file

@ -2,7 +2,7 @@
RSpec.describe Bundler::Source::Git::GitProxy do RSpec.describe Bundler::Source::Git::GitProxy do
let(:path) { Pathname("path") } let(:path) { Pathname("path") }
let(:uri) { "https://github.com/bundler/bundler.git" } let(:uri) { "https://github.com/rubygems/rubygems.git" }
let(:ref) { "HEAD" } let(:ref) { "HEAD" }
let(:revision) { nil } let(:revision) { nil }
let(:git_source) { nil } let(:git_source) { nil }
@ -11,20 +11,20 @@ RSpec.describe Bundler::Source::Git::GitProxy do
context "with configured credentials" do context "with configured credentials" do
it "adds username and password to URI" do it "adds username and password to URI" do
Bundler.settings.temporary(uri => "u:p") do Bundler.settings.temporary(uri => "u:p") do
expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/bundler/bundler.git")) expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/rubygems/rubygems.git"))
subject.checkout subject.checkout
end end
end end
it "adds username and password to URI for host" do it "adds username and password to URI for host" do
Bundler.settings.temporary("github.com" => "u:p") do Bundler.settings.temporary("github.com" => "u:p") do
expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/bundler/bundler.git")) expect(subject).to receive(:git_retry).with(match("https://u:p@github.com/rubygems/rubygems.git"))
subject.checkout subject.checkout
end end
end end
it "does not add username and password to mismatched URI" do it "does not add username and password to mismatched URI" do
Bundler.settings.temporary("https://u:p@github.com/bundler/bundler-mismatch.git" => "u:p") do Bundler.settings.temporary("https://u:p@github.com/rubygems/rubygems-mismatch.git" => "u:p") do
expect(subject).to receive(:git_retry).with(match(uri)) expect(subject).to receive(:git_retry).with(match(uri))
subject.checkout subject.checkout
end end
@ -32,7 +32,7 @@ RSpec.describe Bundler::Source::Git::GitProxy do
it "keeps original userinfo" do it "keeps original userinfo" do
Bundler.settings.temporary("github.com" => "u:p") do Bundler.settings.temporary("github.com" => "u:p") do
original = "https://orig:info@github.com/bundler/bundler.git" original = "https://orig:info@github.com/rubygems/rubygems.git"
subject = described_class.new(Pathname("path"), original, "HEAD") subject = described_class.new(Pathname("path"), original, "HEAD")
expect(subject).to receive(:git_retry).with(match(original)) expect(subject).to receive(:git_retry).with(match(original))
subject.checkout subject.checkout

View file

@ -197,7 +197,12 @@ RSpec.describe "bundle cache" do
end end
it "adds and removes when gems are updated" do it "adds and removes when gems are updated" do
update_repo2 update_repo2 do
build_gem "rack", "1.2" do |s|
s.executables = "rackup"
end
end
bundle "update", :all => true bundle "update", :all => true
expect(cached_gem("rack-1.2")).to exist expect(cached_gem("rack-1.2")).to exist
expect(cached_gem("rack-1.0.0")).not_to exist expect(cached_gem("rack-1.0.0")).not_to exist

View file

@ -51,6 +51,18 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("bin/rake")).to exist expect(bundled_app("bin/rake")).to exist
end end
it "allows installing binstubs for all platforms" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
gem "rack"
G
bundle "binstubs rack --all-platforms"
expect(bundled_app("bin/rackup")).to exist
expect(bundled_app("bin/rackup.cmd")).to exist
end
it "displays an error when used without any gem" do it "displays an error when used without any gem" do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
@ -96,6 +108,10 @@ RSpec.describe "bundle binstubs <gem>" do
before do before do
pristine_system_gems "bundler-#{system_bundler_version}" pristine_system_gems "bundler-#{system_bundler_version}"
build_repo2 do build_repo2 do
build_gem "rack", "1.2" do |s|
s.executables = "rackup"
end
build_gem "prints_loaded_gems", "1.0" do |s| build_gem "prints_loaded_gems", "1.0" do |s|
s.executables = "print_loaded_gems" s.executables = "print_loaded_gems"
s.bindir = "exe" s.bindir = "exe"
@ -262,7 +278,7 @@ RSpec.describe "bundle binstubs <gem>" do
end end
it "sets correct permissions for binstubs" do it "sets correct permissions for binstubs" do
skip "https://github.com/rubygems/bundler/issues/6895" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3352" if Gem.win_platform?
with_umask(0o002) do with_umask(0o002) do
install_gemfile <<-G install_gemfile <<-G
@ -352,6 +368,14 @@ RSpec.describe "bundle binstubs <gem>" do
expect(bundled_app("foo/rackup")).to exist expect(bundled_app("foo/rackup")).to exist
end end
end end
context "when specified --all-platforms option" do
it "generates standalone binstubs for all platforms" do
bundle "binstubs rack --standalone --all-platforms"
expect(bundled_app("bin/rackup")).to exist
expect(bundled_app("bin/rackup.cmd")).to exist
end
end
end end
context "when the bin already exists" do context "when the bin already exists" do
@ -417,8 +441,14 @@ RSpec.describe "bundle binstubs <gem>" do
end end
it "works if the gem has development dependencies" do it "works if the gem has development dependencies" do
build_repo2 do
build_gem "with_development_dependency" do |s|
s.add_development_dependency "activesupport", "= 2.3.5"
end
end
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo2)}"
gem "with_development_dependency" gem "with_development_dependency"
G G

View file

@ -71,13 +71,19 @@ RSpec.describe "bundle check" do
end end
it "prints a generic message if you changed your lockfile" do it "prints a generic message if you changed your lockfile" do
build_repo2 do
build_gem "rails_pinned_to_old_activesupport" do |s|
s.add_dependency "activesupport", "= 1.2.3"
end
end
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo2)}"
gem 'rails' gem 'rails'
G G
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo2)}"
gem "rails" gem "rails"
gem "rails_pinned_to_old_activesupport" gem "rails_pinned_to_old_activesupport"
G G

View file

@ -603,8 +603,7 @@ RSpec.describe "bundle clean" do
it "when using --force on system gems, it doesn't remove binaries" do it "when using --force on system gems, it doesn't remove binaries" do
bundle "config set path.system true" bundle "config set path.system true"
build_repo2 build_repo2 do
update_repo2 do
build_gem "bindir" do |s| build_gem "bindir" do |s|
s.bindir = "exe" s.bindir = "exe"
s.executables = "foo" s.executables = "foo"
@ -640,7 +639,7 @@ RSpec.describe "bundle clean" do
end end
end end
realworld_system_gems "fiddle" realworld_system_gems "fiddle --version 1.0.0"
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}" source "#{file_uri_for(gem_repo2)}"

View file

@ -2,8 +2,43 @@
RSpec.describe "bundle console", :bundler => "< 3", :readline => true do RSpec.describe "bundle console", :bundler => "< 3", :readline => true do
before :each do before :each do
build_repo2 do
# A minimal fake pry console
build_gem "pry" do |s|
s.write "lib/pry.rb", <<-RUBY
class Pry
class << self
def toplevel_binding
unless defined?(@toplevel_binding) && @toplevel_binding
TOPLEVEL_BINDING.eval %{
def self.__pry__; binding; end
Pry.instance_variable_set(:@toplevel_binding, __pry__)
class << self; undef __pry__; end
}
end
@toplevel_binding.eval('private')
@toplevel_binding
end
def __pry__
while line = gets
begin
puts eval(line, toplevel_binding).inspect.sub(/^"(.*)"$/, '=> \\1')
rescue Exception => e
puts "\#{e.class}: \#{e.message}"
puts e.backtrace.first
end
end
end
alias start __pry__
end
end
RUBY
end
end
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo2)}"
gem "rack" gem "rack"
gem "activesupport", :group => :test gem "activesupport", :group => :test
gem "rack_middleware", :group => :development gem "rack_middleware", :group => :development
@ -28,7 +63,7 @@ RSpec.describe "bundle console", :bundler => "< 3", :readline => true do
it "starts another REPL if configured as such" do it "starts another REPL if configured as such" do
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo2)}"
gem "pry" gem "pry"
G G
bundle "config set console pry" bundle "config set console pry"
@ -87,7 +122,7 @@ RSpec.describe "bundle console", :bundler => "< 3", :readline => true do
it "performs an automatic bundle install" do it "performs an automatic bundle install" do
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo2)}"
gem "rack" gem "rack"
gem "activesupport", :group => :test gem "activesupport", :group => :test
gem "rack_middleware", :group => :development gem "rack_middleware", :group => :development

View file

@ -68,7 +68,7 @@ RSpec.describe "bundle exec" do
end end
it "respects custom process title when loading through ruby" do it "respects custom process title when loading through ruby" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
script_that_changes_its_own_title_and_checks_if_picked_up_by_ps_unix_utility = <<~'RUBY' script_that_changes_its_own_title_and_checks_if_picked_up_by_ps_unix_utility = <<~'RUBY'
Process.setproctitle("1-2-3-4-5-6-7") Process.setproctitle("1-2-3-4-5-6-7")
@ -93,7 +93,7 @@ RSpec.describe "bundle exec" do
end end
it "handles --keep-file-descriptors" do it "handles --keep-file-descriptors" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
require "tempfile" require "tempfile"
@ -126,7 +126,7 @@ RSpec.describe "bundle exec" do
end end
it "can run a command named --verbose" do it "can run a command named --verbose" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
install_gemfile 'gem "rack"' install_gemfile 'gem "rack"'
File.open(bundled_app("--verbose"), "w") do |f| File.open(bundled_app("--verbose"), "w") do |f|
@ -286,7 +286,7 @@ RSpec.describe "bundle exec" do
end end
it "does not duplicate already exec'ed RUBYOPT" do it "does not duplicate already exec'ed RUBYOPT" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
gem "rack" gem "rack"
@ -304,7 +304,7 @@ RSpec.describe "bundle exec" do
end end
it "does not duplicate already exec'ed RUBYLIB" do it "does not duplicate already exec'ed RUBYLIB" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
gem "rack" gem "rack"
@ -357,7 +357,7 @@ RSpec.describe "bundle exec" do
bundle "config set clean false" # want to keep the rackup binstub bundle "config set clean false" # want to keep the rackup binstub
install_gemfile <<-G install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "with_license" gem "foo"
G G
[true, false].each do |l| [true, false].each do |l|
bundle "config set disable_exec_load #{l}" bundle "config set disable_exec_load #{l}"
@ -373,7 +373,7 @@ RSpec.describe "bundle exec" do
each_prefix.call("exec") do |exec| each_prefix.call("exec") do |exec|
describe "when #{exec} is used" do describe "when #{exec} is used" do
before(:each) do before(:each) do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
install_gemfile <<-G install_gemfile <<-G
gem "rack" gem "rack"
@ -588,7 +588,7 @@ RSpec.describe "bundle exec" do
describe "with gems bundled for deployment" do describe "with gems bundled for deployment" do
it "works when calling bundler from another script" do it "works when calling bundler from another script" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
gemfile <<-G gemfile <<-G
module Monkey module Monkey
@ -644,7 +644,7 @@ RSpec.describe "bundle exec" do
shared_examples_for "it runs" do shared_examples_for "it runs" do
it "like a normally executed executable" do it "like a normally executed executable" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject subject
expect(exitstatus).to eq(exit_code) expect(exitstatus).to eq(exit_code)
@ -698,15 +698,23 @@ RSpec.describe "bundle exec" do
let(:exit_code) { 1 } let(:exit_code) { 1 }
let(:expected_err) do let(:expected_err) do
"bundler: failed to load command: #{path} (#{path})" \ "bundler: failed to load command: #{path} (#{path})" \
"\nRuntimeError: ERROR\n #{path}:10:in `<top (required)>'" "\n#{path}:10:in `<top (required)>': ERROR (RuntimeError)"
end
it "runs like a normally executed executable" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to start_with(expected_err)
expect(out).to eq(expected)
end end
it_behaves_like "it runs"
end end
context "the executable raises an error without a backtrace" do context "the executable raises an error without a backtrace" do
let(:executable) { super() << "\nclass Err < Exception\ndef backtrace; end;\nend\nraise Err" } let(:executable) { super() << "\nclass Err < Exception\ndef backtrace; end;\nend\nraise Err" }
let(:exit_code) { 1 } let(:exit_code) { 1 }
let(:expected_err) { "bundler: failed to load command: #{path} (#{path})\nErr: Err" } let(:expected_err) { "bundler: failed to load command: #{path} (#{path})\n#{system_gem_path("bin/bundle")}: Err (Err)" }
let(:expected) { super() } let(:expected) { super() }
it_behaves_like "it runs" it_behaves_like "it runs"
@ -747,7 +755,7 @@ RSpec.describe "bundle exec" do
let(:expected) { "" } let(:expected) { "" }
let(:expected_err) { <<-EOS.strip } let(:expected_err) { <<-EOS.strip }
\e[31mCould not find gem 'rack (= 2)' in locally installed gems. \e[31mCould not find gem 'rack (= 2)' in locally installed gems.
The source contains 'rack' at: 1.0.0\e[0m The source contains the following versions of 'rack': 1.0.0\e[0m
\e[33mRun `bundle install` to install missing gems.\e[0m \e[33mRun `bundle install` to install missing gems.\e[0m
EOS EOS
@ -825,7 +833,7 @@ __FILE__: #{path.to_s.inspect}
RUBY RUBY
it "receives the signal" do it "receives the signal" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
bundle("exec #{path}") do |_, o, thr| bundle("exec #{path}") do |_, o, thr|
o.gets # Consumes 'Started' and ensures that thread has started o.gets # Consumes 'Started' and ensures that thread has started
@ -848,7 +856,7 @@ __FILE__: #{path.to_s.inspect}
RUBY RUBY
it "makes sure no unexpected signals are restored to DEFAULT" do it "makes sure no unexpected signals are restored to DEFAULT" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
test_signals.each do |n| test_signals.each do |n|
Signal.trap(n, "IGNORE") Signal.trap(n, "IGNORE")
@ -865,6 +873,8 @@ __FILE__: #{path.to_s.inspect}
context "nested bundle exec" do context "nested bundle exec" do
context "when bundle in a local path" do context "when bundle in a local path" do
before do before do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
gemfile <<-G gemfile <<-G
source "#{file_uri_for(gem_repo1)}" source "#{file_uri_for(gem_repo1)}"
gem "rack" gem "rack"
@ -874,8 +884,6 @@ __FILE__: #{path.to_s.inspect}
end end
it "correctly shells out" do it "correctly shells out" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform?
file = bundled_app("file_that_bundle_execs.rb") file = bundled_app("file_that_bundle_execs.rb")
create_file(file, <<-RUBY) create_file(file, <<-RUBY)
#!#{Gem.ruby} #!#{Gem.ruby}
@ -887,12 +895,55 @@ __FILE__: #{path.to_s.inspect}
end end
end end
context "when Kernel.require uses extra monkeypatches" do
before do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
install_gemfile ""
end
it "does not undo the monkeypatches" do
karafka = bundled_app("bin/karafka")
create_file(karafka, <<~RUBY)
#!#{Gem.ruby}
module Kernel
module_function
alias_method :require_before_extra_monkeypatches, :require
def require(path)
puts "requiring \#{path} used the monkeypatch"
require_before_extra_monkeypatches(path)
end
end
Bundler.setup(:default)
require "foo"
RUBY
karafka.chmod(0o777)
foreman = bundled_app("bin/foreman")
create_file(foreman, <<~RUBY)
#!#{Gem.ruby}
puts `bundle exec bin/karafka`
RUBY
foreman.chmod(0o777)
bundle "exec #{foreman}"
expect(out).to eq("requiring foo used the monkeypatch")
end
end
context "with a system gem that shadows a default gem" do context "with a system gem that shadows a default gem" do
let(:openssl_version) { "99.9.9" } let(:openssl_version) { "99.9.9" }
let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", :artifice => nil, :raise_on_error => false } let(:expected) { ruby "gem 'openssl', '< 999999'; require 'openssl'; puts OpenSSL::VERSION", :artifice => nil, :raise_on_error => false }
it "only leaves the default gem in the stdlib available" do it "only leaves the default gem in the stdlib available" do
skip "https://github.com/rubygems/bundler/issues/6898" if Gem.win_platform? skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
skip "openssl isn't a default gem" if expected.empty? skip "openssl isn't a default gem" if expected.empty?
install_gemfile "" # must happen before installing the broken system gem install_gemfile "" # must happen before installing the broken system gem

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