зеркало из https://github.com/github/ruby.git
Sync latest development version of bundler & rubygems
This commit is contained in:
Родитель
2ab6b7a751
Коммит
53468cc111
|
@ -63,7 +63,6 @@ module Bundler
|
|||
autoload :Resolver, File.expand_path("bundler/resolver", __dir__)
|
||||
autoload :Retry, File.expand_path("bundler/retry", __dir__)
|
||||
autoload :RubyDsl, File.expand_path("bundler/ruby_dsl", __dir__)
|
||||
autoload :RubyGemsGemInstaller, File.expand_path("bundler/rubygems_gem_installer", __dir__)
|
||||
autoload :RubyVersion, File.expand_path("bundler/ruby_version", __dir__)
|
||||
autoload :Runtime, File.expand_path("bundler/runtime", __dir__)
|
||||
autoload :Settings, File.expand_path("bundler/settings", __dir__)
|
||||
|
@ -441,7 +440,7 @@ EOF
|
|||
end
|
||||
|
||||
def local_platform
|
||||
return Gem::Platform::RUBY if settings[:force_ruby_platform]
|
||||
return Gem::Platform::RUBY if settings[:force_ruby_platform] || Gem.platforms == [Gem::Platform::RUBY]
|
||||
Gem::Platform.local
|
||||
end
|
||||
|
||||
|
|
|
@ -586,6 +586,7 @@ module Bundler
|
|||
method_option :git, :type => :boolean, :default => true, :desc => "Initialize a git repo inside your library."
|
||||
method_option :mit, :type => :boolean, :desc => "Generate an MIT license file. Set a default with `bundle config set --global gem.mit true`."
|
||||
method_option :rubocop, :type => :boolean, :desc => "Add rubocop to the generated Rakefile and gemspec. Set a default with `bundle config set --global gem.rubocop true`."
|
||||
method_option :changelog, :type => :boolean, :desc => "Generate changelog file. Set a default with `bundle config set --global gem.changelog true`."
|
||||
method_option :test, :type => :string, :lazy_default => Bundler.settings["gem.test"] || "", :aliases => "-t", :banner => "Use the specified test framework for your library",
|
||||
:desc => "Generate a test directory for your library, either rspec, minitest or test-unit. Set a default with `bundle config set --global gem.test (rspec|minitest|test-unit)`."
|
||||
method_option :ci, :type => :string, :lazy_default => Bundler.settings["gem.ci"] || "",
|
||||
|
|
|
@ -30,6 +30,7 @@ module Bundler
|
|||
require_relative "install"
|
||||
options = self.options.dup
|
||||
options["local"] = false if Bundler.settings[:cache_all_platforms]
|
||||
options["no-cache"] = true
|
||||
Bundler::CLI::Install.new(options).run
|
||||
end
|
||||
|
||||
|
|
|
@ -39,11 +39,11 @@ module Bundler
|
|||
constant_name = name.gsub(/-[_-]*(?![_-]|$)/) { "::" }.gsub(/([_-]+|(::)|^)(.|$)/) { $2.to_s + $3.upcase }
|
||||
constant_array = constant_name.split("::")
|
||||
|
||||
git_installed = Bundler.git_present?
|
||||
use_git = Bundler.git_present? && options[:git]
|
||||
|
||||
git_author_name = git_installed ? `git config user.name`.chomp : ""
|
||||
github_username = git_installed ? `git config github.user`.chomp : ""
|
||||
git_user_email = git_installed ? `git config user.email`.chomp : ""
|
||||
git_author_name = use_git ? `git config user.name`.chomp : ""
|
||||
github_username = use_git ? `git config github.user`.chomp : ""
|
||||
git_user_email = use_git ? `git config user.email`.chomp : ""
|
||||
|
||||
config = {
|
||||
:name => name,
|
||||
|
@ -58,7 +58,9 @@ module Bundler
|
|||
:ext => options[:ext],
|
||||
:exe => options[:exe],
|
||||
:bundler_version => bundler_dependency_version,
|
||||
:git => use_git,
|
||||
:github_username => github_username.empty? ? "[USERNAME]" : github_username,
|
||||
:required_ruby_version => Gem.ruby_version < Gem::Version.new("2.4.a") ? "2.3.0" : "2.4.0",
|
||||
}
|
||||
ensure_safe_gem_name(name, constant_array)
|
||||
|
||||
|
@ -78,7 +80,7 @@ module Bundler
|
|||
bin/setup
|
||||
]
|
||||
|
||||
templates.merge!("gitignore.tt" => ".gitignore") if Bundler.git_present?
|
||||
templates.merge!("gitignore.tt" => ".gitignore") if use_git
|
||||
|
||||
if test_framework = ask_and_set_test_framework
|
||||
config[:test] = test_framework
|
||||
|
@ -141,12 +143,25 @@ module Bundler
|
|||
templates.merge!("CODE_OF_CONDUCT.md.tt" => "CODE_OF_CONDUCT.md")
|
||||
end
|
||||
|
||||
if ask_and_set(:changelog, "Do you want to include a changelog?",
|
||||
"A changelog is a file which contains a curated, chronologically ordered list of notable " \
|
||||
"changes for each version of a project. To make it easier for users and contributors to" \
|
||||
" see precisely what notable changes have been made between each release (or version) of" \
|
||||
" the project. Whether consumers or developers, the end users of software are" \
|
||||
" human beings who care about what's in the software. When the software changes, people " \
|
||||
"want to know why and how. see https://keepachangelog.com")
|
||||
config[:changelog] = true
|
||||
Bundler.ui.info "Changelog enabled in config"
|
||||
templates.merge!("CHANGELOG.md.tt" => "CHANGELOG.md")
|
||||
end
|
||||
|
||||
if ask_and_set(:rubocop, "Do you want to add rubocop as a dependency for gems you generate?",
|
||||
"RuboCop is a static code analyzer that has out-of-the-box rules for many " \
|
||||
"of the guidelines in the community style guide. " \
|
||||
"For more information, see the RuboCop docs (https://docs.rubocop.org/en/stable/) " \
|
||||
"and the Ruby Style Guides (https://github.com/rubocop-hq/ruby-style-guide).")
|
||||
config[:rubocop] = true
|
||||
config[:rubocop_version] = Gem.ruby_version < Gem::Version.new("2.4.a") ? "0.81.0" : "1.7"
|
||||
Bundler.ui.info "RuboCop enabled in config"
|
||||
templates.merge!("rubocop.yml.tt" => ".rubocop.yml")
|
||||
end
|
||||
|
@ -161,24 +176,31 @@ module Bundler
|
|||
)
|
||||
end
|
||||
|
||||
if File.exist?(target) && !File.directory?(target)
|
||||
Bundler.ui.error "Couldn't create a new gem named `#{gem_name}` because there's an existing file named `#{gem_name}`."
|
||||
exit Bundler::BundlerError.all_errors[Bundler::GenericSystemCallError]
|
||||
end
|
||||
|
||||
if use_git
|
||||
Bundler.ui.info "Initializing git repo in #{target}"
|
||||
`git init #{target}`
|
||||
|
||||
config[:git_default_branch] = File.read("#{target}/.git/HEAD").split("/").last.chomp
|
||||
end
|
||||
|
||||
templates.each do |src, dst|
|
||||
destination = target.join(dst)
|
||||
SharedHelpers.filesystem_access(destination) do
|
||||
thor.template("newgem/#{src}", destination, config)
|
||||
end
|
||||
thor.template("newgem/#{src}", destination, config)
|
||||
end
|
||||
|
||||
executables.each do |file|
|
||||
SharedHelpers.filesystem_access(target.join(file)) do |path|
|
||||
executable = (path.stat.mode | 0o111)
|
||||
path.chmod(executable)
|
||||
end
|
||||
path = target.join(file)
|
||||
executable = (path.stat.mode | 0o111)
|
||||
path.chmod(executable)
|
||||
end
|
||||
|
||||
if Bundler.git_present? && options[:git]
|
||||
Bundler.ui.info "Initializing git repo in #{target}"
|
||||
if use_git
|
||||
Dir.chdir(target) do
|
||||
`git init`
|
||||
`git add .`
|
||||
end
|
||||
end
|
||||
|
@ -188,8 +210,6 @@ module Bundler
|
|||
|
||||
Bundler.ui.info "Gem '#{name}' was successfully created. " \
|
||||
"For more information on making a RubyGem visit https://bundler.io/guides/creating_gem.html"
|
||||
rescue Errno::EEXIST => e
|
||||
raise GenericSystemCallError.new(e, "There was a conflict while creating the new gem.")
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../vendored_fileutils"
|
||||
require "stringio"
|
||||
require "zlib"
|
||||
|
||||
module Bundler
|
||||
class CompactIndexClient
|
||||
|
@ -45,24 +43,18 @@ module Bundler
|
|||
else
|
||||
"bytes=#{local_temp_path.size}-"
|
||||
end
|
||||
else
|
||||
# Fastly ignores Range when Accept-Encoding: gzip is set
|
||||
headers["Accept-Encoding"] = "gzip"
|
||||
end
|
||||
|
||||
response = @fetcher.call(remote_path, headers)
|
||||
return nil if response.is_a?(Net::HTTPNotModified)
|
||||
|
||||
content = response.body
|
||||
if response["Content-Encoding"] == "gzip"
|
||||
content = Zlib::GzipReader.new(StringIO.new(content)).read
|
||||
end
|
||||
|
||||
SharedHelpers.filesystem_access(local_temp_path) do
|
||||
if response.is_a?(Net::HTTPPartialContent) && local_temp_path.size.nonzero?
|
||||
local_temp_path.open("a") {|f| f << slice_body(content, 1..-1) }
|
||||
else
|
||||
local_temp_path.open("w") {|f| f << content }
|
||||
local_temp_path.open("wb") {|f| f << content }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "lockfile_parser"
|
||||
require "set"
|
||||
|
||||
module Bundler
|
||||
class Definition
|
||||
|
@ -88,11 +87,7 @@ module Bundler
|
|||
@lockfile_contents = Bundler.read_file(lockfile)
|
||||
@locked_gems = LockfileParser.new(@lockfile_contents)
|
||||
@locked_platforms = @locked_gems.platforms
|
||||
if Bundler.settings[:force_ruby_platform]
|
||||
@platforms = [Gem::Platform::RUBY]
|
||||
else
|
||||
@platforms = @locked_platforms.dup
|
||||
end
|
||||
@platforms = @locked_platforms.dup
|
||||
@locked_bundler_version = @locked_gems.bundler_version
|
||||
@locked_ruby_version = @locked_gems.ruby_version
|
||||
|
||||
|
@ -264,23 +259,18 @@ module Bundler
|
|||
def resolve
|
||||
@resolve ||= begin
|
||||
last_resolve = converge_locked_specs
|
||||
resolve =
|
||||
if Bundler.frozen_bundle?
|
||||
Bundler.ui.debug "Frozen, using resolution from the lockfile"
|
||||
last_resolve
|
||||
elsif !unlocking? && nothing_changed?
|
||||
Bundler.ui.debug("Found no changes, using resolution from the lockfile")
|
||||
last_resolve
|
||||
else
|
||||
# Run a resolve against the locally available gems
|
||||
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
|
||||
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
|
||||
last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
|
||||
end
|
||||
|
||||
# filter out gems that _can_ be installed on multiple platforms, but don't need
|
||||
# to be
|
||||
resolve.for(expand_dependencies(dependencies, true), [], false, false, false)
|
||||
if Bundler.frozen_bundle?
|
||||
Bundler.ui.debug "Frozen, using resolution from the lockfile"
|
||||
last_resolve
|
||||
elsif !unlocking? && nothing_changed?
|
||||
Bundler.ui.debug("Found no changes, using resolution from the lockfile")
|
||||
last_resolve
|
||||
else
|
||||
# Run a resolve against the locally available gems
|
||||
Bundler.ui.debug("Found changes from the lockfile, re-resolving dependencies because #{change_reason}")
|
||||
expanded_dependencies = expand_dependencies(dependencies + metadata_dependencies, @remote)
|
||||
Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -611,7 +601,7 @@ module Bundler
|
|||
deps_for_source = @dependencies.select {|s| s.source == source }
|
||||
locked_deps_for_source = @locked_deps.values.select {|dep| dep.source == locked_source }
|
||||
|
||||
Set.new(deps_for_source) != Set.new(locked_deps_for_source)
|
||||
deps_for_source.uniq.sort != locked_deps_for_source.sort
|
||||
end
|
||||
|
||||
def specs_for_source_changed?(source)
|
||||
|
@ -673,19 +663,20 @@ module Bundler
|
|||
def converge_rubygems_sources
|
||||
return false if Bundler.feature_flag.disable_multisource?
|
||||
|
||||
changes = false
|
||||
|
||||
# Get the RubyGems sources from the Gemfile.lock
|
||||
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
|
||||
return false if locked_gem_sources.empty?
|
||||
|
||||
# Get the RubyGems remotes from the Gemfile
|
||||
actual_remotes = sources.rubygems_remotes
|
||||
return false if actual_remotes.empty?
|
||||
|
||||
changes = false
|
||||
|
||||
# If there is a RubyGems source in both
|
||||
if !locked_gem_sources.empty? && !actual_remotes.empty?
|
||||
locked_gem_sources.each do |locked_gem|
|
||||
# Merge the remotes from the Gemfile into the Gemfile.lock
|
||||
changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
|
||||
end
|
||||
locked_gem_sources.each do |locked_gem|
|
||||
# Merge the remotes from the Gemfile into the Gemfile.lock
|
||||
changes |= locked_gem.replace_remotes(actual_remotes, Bundler.settings[:allow_deployment_source_credential_changes])
|
||||
end
|
||||
|
||||
changes
|
||||
|
@ -825,11 +816,6 @@ module Bundler
|
|||
# commonly happens if the version changed in the gemspec
|
||||
next unless new_spec
|
||||
|
||||
new_runtime_deps = new_spec.dependencies.select {|d| d.type != :development }
|
||||
old_runtime_deps = s.dependencies.select {|d| d.type != :development }
|
||||
# If the dependencies of the path source have changed and locked spec can't satisfy new dependencies, unlock it
|
||||
next unless new_runtime_deps.sort == old_runtime_deps.sort || new_runtime_deps.all? {|d| satisfies_locked_spec?(d) }
|
||||
|
||||
s.dependencies.replace(new_spec.dependencies)
|
||||
end
|
||||
|
||||
|
@ -896,7 +882,7 @@ module Bundler
|
|||
dependencies.each do |dep|
|
||||
dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
|
||||
next unless remote || dep.current_platform?
|
||||
target_platforms = dep.gem_platforms(remote ? Resolver.sort_platforms(@platforms) : [generic_local_platform])
|
||||
target_platforms = dep.gem_platforms(remote ? @platforms : [generic_local_platform])
|
||||
deps += expand_dependency_with_platforms(dep, target_platforms)
|
||||
end
|
||||
deps
|
||||
|
@ -904,7 +890,7 @@ module Bundler
|
|||
|
||||
def expand_dependency_with_platforms(dep, platforms)
|
||||
platforms.map do |p|
|
||||
DepProxy.new(dep, p)
|
||||
DepProxy.get_proxy(dep, p)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -915,29 +901,18 @@ module Bundler
|
|||
# Record the specs available in each gem's source, so that those
|
||||
# specs will be available later when the resolver knows where to
|
||||
# look for that gemspec (or its dependencies)
|
||||
default = sources.default_source
|
||||
source_requirements = { :default => default }
|
||||
default = nil unless Bundler.feature_flag.disable_multisource?
|
||||
dependencies.each do |dep|
|
||||
next unless source = dep.source || default
|
||||
source_requirements[dep.name] = source
|
||||
end
|
||||
source_requirements = { :default => sources.default_source }.merge(dependency_source_requirements)
|
||||
metadata_dependencies.each do |dep|
|
||||
source_requirements[dep.name] = sources.metadata_source
|
||||
end
|
||||
source_requirements[:global] = index unless Bundler.feature_flag.disable_multisource?
|
||||
source_requirements[:default_bundler] = source_requirements["bundler"] || source_requirements[:default]
|
||||
source_requirements["bundler"] = sources.metadata_source # needs to come last to override
|
||||
source_requirements
|
||||
end
|
||||
|
||||
def pinned_spec_names(skip = nil)
|
||||
pinned_names = []
|
||||
default = Bundler.feature_flag.disable_multisource? && sources.default_source
|
||||
@dependencies.each do |dep|
|
||||
next unless dep_source = dep.source || default
|
||||
next if dep_source == skip
|
||||
pinned_names << dep.name
|
||||
end
|
||||
pinned_names
|
||||
dependency_source_requirements.reject {|_, source| source == skip }.keys
|
||||
end
|
||||
|
||||
def requested_groups
|
||||
|
@ -984,7 +959,7 @@ module Bundler
|
|||
next requirements if @locked_gems.dependencies[name] != dependency
|
||||
next requirements if dependency.source.is_a?(Source::Path)
|
||||
dep = Gem::Dependency.new(name, ">= #{locked_spec.version}")
|
||||
requirements[name] = DepProxy.new(dep, locked_spec.platform)
|
||||
requirements[name] = DepProxy.get_proxy(dep, locked_spec.platform)
|
||||
requirements
|
||||
end.values
|
||||
end
|
||||
|
@ -994,5 +969,17 @@ module Bundler
|
|||
|
||||
Bundler.settings[:allow_deployment_source_credential_changes] && source.equivalent_remotes?(sources.rubygems_remotes)
|
||||
end
|
||||
|
||||
def dependency_source_requirements
|
||||
@dependency_source_requirements ||= begin
|
||||
source_requirements = {}
|
||||
default = sources.default_source
|
||||
dependencies.each do |dep|
|
||||
dep_source = dep.source || default
|
||||
source_requirements[dep.name] = dep_source
|
||||
end
|
||||
source_requirements
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,19 +4,18 @@ module Bundler
|
|||
class DepProxy
|
||||
attr_reader :__platform, :dep
|
||||
|
||||
@proxies = {}
|
||||
|
||||
def self.get_proxy(dep, platform)
|
||||
@proxies[[dep, platform]] ||= new(dep, platform).freeze
|
||||
end
|
||||
|
||||
def initialize(dep, platform)
|
||||
@dep = dep
|
||||
@__platform = platform
|
||||
end
|
||||
|
||||
def hash
|
||||
@hash ||= [dep, __platform].hash
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
return false if other.class != self.class
|
||||
dep == other.dep && __platform == other.__platform
|
||||
end
|
||||
private_class_method :new
|
||||
|
||||
alias_method :eql?, :==
|
||||
|
||||
|
@ -39,6 +38,14 @@ module Bundler
|
|||
s
|
||||
end
|
||||
|
||||
def dup
|
||||
raise NoMethodError.new("DepProxy cannot be duplicated")
|
||||
end
|
||||
|
||||
def clone
|
||||
raise NoMethodError.new("DepProxy cannot be cloned")
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def method_missing(*args, &blk)
|
||||
|
|
|
@ -24,6 +24,9 @@ module Bundler
|
|||
def initialize
|
||||
@source = nil
|
||||
@sources = SourceList.new
|
||||
|
||||
@global_rubygems_sources = []
|
||||
|
||||
@git_sources = {}
|
||||
@dependencies = []
|
||||
@groups = []
|
||||
|
@ -45,6 +48,7 @@ module Bundler
|
|||
@gemfiles << expanded_gemfile_path
|
||||
contents ||= Bundler.read_file(@gemfile.to_s)
|
||||
instance_eval(contents.dup.tap{|x| x.untaint if RUBY_VERSION < "2.7" }, gemfile.to_s, 1)
|
||||
check_primary_source_safety
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
message = "There was an error " \
|
||||
"#{e.is_a?(GemfileEvalError) ? "evaluating" : "parsing"} " \
|
||||
|
@ -164,8 +168,7 @@ module Bundler
|
|||
elsif block_given?
|
||||
with_source(@sources.add_rubygems_source("remotes" => source), &blk)
|
||||
else
|
||||
check_primary_source_safety(@sources)
|
||||
@sources.global_rubygems_source = source
|
||||
@global_rubygems_sources << source
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -183,24 +186,14 @@ module Bundler
|
|||
end
|
||||
|
||||
def path(path, options = {}, &blk)
|
||||
unless block_given?
|
||||
msg = "You can no longer specify a path source by itself. Instead, \n" \
|
||||
"either use the :path option on a gem, or specify the gems that \n" \
|
||||
"bundler should find in the path source by passing a block to \n" \
|
||||
"the path method, like: \n\n" \
|
||||
" path 'dir/containing/rails' do\n" \
|
||||
" gem 'rails'\n" \
|
||||
" end\n\n"
|
||||
|
||||
raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource?
|
||||
SharedHelpers.major_deprecation(2, msg.strip)
|
||||
end
|
||||
|
||||
source_options = normalize_hash(options).merge(
|
||||
"path" => Pathname.new(path),
|
||||
"root_path" => gemfile_root,
|
||||
"gemspec" => gemspecs.find {|g| g.name == options["name"] }
|
||||
)
|
||||
|
||||
source_options["global"] = true unless block_given?
|
||||
|
||||
source = @sources.add_path_source(source_options)
|
||||
with_source(source, &blk)
|
||||
end
|
||||
|
@ -279,6 +272,11 @@ module Bundler
|
|||
raise GemfileError, "Undefined local variable or method `#{name}' for Gemfile"
|
||||
end
|
||||
|
||||
def check_primary_source_safety
|
||||
check_path_source_safety
|
||||
check_rubygems_source_safety
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_git_sources
|
||||
|
@ -440,17 +438,33 @@ repo_name ||= user_name
|
|||
end
|
||||
end
|
||||
|
||||
def check_primary_source_safety(source_list)
|
||||
return if source_list.rubygems_primary_remotes.empty? && source_list.global_rubygems_source.nil?
|
||||
def check_path_source_safety
|
||||
return if @sources.global_path_source.nil?
|
||||
|
||||
msg = "You can no longer specify a path source by itself. Instead, \n" \
|
||||
"either use the :path option on a gem, or specify the gems that \n" \
|
||||
"bundler should find in the path source by passing a block to \n" \
|
||||
"the path method, like: \n\n" \
|
||||
" path 'dir/containing/rails' do\n" \
|
||||
" gem 'rails'\n" \
|
||||
" end\n\n"
|
||||
|
||||
SharedHelpers.major_deprecation(2, msg.strip)
|
||||
end
|
||||
|
||||
def check_rubygems_source_safety
|
||||
@sources.global_rubygems_source = @global_rubygems_sources.shift
|
||||
return if @global_rubygems_sources.empty?
|
||||
|
||||
@global_rubygems_sources.each do |source|
|
||||
@sources.add_rubygems_remote(source)
|
||||
end
|
||||
|
||||
if Bundler.feature_flag.disable_multisource?
|
||||
msg = "This Gemfile contains multiple primary sources. " \
|
||||
"Each source after the first must include a block to indicate which gems " \
|
||||
"should come from that source"
|
||||
unless Bundler.feature_flag.bundler_2_mode?
|
||||
msg += ". To downgrade this error to a warning, run " \
|
||||
"`bundle config unset disable_multisource`"
|
||||
end
|
||||
"should come from that source. To downgrade this error to a warning, run " \
|
||||
"`bundle config unset disable_multisource`"
|
||||
raise GemfileEvalError, msg
|
||||
else
|
||||
Bundler::SharedHelpers.major_deprecation 2, "Your Gemfile contains multiple primary sources. " \
|
||||
|
|
|
@ -27,7 +27,6 @@ module Bundler
|
|||
|
||||
(1..10).each {|v| define_method("bundler_#{v}_mode?") { major_version >= v } }
|
||||
|
||||
settings_flag(:allow_bundler_dependency_conflicts) { bundler_3_mode? }
|
||||
settings_flag(:allow_offline_install) { bundler_3_mode? }
|
||||
settings_flag(:auto_clean_without_path) { bundler_3_mode? }
|
||||
settings_flag(:cache_all) { bundler_3_mode? }
|
||||
|
|
|
@ -137,7 +137,6 @@ module Bundler
|
|||
end
|
||||
|
||||
specs.each do |name, version, platform, dependencies, metadata|
|
||||
next if name == "bundler"
|
||||
spec = if dependencies
|
||||
EndpointSpecification.new(name, version, platform, dependencies, metadata)
|
||||
else
|
||||
|
|
|
@ -116,19 +116,21 @@ module Bundler
|
|||
|
||||
def git_push(remote = nil)
|
||||
remote ||= default_remote
|
||||
perform_git_push remote
|
||||
perform_git_push "#{remote} refs/heads/#{current_branch}"
|
||||
perform_git_push "#{remote} refs/tags/#{version_tag}"
|
||||
Bundler.ui.confirm "Pushed git commits and release tag."
|
||||
end
|
||||
|
||||
def default_remote
|
||||
remote_for_branch, status = sh_with_status(%W[git config --get branch.#{current_branch}.remote])
|
||||
return "origin" unless status.success?
|
||||
|
||||
remote_for_branch.strip
|
||||
end
|
||||
|
||||
def current_branch
|
||||
# We can replace this with `git branch --show-current` once we drop support for git < 2.22.0
|
||||
current_branch = sh(%w[git rev-parse --abbrev-ref HEAD]).gsub(%r{\Aheads/}, "").strip
|
||||
|
||||
remote_for_branch = sh(%W[git config --get branch.#{current_branch}.remote]).strip
|
||||
return "origin" if remote_for_branch.empty?
|
||||
|
||||
remote_for_branch
|
||||
sh(%w[git rev-parse --abbrev-ref HEAD]).gsub(%r{\Aheads/}, "").strip
|
||||
end
|
||||
|
||||
def allowed_push_host
|
||||
|
|
|
@ -81,8 +81,8 @@ module Bundler
|
|||
sort_dep_specs(spec_groups, locked_spec)
|
||||
end.tap do |specs|
|
||||
if DEBUG
|
||||
warn before_result
|
||||
warn " after sort_versions: #{debug_format_result(dep, specs).inspect}"
|
||||
puts before_result
|
||||
puts " after sort_versions: #{debug_format_result(dep, specs).inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "set"
|
||||
|
||||
module Bundler
|
||||
class Index
|
||||
include Enumerable
|
||||
|
@ -65,11 +63,14 @@ module Bundler
|
|||
def unsorted_search(query, base)
|
||||
results = local_search(query, base)
|
||||
|
||||
seen = results.map(&:full_name).to_set unless @sources.empty?
|
||||
seen = results.map(&:full_name).uniq unless @sources.empty?
|
||||
|
||||
@sources.each do |source|
|
||||
source.unsorted_search(query, base).each do |spec|
|
||||
results << spec if seen.add?(spec.full_name)
|
||||
next if seen.include?(spec.full_name)
|
||||
|
||||
seen << spec.full_name
|
||||
results << spec
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -170,7 +171,7 @@ module Bundler
|
|||
def dependencies_eql?(spec, other_spec)
|
||||
deps = spec.dependencies.select {|d| d.type != :development }
|
||||
other_deps = other_spec.dependencies.select {|d| d.type != :development }
|
||||
Set.new(deps) == Set.new(other_deps)
|
||||
deps.sort == other_deps.sort
|
||||
end
|
||||
|
||||
def add_source(index)
|
||||
|
|
|
@ -50,6 +50,7 @@ def gemfile(install = false, options = {}, &gemfile)
|
|||
Bundler::Plugin.gemfile_install(&gemfile) if Bundler.feature_flag.plugins?
|
||||
builder = Bundler::Dsl.new
|
||||
builder.instance_eval(&gemfile)
|
||||
builder.check_primary_source_safety
|
||||
|
||||
Bundler.settings.temporary(:frozen => false) do
|
||||
definition = builder.to_definition(nil, true)
|
||||
|
|
|
@ -82,7 +82,6 @@ module Bundler
|
|||
|
||||
if resolve_if_needed(options)
|
||||
ensure_specs_are_compatible!
|
||||
warn_on_incompatible_bundler_deps
|
||||
load_plugins
|
||||
options.delete(:jobs)
|
||||
else
|
||||
|
@ -90,6 +89,8 @@ module Bundler
|
|||
end
|
||||
install(options)
|
||||
|
||||
Gem::Specification.reset # invalidate gem specification cache so that installed gems are immediately available
|
||||
|
||||
lock unless Bundler.frozen_bundle?
|
||||
Standalone.new(options[:standalone], @definition).generate if options[:standalone]
|
||||
end
|
||||
|
@ -265,22 +266,6 @@ module Bundler
|
|||
end
|
||||
end
|
||||
|
||||
def warn_on_incompatible_bundler_deps
|
||||
bundler_version = Gem::Version.create(Bundler::VERSION)
|
||||
@definition.specs.each do |spec|
|
||||
spec.dependencies.each do |dep|
|
||||
next if dep.type == :development
|
||||
next unless dep.name == "bundler".freeze
|
||||
next if dep.requirement.satisfied_by?(bundler_version)
|
||||
|
||||
Bundler.ui.warn "#{spec.name} (#{spec.version}) has dependency" \
|
||||
" #{SharedHelpers.pretty_dependency(dep)}" \
|
||||
", which is unsatisfied by the current bundler version #{VERSION}" \
|
||||
", so the dependency is being ignored"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def install_in_parallel(size, standalone, force = false)
|
||||
spec_installations = ParallelInstaller.call(self, @definition.specs, size, standalone, force)
|
||||
spec_installations.each do |installation|
|
||||
|
|
|
@ -15,6 +15,7 @@ module Bundler
|
|||
file.puts "ruby_engine = RUBY_ENGINE"
|
||||
file.puts "ruby_version = RbConfig::CONFIG[\"ruby_version\"]"
|
||||
file.puts "path = File.expand_path('..', __FILE__)"
|
||||
file.puts reverse_rubygems_kernel_mixin
|
||||
paths.each do |path|
|
||||
file.puts %($:.unshift File.expand_path("\#{path}/#{path}"))
|
||||
end
|
||||
|
@ -48,5 +49,19 @@ module Bundler
|
|||
error_message = "#{spec.name} #{spec.version} has an invalid gemspec"
|
||||
raise Gem::InvalidSpecificationException.new(error_message)
|
||||
end
|
||||
|
||||
def reverse_rubygems_kernel_mixin
|
||||
<<~END
|
||||
kernel = (class << ::Kernel; self; end)
|
||||
[kernel, ::Kernel].each do |k|
|
||||
if k.private_method_defined?(:gem_original_require)
|
||||
private_require = k.private_method_defined?(:require)
|
||||
k.send(:remove_method, :require)
|
||||
k.send(:define_method, :require, k.instance_method(:gem_original_require))
|
||||
k.send(:private, :require) if private_require
|
||||
end
|
||||
end
|
||||
END
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,22 +4,6 @@ require_relative "match_platform"
|
|||
|
||||
module Bundler
|
||||
class LazySpecification
|
||||
Identifier = Struct.new(:name, :version, :platform)
|
||||
class Identifier
|
||||
include Comparable
|
||||
def <=>(other)
|
||||
return unless other.is_a?(Identifier)
|
||||
[name, version, platform_string] <=> [other.name, other.version, other.platform_string]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def platform_string
|
||||
platform_string = platform.to_s
|
||||
platform_string == Index::RUBY ? Index::NULL : platform_string
|
||||
end
|
||||
end
|
||||
|
||||
include MatchPlatform
|
||||
|
||||
attr_reader :name, :version, :dependencies, :platform
|
||||
|
@ -108,7 +92,7 @@ module Bundler
|
|||
end
|
||||
|
||||
def identifier
|
||||
@__identifier ||= Identifier.new(name, version, platform)
|
||||
@__identifier ||= [name, version, platform_string]
|
||||
end
|
||||
|
||||
def git_version
|
||||
|
@ -116,6 +100,13 @@ module Bundler
|
|||
" #{source.revision[0..6]}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def platform_string
|
||||
platform_string = platform.to_s
|
||||
platform_string == Index::RUBY ? Index::NULL : platform_string
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def to_ary
|
||||
|
@ -140,7 +131,7 @@ module Bundler
|
|||
# explicitly add a more specific platform.
|
||||
#
|
||||
def ruby_platform_materializes_to_ruby_platform?
|
||||
!Bundler.most_specific_locked_platform?(Gem::Platform::RUBY)
|
||||
!Bundler.most_specific_locked_platform?(Gem::Platform::RUBY) || Bundler.settings[:force_ruby_platform]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -64,8 +64,6 @@ module Bundler
|
|||
@state = nil
|
||||
@specs = {}
|
||||
|
||||
@rubygems_aggregate = Source::Rubygems.new
|
||||
|
||||
if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
|
||||
raise LockfileError, "Your #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)} contains merge conflicts.\n" \
|
||||
"Run `git checkout HEAD -- #{Bundler.default_lockfile.relative_path_from(SharedHelpers.pwd)}` first to get a clean lock."
|
||||
|
@ -89,7 +87,6 @@ module Bundler
|
|||
send("parse_#{@state}", line)
|
||||
end
|
||||
end
|
||||
@sources << @rubygems_aggregate unless Bundler.feature_flag.disable_multisource?
|
||||
@specs = @specs.values.sort_by(&:identifier)
|
||||
warn_for_outdated_bundler_version
|
||||
rescue ArgumentError => e
|
||||
|
@ -134,16 +131,19 @@ module Bundler
|
|||
@sources << @current_source
|
||||
end
|
||||
when GEM
|
||||
if Bundler.feature_flag.disable_multisource?
|
||||
source_remotes = Array(@opts["remote"])
|
||||
|
||||
if source_remotes.size == 1
|
||||
@opts["remotes"] = @opts.delete("remote")
|
||||
@current_source = TYPES[@type].from_lock(@opts)
|
||||
@sources << @current_source
|
||||
else
|
||||
Array(@opts["remote"]).each do |url|
|
||||
@rubygems_aggregate.add_remote(url)
|
||||
source_remotes.each do |url|
|
||||
rubygems_aggregate.add_remote(url)
|
||||
end
|
||||
@current_source = @rubygems_aggregate
|
||||
@current_source = rubygems_aggregate
|
||||
end
|
||||
|
||||
@sources << @current_source
|
||||
when PLUGIN
|
||||
@current_source = Plugin.source_from_lock(@opts)
|
||||
@sources << @current_source
|
||||
|
@ -245,5 +245,9 @@ module Bundler
|
|||
def parse_ruby(line)
|
||||
@ruby_version = line.strip
|
||||
end
|
||||
|
||||
def rubygems_aggregate
|
||||
@rubygems_aggregate ||= Source::Rubygems.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-ADD" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-ADD" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-add\fR \- Add gem to the Gemfile and run bundle install
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-BINSTUBS" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-BINSTUBS" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-binstubs\fR \- Install the binstubs of the listed gems
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CACHE" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-CACHE" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-cache\fR \- Package your needed \fB\.gem\fR files into your application
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CHECK" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-CHECK" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-check\fR \- Verifies if dependencies are satisfied by installed gems
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CLEAN" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-CLEAN" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-clean\fR \- Cleans up unused gems in your bundler directory
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-CONFIG" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-CONFIG" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-config\fR \- Set bundler configuration options
|
||||
|
@ -136,9 +136,6 @@ Any periods in the configuration keys must be replaced with two underscores when
|
|||
The following is a list of all configuration keys and their purpose\. You can learn more about their operation in bundle install(1) \fIbundle\-install\.1\.html\fR\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBallow_bundler_dependency_conflicts\fR (\fBBUNDLE_ALLOW_BUNDLER_DEPENDENCY_CONFLICTS\fR): Allow resolving to specifications that have dependencies on \fBbundler\fR that are incompatible with the running Bundler version\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBallow_deployment_source_credential_changes\fR (\fBBUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES\fR): When in deployment mode, allow changing the credentials to a gem\'s source\. Ex: \fBhttps://some\.host\.com/gems/path/\fR \-> \fBhttps://user_name:password@some\.host\.com/gems/path\fR
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
|
@ -184,6 +181,9 @@ The following is a list of all configuration keys and their purpose\. You can le
|
|||
\fBdisable_local_branch_check\fR (\fBBUNDLE_DISABLE_LOCAL_BRANCH_CHECK\fR): Allow Bundler to use a local git override without a branch specified in the Gemfile\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBdisable_local_revision_check\fR (\fBBUNDLE_DISABLE_LOCAL_REVISION_CHECK\fR): Allow Bundler to use a local git override without checking if the revision present in the lockfile is present in the repository\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
\fBdisable_multisource\fR (\fBBUNDLE_DISABLE_MULTISOURCE\fR): When set, Gemfiles containing multiple sources will produce errors instead of warnings\. Use \fBbundle config unset disable_multisource\fR to unset\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
|
|
|
@ -133,9 +133,6 @@ the environment variable `BUNDLE_LOCAL__RACK`.
|
|||
The following is a list of all configuration keys and their purpose. You can
|
||||
learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
||||
|
||||
* `allow_bundler_dependency_conflicts` (`BUNDLE_ALLOW_BUNDLER_DEPENDENCY_CONFLICTS`):
|
||||
Allow resolving to specifications that have dependencies on `bundler` that
|
||||
are incompatible with the running Bundler version.
|
||||
* `allow_deployment_source_credential_changes` (`BUNDLE_ALLOW_DEPLOYMENT_SOURCE_CREDENTIAL_CHANGES`):
|
||||
When in deployment mode, allow changing the credentials to a gem's source.
|
||||
Ex: `https://some.host.com/gems/path/` -> `https://user_name:password@some.host.com/gems/path`
|
||||
|
@ -178,6 +175,9 @@ learn more about their operation in [bundle install(1)](bundle-install.1.html).
|
|||
* `disable_local_branch_check` (`BUNDLE_DISABLE_LOCAL_BRANCH_CHECK`):
|
||||
Allow Bundler to use a local git override without a branch specified in the
|
||||
Gemfile.
|
||||
* `disable_local_revision_check` (`BUNDLE_DISABLE_LOCAL_REVISION_CHECK`):
|
||||
Allow Bundler to use a local git override without checking if the revision
|
||||
present in the lockfile is present in the repository.
|
||||
* `disable_multisource` (`BUNDLE_DISABLE_MULTISOURCE`):
|
||||
When set, Gemfiles containing multiple sources will produce errors
|
||||
instead of warnings.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-DOCTOR" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-DOCTOR" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-doctor\fR \- Checks the bundle for common problems
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-EXEC" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-EXEC" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-exec\fR \- Execute a command in the context of the bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-GEM" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-GEM" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-gem\fR \- Generate a project skeleton for creating a rubygem
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INFO" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-INFO" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-info\fR \- Show information for the given gem in your bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INIT" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-INIT" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-init\fR \- Generates a Gemfile into the current working directory
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INJECT" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-INJECT" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-inject\fR \- Add named gem(s) with version requirements to Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-INSTALL" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-INSTALL" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-LIST" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-LIST" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-list\fR \- List all the gems in the bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-LOCK" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-LOCK" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-lock\fR \- Creates / Updates a lockfile without installing
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-OPEN" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-OPEN" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-open\fR \- Opens the source directory for a gem in your bundle
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-OUTDATED" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-OUTDATED" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-outdated\fR \- List installed gems with newer versions available
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-PLATFORM" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-PLATFORM" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-platform\fR \- Displays platform compatibility information
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-PRISTINE" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-PRISTINE" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-pristine\fR \- Restores installed gems to their pristine condition
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-REMOVE" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-REMOVE" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-remove\fR \- Removes gems from the Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-SHOW" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-SHOW" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-show\fR \- Shows all the gems in your bundle, or the path to a gem
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-UPDATE" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-UPDATE" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-update\fR \- Update your gems to the latest available versions
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE\-VIZ" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE\-VIZ" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "BUNDLE" "1" "December 2020" "" ""
|
||||
.TH "BUNDLE" "1" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBbundle\fR \- Ruby Dependency Management
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "GEMFILE" "5" "December 2020" "" ""
|
||||
.TH "GEMFILE" "5" "January 2021" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
|
||||
|
|
|
@ -105,6 +105,7 @@ module Bundler
|
|||
else
|
||||
builder.eval_gemfile(gemfile)
|
||||
end
|
||||
builder.check_primary_source_safety
|
||||
definition = builder.to_definition(nil, true)
|
||||
|
||||
return if definition.dependencies.empty?
|
||||
|
|
|
@ -16,15 +16,13 @@ module Bundler
|
|||
|
||||
version = options[:version] || [">= 0"]
|
||||
|
||||
Bundler.settings.temporary(:disable_multisource => false) do
|
||||
if options[:git]
|
||||
install_git(names, version, options)
|
||||
elsif options[:local_git]
|
||||
install_local_git(names, version, options)
|
||||
else
|
||||
sources = options[:source] || Bundler.rubygems.sources
|
||||
install_rubygems(names, version, sources)
|
||||
end
|
||||
if options[:git]
|
||||
install_git(names, version, options)
|
||||
elsif options[:local_git]
|
||||
install_local_git(names, version, options)
|
||||
else
|
||||
sources = options[:source] || Bundler.rubygems.sources
|
||||
install_rubygems(names, version, sources)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -79,7 +77,7 @@ module Bundler
|
|||
source_list = SourceList.new
|
||||
|
||||
source_list.add_git_source(git_source_options) if git_source_options
|
||||
source_list.add_rubygems_source("remotes" => rubygems_source) if rubygems_source
|
||||
source_list.global_rubygems_source = rubygems_source if rubygems_source
|
||||
|
||||
deps = names.map {|name| Dependency.new name, version }
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@ module Bundler
|
|||
path_sources + git_sources + rubygems_sources + [metadata_source]
|
||||
end
|
||||
|
||||
def default_source
|
||||
git_sources.first || global_rubygems_source
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rubygems_aggregate_class
|
||||
|
|
|
@ -5,6 +5,8 @@ module Bundler
|
|||
require_relative "vendored_molinillo"
|
||||
require_relative "resolver/spec_group"
|
||||
|
||||
include GemHelpers
|
||||
|
||||
# Figures out the best possible configuration of gems that satisfies
|
||||
# the list of passed dependencies and any child dependencies without
|
||||
# causing any gem activation errors.
|
||||
|
@ -15,31 +17,38 @@ module Bundler
|
|||
# ==== Returns
|
||||
# <GemBundle>,nil:: If the list of dependencies can be resolved, a
|
||||
# collection of gemspecs is returned. Otherwise, nil is returned.
|
||||
def self.resolve(requirements, index, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
|
||||
platforms = Set.new(platforms) if platforms
|
||||
def self.resolve(requirements, source_requirements = {}, base = [], gem_version_promoter = GemVersionPromoter.new, additional_base_requirements = [], platforms = nil)
|
||||
base = SpecSet.new(base) unless base.is_a?(SpecSet)
|
||||
resolver = new(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
||||
resolver = new(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
||||
result = resolver.start(requirements)
|
||||
SpecSet.new(result)
|
||||
end
|
||||
|
||||
def initialize(index, source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
||||
@index = index
|
||||
def initialize(source_requirements, base, gem_version_promoter, additional_base_requirements, platforms)
|
||||
@source_requirements = source_requirements
|
||||
|
||||
@index_requirements = source_requirements.each_with_object({}) do |source_requirement, index_requirements|
|
||||
name, source = source_requirement
|
||||
index_requirements[name] = name == :global ? source : source.specs
|
||||
end
|
||||
|
||||
@base = base
|
||||
@resolver = Molinillo::Resolver.new(self, self)
|
||||
@search_for = {}
|
||||
@base_dg = Molinillo::DependencyGraph.new
|
||||
@base.each do |ls|
|
||||
dep = Dependency.new(ls.name, ls.version)
|
||||
@base_dg.add_vertex(ls.name, DepProxy.new(dep, ls.platform), true)
|
||||
@base_dg.add_vertex(ls.name, DepProxy.get_proxy(dep, ls.platform), true)
|
||||
end
|
||||
additional_base_requirements.each {|d| @base_dg.add_vertex(d.name, d) }
|
||||
@platforms = platforms
|
||||
@platforms = platforms.reject {|p| p != Gem::Platform::RUBY && (platforms - [p]).any? {|pl| generic(pl) == p } }
|
||||
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
|
||||
@gem_version_promoter = gem_version_promoter
|
||||
@allow_bundler_dependency_conflicts = Bundler.feature_flag.allow_bundler_dependency_conflicts?
|
||||
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
|
||||
@lockfile_uses_separate_rubygems_sources = Bundler.feature_flag.disable_multisource?
|
||||
@no_aggregate_global_source = @source_requirements[:global].nil?
|
||||
|
||||
@variant_specific_names = []
|
||||
@generic_names = ["Ruby\0", "RubyGems\0"]
|
||||
end
|
||||
|
||||
def start(requirements)
|
||||
|
@ -75,7 +84,7 @@ module Bundler
|
|||
return unless debug?
|
||||
debug_info = yield
|
||||
debug_info = debug_info.inspect unless debug_info.is_a?(String)
|
||||
puts debug_info.split("\n").map {|s| "BUNDLER: " + " " * depth + s }
|
||||
puts debug_info.split("\n").map {|s| depth == 0 ? "BUNDLER: #{s}" : "BUNDLER(#{depth}): #{s}" }
|
||||
end
|
||||
|
||||
def debug?
|
||||
|
@ -103,16 +112,25 @@ module Bundler
|
|||
include Molinillo::SpecificationProvider
|
||||
|
||||
def dependencies_for(specification)
|
||||
specification.dependencies_for_activated_platforms
|
||||
all_dependencies = specification.dependencies_for_activated_platforms
|
||||
|
||||
if @variant_specific_names.include?(specification.name)
|
||||
@variant_specific_names |= all_dependencies.map(&:name) - @generic_names
|
||||
else
|
||||
generic_names, variant_specific_names = specification.partitioned_dependency_names_for_activated_platforms
|
||||
@variant_specific_names |= variant_specific_names - @generic_names
|
||||
@generic_names |= generic_names
|
||||
end
|
||||
|
||||
all_dependencies
|
||||
end
|
||||
|
||||
def search_for(dependency_proxy)
|
||||
platform = dependency_proxy.__platform
|
||||
dependency = dependency_proxy.dep
|
||||
@search_for[dependency_proxy] ||= begin
|
||||
name = dependency.name
|
||||
index = index_for(dependency)
|
||||
results = index.search(dependency, @base[name])
|
||||
name = dependency.name
|
||||
search_result = @search_for[dependency_proxy] ||= begin
|
||||
results = results_for(dependency, @base[name])
|
||||
|
||||
if vertex = @base_dg.vertex_named(name)
|
||||
locked_requirement = vertex.payload.requirement
|
||||
|
@ -137,55 +155,67 @@ module Bundler
|
|||
end
|
||||
nested.reduce([]) do |groups, (version, specs)|
|
||||
next groups if locked_requirement && !locked_requirement.satisfied_by?(version)
|
||||
spec_group = SpecGroup.new(specs)
|
||||
spec_group.ignores_bundler_dependencies = @allow_bundler_dependency_conflicts
|
||||
groups << spec_group
|
||||
|
||||
specs_by_platform = Hash.new do |current_specs, current_platform|
|
||||
current_specs[current_platform] = select_best_platform_match(specs, current_platform)
|
||||
end
|
||||
|
||||
spec_group_ruby = SpecGroup.create_for(specs_by_platform, [Gem::Platform::RUBY], Gem::Platform::RUBY)
|
||||
groups << spec_group_ruby if spec_group_ruby
|
||||
|
||||
next groups if @resolving_only_for_ruby
|
||||
|
||||
spec_group = SpecGroup.create_for(specs_by_platform, @platforms, platform)
|
||||
groups << spec_group if spec_group
|
||||
|
||||
groups
|
||||
end
|
||||
else
|
||||
[]
|
||||
end
|
||||
# GVP handles major itself, but it's still a bit risky to trust it with it
|
||||
# until we get it settled with new behavior. For 2.x it can take over all cases.
|
||||
search = if !@use_gvp
|
||||
if !@use_gvp
|
||||
spec_groups
|
||||
else
|
||||
@gem_version_promoter.sort_versions(dependency, spec_groups)
|
||||
end
|
||||
selected_sgs = []
|
||||
search.each do |sg|
|
||||
next unless sg.for?(platform)
|
||||
sg_all_platforms = sg.copy_for(self.class.sort_platforms(@platforms).reverse)
|
||||
next unless sg_all_platforms
|
||||
|
||||
selected_sgs << sg_all_platforms
|
||||
|
||||
next if sg_all_platforms.activated_platforms == [Gem::Platform::RUBY]
|
||||
# Add a spec group for "non platform specific spec" as the fallback
|
||||
# spec group.
|
||||
sg_ruby = sg.copy_for([Gem::Platform::RUBY])
|
||||
selected_sgs.insert(-2, sg_ruby) if sg_ruby
|
||||
end
|
||||
selected_sgs
|
||||
end
|
||||
|
||||
unless search_result.empty?
|
||||
specific_dependency = @variant_specific_names.include?(name)
|
||||
return search_result unless specific_dependency
|
||||
|
||||
search_result.each do |sg|
|
||||
if @generic_names.include?(name)
|
||||
@variant_specific_names -= [name]
|
||||
sg.activate_all_platforms!
|
||||
else
|
||||
sg.activate_platform!(platform)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
search_result
|
||||
end
|
||||
|
||||
def index_for(dependency)
|
||||
source = @source_requirements[dependency.name]
|
||||
source = @index_requirements[dependency.name]
|
||||
if source
|
||||
source.specs
|
||||
elsif @lockfile_uses_separate_rubygems_sources
|
||||
source
|
||||
elsif @no_aggregate_global_source
|
||||
Index.build do |idx|
|
||||
if dependency.all_sources
|
||||
dependency.all_sources.each {|s| idx.add_source(s.specs) if s }
|
||||
else
|
||||
idx.add_source @source_requirements[:default].specs
|
||||
end
|
||||
dependency.all_sources.each {|s| idx.add_source(s.specs) }
|
||||
end
|
||||
else
|
||||
@index
|
||||
@index_requirements[:global]
|
||||
end
|
||||
end
|
||||
|
||||
def results_for(dependency, base)
|
||||
index_for(dependency).search(dependency, base)
|
||||
end
|
||||
|
||||
def name_for(dependency)
|
||||
dependency.name
|
||||
end
|
||||
|
@ -206,21 +236,27 @@ module Bundler
|
|||
requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
|
||||
end
|
||||
|
||||
def dependencies_equal?(dependencies, other_dependencies)
|
||||
dependencies.map(&:dep) == other_dependencies.map(&:dep)
|
||||
end
|
||||
|
||||
def relevant_sources_for_vertex(vertex)
|
||||
if vertex.root?
|
||||
[@source_requirements[vertex.name]]
|
||||
elsif @lockfile_uses_separate_rubygems_sources
|
||||
elsif @no_aggregate_global_source
|
||||
vertex.recursive_predecessors.map do |v|
|
||||
@source_requirements[v.name]
|
||||
end << @source_requirements[:default]
|
||||
end.compact << @source_requirements[:default]
|
||||
else
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
def sort_dependencies(dependencies, activated, conflicts)
|
||||
dependencies.sort_by do |dependency|
|
||||
dependency.all_sources = relevant_sources_for_vertex(activated.vertex_named(dependency.name))
|
||||
name = name_for(dependency)
|
||||
vertex = activated.vertex_named(name)
|
||||
dependency.all_sources = relevant_sources_for_vertex(vertex)
|
||||
[
|
||||
@base_dg.vertex_named(name) ? 0 : 1,
|
||||
vertex.payload ? 0 : 1,
|
||||
|
@ -233,13 +269,6 @@ module Bundler
|
|||
end
|
||||
end
|
||||
|
||||
# Sort platforms from most general to most specific
|
||||
def self.sort_platforms(platforms)
|
||||
platforms.sort_by do |platform|
|
||||
platform_sort_key(platform)
|
||||
end
|
||||
end
|
||||
|
||||
def self.platform_sort_key(platform)
|
||||
# Prefer specific platform to not specific platform
|
||||
return ["99-LAST", "", "", ""] if Gem::Platform::RUBY == platform
|
||||
|
@ -294,7 +323,7 @@ module Bundler
|
|||
"If you are updating multiple gems in your Gemfile at once,\n" \
|
||||
"try passing them all to `bundle update`"
|
||||
elsif source = @source_requirements[name]
|
||||
specs = source.specs[name]
|
||||
specs = source.specs.search(name)
|
||||
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 << if versions_with_platforms.any?
|
||||
|
@ -303,7 +332,7 @@ module Bundler
|
|||
"The source does not contain any versions of '#{name}'"
|
||||
end
|
||||
else
|
||||
message = "Could not find gem '#{requirement}' in any of the gem sources " \
|
||||
message = "Could not find gem '#{SharedHelpers.pretty_dependency(requirement)}' in any of the gem sources " \
|
||||
"listed in your Gemfile#{cache_message}."
|
||||
end
|
||||
raise GemNotFound, message
|
||||
|
@ -324,10 +353,16 @@ module Bundler
|
|||
def version_conflict_message(e)
|
||||
# only show essential conflicts, if possible
|
||||
conflicts = e.conflicts.dup
|
||||
conflicts.delete_if do |_name, conflict|
|
||||
deps = conflict.requirement_trees.map(&:last).flatten(1)
|
||||
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
||||
|
||||
if conflicts["bundler"]
|
||||
conflicts.replace("bundler" => conflicts["bundler"])
|
||||
else
|
||||
conflicts.delete_if do |_name, conflict|
|
||||
deps = conflict.requirement_trees.map(&:last).flatten(1)
|
||||
!Bundler::VersionRanges.empty?(*Bundler::VersionRanges.for_many(deps.map(&:requirement)))
|
||||
end
|
||||
end
|
||||
|
||||
e = Molinillo::VersionConflict.new(conflicts, e.specification_provider) unless conflicts.empty?
|
||||
|
||||
solver_name = "Bundler"
|
||||
|
@ -355,15 +390,25 @@ module Bundler
|
|||
:additional_message_for_conflict => lambda do |o, name, conflict|
|
||||
if name == "bundler"
|
||||
o << %(\n Current Bundler version:\n bundler (#{Bundler::VERSION}))
|
||||
other_bundler_required = !conflict.requirement.requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
||||
end
|
||||
|
||||
if name == "bundler" && other_bundler_required
|
||||
o << "\n"
|
||||
o << "This Gemfile requires a different version of Bundler.\n"
|
||||
o << "Perhaps you need to update Bundler by running `gem install bundler`?\n"
|
||||
end
|
||||
if conflict.locked_requirement
|
||||
conflict_dependency = conflict.requirement
|
||||
conflict_requirement = conflict_dependency.requirement
|
||||
other_bundler_required = !conflict_requirement.satisfied_by?(Gem::Version.new(Bundler::VERSION))
|
||||
|
||||
if other_bundler_required
|
||||
o << "\n\n"
|
||||
|
||||
candidate_specs = @index_requirements[:default_bundler].search(conflict_dependency)
|
||||
if candidate_specs.any?
|
||||
target_version = candidate_specs.last.version
|
||||
new_command = [File.basename($PROGRAM_NAME), "_#{target_version}_", *ARGV].join(" ")
|
||||
o << "Your bundle requires a different version of Bundler than the one you're running.\n"
|
||||
o << "Install the necessary version with `gem install bundler:#{target_version}` and rerun bundler using `#{new_command}`\n"
|
||||
else
|
||||
o << "Your bundle requires a different version of Bundler than the one you're running, and that version could not be found.\n"
|
||||
end
|
||||
end
|
||||
elsif conflict.locked_requirement
|
||||
o << "\n"
|
||||
o << %(Running `bundle update` will rebuild your snapshot from scratch, using only\n)
|
||||
o << %(the gems in your Gemfile, which may resolve the conflict.\n)
|
||||
|
@ -372,14 +417,8 @@ module Bundler
|
|||
|
||||
relevant_sources = if conflict.requirement.source
|
||||
[conflict.requirement.source]
|
||||
elsif conflict.requirement.all_sources
|
||||
conflict.requirement.all_sources
|
||||
elsif @lockfile_uses_separate_rubygems_sources
|
||||
# every conflict should have an explicit group of sources when we
|
||||
# enforce strict pinning
|
||||
raise "no source set for #{conflict}"
|
||||
else
|
||||
[]
|
||||
conflict.requirement.all_sources
|
||||
end.compact.map(&:to_s).uniq.sort
|
||||
|
||||
metadata_requirement = name.end_with?("\0")
|
||||
|
@ -416,23 +455,21 @@ module Bundler
|
|||
def validate_resolved_specs!(resolved_specs)
|
||||
resolved_specs.each do |v|
|
||||
name = v.name
|
||||
next unless sources = relevant_sources_for_vertex(v)
|
||||
sources.compact!
|
||||
sources = relevant_sources_for_vertex(v)
|
||||
next unless sources.any?
|
||||
if default_index = sources.index(@source_requirements[:default])
|
||||
sources.delete_at(default_index)
|
||||
end
|
||||
sources.reject! {|s| s.specs[name].empty? }
|
||||
sources.reject! {|s| s.specs.search(name).empty? }
|
||||
sources.uniq!
|
||||
next if sources.size <= 1
|
||||
|
||||
multisource_disabled = Bundler.feature_flag.disable_multisource?
|
||||
|
||||
msg = ["The gem '#{name}' was found in multiple relevant sources."]
|
||||
msg.concat sources.map {|s| " * #{s}" }.sort
|
||||
msg << "You #{multisource_disabled ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
|
||||
msg << "You #{@no_aggregate_global_source ? :must : :should} add this gem to the source block for the source you wish it to be installed from."
|
||||
msg = msg.join("\n")
|
||||
|
||||
raise SecurityError, msg if multisource_disabled
|
||||
raise SecurityError, msg if @no_aggregate_global_source
|
||||
Bundler.ui.warn "Warning: #{msg}"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,28 +3,37 @@
|
|||
module Bundler
|
||||
class Resolver
|
||||
class SpecGroup
|
||||
include GemHelpers
|
||||
|
||||
attr_accessor :name, :version, :source
|
||||
attr_accessor :ignores_bundler_dependencies, :activated_platforms
|
||||
attr_accessor :activated_platforms
|
||||
|
||||
def initialize(all_specs)
|
||||
@all_specs = all_specs
|
||||
raise ArgumentError, "cannot initialize with an empty value" unless exemplary_spec = all_specs.first
|
||||
def self.create_for(specs, all_platforms, specific_platform)
|
||||
specific_platform_specs = specs[specific_platform]
|
||||
return unless specific_platform_specs.any?
|
||||
|
||||
platforms = all_platforms.select {|p| specs[p].any? }
|
||||
|
||||
new(specific_platform_specs.first, specs, platforms)
|
||||
end
|
||||
|
||||
def initialize(exemplary_spec, specs, relevant_platforms)
|
||||
@exemplary_spec = exemplary_spec
|
||||
@name = exemplary_spec.name
|
||||
@version = exemplary_spec.version
|
||||
@source = exemplary_spec.source
|
||||
|
||||
@activated_platforms = []
|
||||
@dependencies = nil
|
||||
@specs = Hash.new do |specs, platform|
|
||||
specs[platform] = select_best_platform_match(all_specs, platform)
|
||||
@all_platforms = relevant_platforms
|
||||
@activated_platforms = relevant_platforms
|
||||
@dependencies = Hash.new do |dependencies, platforms|
|
||||
dependencies[platforms] = dependencies_for(platforms)
|
||||
end
|
||||
@ignores_bundler_dependencies = true
|
||||
@partitioned_dependency_names = Hash.new do |partitioned_dependency_names, platforms|
|
||||
partitioned_dependency_names[platforms] = partitioned_dependency_names_for(platforms)
|
||||
end
|
||||
@specs = specs
|
||||
end
|
||||
|
||||
def to_specs
|
||||
@activated_platforms.map do |p|
|
||||
activated_platforms.map do |p|
|
||||
specs = @specs[p]
|
||||
next unless specs.any?
|
||||
|
||||
|
@ -36,18 +45,12 @@ module Bundler
|
|||
end.flatten.compact.uniq
|
||||
end
|
||||
|
||||
def copy_for(platforms)
|
||||
platforms.select! {|p| for?(p) }
|
||||
return unless platforms.any?
|
||||
|
||||
copied_sg = self.class.new(@all_specs)
|
||||
copied_sg.ignores_bundler_dependencies = @ignores_bundler_dependencies
|
||||
copied_sg.activated_platforms = platforms
|
||||
copied_sg
|
||||
def activate_platform!(platform)
|
||||
self.activated_platforms = [platform]
|
||||
end
|
||||
|
||||
def for?(platform)
|
||||
@specs[platform].any?
|
||||
def activate_all_platforms!
|
||||
self.activated_platforms = @all_platforms
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -56,11 +59,11 @@ module Bundler
|
|||
end
|
||||
|
||||
def dependencies_for_activated_platforms
|
||||
dependencies = @activated_platforms.map {|p| __dependencies[p] }
|
||||
metadata_dependencies = @activated_platforms.map do |platform|
|
||||
metadata_dependencies(@specs[platform].first, platform)
|
||||
end
|
||||
dependencies.concat(metadata_dependencies).flatten
|
||||
@dependencies[activated_platforms]
|
||||
end
|
||||
|
||||
def partitioned_dependency_names_for_activated_platforms
|
||||
@partitioned_dependency_names[activated_platforms]
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
|
@ -86,34 +89,43 @@ module Bundler
|
|||
protected
|
||||
|
||||
def sorted_activated_platforms
|
||||
@activated_platforms.sort_by(&:to_s)
|
||||
activated_platforms.sort_by(&:to_s)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def __dependencies
|
||||
@dependencies = Hash.new do |dependencies, platform|
|
||||
dependencies[platform] = []
|
||||
specs = @specs[platform]
|
||||
if spec = specs.first
|
||||
spec.dependencies.each do |dep|
|
||||
next if dep.type == :development
|
||||
next if @ignores_bundler_dependencies && dep.name == "bundler".freeze
|
||||
dependencies[platform] << DepProxy.new(dep, platform)
|
||||
end
|
||||
end
|
||||
dependencies[platform]
|
||||
end
|
||||
def dependencies_for(platforms)
|
||||
platforms.map do |platform|
|
||||
__dependencies(platform) + metadata_dependencies(platform)
|
||||
end.flatten
|
||||
end
|
||||
|
||||
def metadata_dependencies(spec, platform)
|
||||
return [] unless spec && spec.is_a?(Gem::Specification)
|
||||
def partitioned_dependency_names_for(platforms)
|
||||
return @dependencies[platforms].map(&:name), [] if platforms.size == 1
|
||||
|
||||
@dependencies[platforms].partition do |dep_proxy|
|
||||
@dependencies[platforms].count {|dp| dp.dep == dep_proxy.dep } == platforms.size
|
||||
end.map {|deps| deps.map(&:name) }
|
||||
end
|
||||
|
||||
def __dependencies(platform)
|
||||
dependencies = []
|
||||
@specs[platform].first.dependencies.each do |dep|
|
||||
next if dep.type == :development
|
||||
dependencies << DepProxy.get_proxy(dep, platform)
|
||||
end
|
||||
dependencies
|
||||
end
|
||||
|
||||
def metadata_dependencies(platform)
|
||||
spec = @specs[platform].first
|
||||
return [] unless spec.is_a?(Gem::Specification)
|
||||
dependencies = []
|
||||
if !spec.required_ruby_version.nil? && !spec.required_ruby_version.none?
|
||||
dependencies << DepProxy.new(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
|
||||
dependencies << DepProxy.get_proxy(Gem::Dependency.new("Ruby\0", spec.required_ruby_version), platform)
|
||||
end
|
||||
if !spec.required_rubygems_version.nil? && !spec.required_rubygems_version.none?
|
||||
dependencies << DepProxy.new(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
|
||||
dependencies << DepProxy.get_proxy(Gem::Dependency.new("RubyGems\0", spec.required_rubygems_version), platform)
|
||||
end
|
||||
dependencies
|
||||
end
|
||||
|
|
|
@ -158,6 +158,22 @@ module Gem
|
|||
end
|
||||
end
|
||||
|
||||
if Gem::Requirement.new("~> 2.0").hash == Gem::Requirement.new("~> 2.0.0").hash
|
||||
class Requirement
|
||||
module CorrectHashForLambdaOperator
|
||||
def hash
|
||||
if requirements.any? {|r| r.first == "~>" }
|
||||
requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
prepend CorrectHashForLambdaOperator
|
||||
end
|
||||
end
|
||||
|
||||
class Platform
|
||||
JAVA = Gem::Platform.new("java") unless defined?(JAVA)
|
||||
MSWIN = Gem::Platform.new("mswin32") unless defined?(MSWIN)
|
||||
|
|
|
@ -8,6 +8,53 @@ module Bundler
|
|||
# Bundler needs to install gems regardless of binstub overwriting
|
||||
end
|
||||
|
||||
def install
|
||||
pre_install_checks
|
||||
|
||||
run_pre_install_hooks
|
||||
|
||||
spec.loaded_from = spec_file
|
||||
|
||||
# Completely remove any previous gem files
|
||||
FileUtils.rm_rf gem_dir
|
||||
FileUtils.rm_rf spec.extension_dir
|
||||
|
||||
FileUtils.mkdir_p gem_dir, :mode => 0o755
|
||||
|
||||
extract_files
|
||||
|
||||
build_extensions
|
||||
write_build_info_file
|
||||
run_post_build_hooks
|
||||
|
||||
generate_bin
|
||||
generate_plugins
|
||||
|
||||
write_spec
|
||||
write_cache_file
|
||||
|
||||
say spec.post_install_message unless spec.post_install_message.nil?
|
||||
|
||||
run_post_install_hooks
|
||||
|
||||
spec
|
||||
end
|
||||
|
||||
def generate_plugins
|
||||
return unless Gem::Installer.instance_methods(false).include?(:generate_plugins)
|
||||
|
||||
latest = Gem::Specification.stubs_for(spec.name).first
|
||||
return if latest && latest.version > spec.version
|
||||
|
||||
ensure_writable_dir @plugins_dir
|
||||
|
||||
if spec.plugins.empty?
|
||||
remove_plugins_for(spec, @plugins_dir)
|
||||
else
|
||||
regenerate_plugins_for(spec, @plugins_dir)
|
||||
end
|
||||
end
|
||||
|
||||
def pre_install_checks
|
||||
super && validate_bundler_checksum(options[:bundler_expected_checksum])
|
||||
end
|
||||
|
|
|
@ -7,7 +7,6 @@ module Bundler
|
|||
autoload :Validator, File.expand_path("settings/validator", __dir__)
|
||||
|
||||
BOOL_KEYS = %w[
|
||||
allow_bundler_dependency_conflicts
|
||||
allow_deployment_source_credential_changes
|
||||
allow_offline_install
|
||||
auto_clean_without_path
|
||||
|
@ -20,6 +19,7 @@ module Bundler
|
|||
disable_checksum_validation
|
||||
disable_exec_load
|
||||
disable_local_branch_check
|
||||
disable_local_revision_check
|
||||
disable_multisource
|
||||
disable_shared_gems
|
||||
disable_version_check
|
||||
|
|
|
@ -187,11 +187,11 @@ module Bundler
|
|||
return @md5_available if defined?(@md5_available)
|
||||
@md5_available = begin
|
||||
require "openssl"
|
||||
OpenSSL::Digest.digest("MD5", "")
|
||||
::OpenSSL::Digest.digest("MD5", "")
|
||||
true
|
||||
rescue LoadError
|
||||
true
|
||||
rescue OpenSSL::Digest::DigestError
|
||||
rescue ::OpenSSL::Digest::DigestError
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ module Bundler
|
|||
@uri = options["uri"] || ""
|
||||
@safe_uri = URICredentialsFilter.credential_filtered_uri(@uri)
|
||||
@branch = options["branch"]
|
||||
@ref = options["ref"] || options["branch"] || options["tag"] || "master"
|
||||
@ref = options["ref"] || options["branch"] || options["tag"]
|
||||
@submodules = options["submodules"]
|
||||
@name = options["name"]
|
||||
@version = options["version"].to_s.strip.gsub("-", ".pre.")
|
||||
|
@ -60,25 +60,27 @@ module Bundler
|
|||
alias_method :==, :eql?
|
||||
|
||||
def to_s
|
||||
at = if local?
|
||||
path
|
||||
elsif user_ref = options["ref"]
|
||||
if ref =~ /\A[a-z0-9]{4,}\z/i
|
||||
shortref_for_display(user_ref)
|
||||
begin
|
||||
at = if local?
|
||||
path
|
||||
elsif user_ref = options["ref"]
|
||||
if ref =~ /\A[a-z0-9]{4,}\z/i
|
||||
shortref_for_display(user_ref)
|
||||
else
|
||||
user_ref
|
||||
end
|
||||
elsif ref
|
||||
ref
|
||||
else
|
||||
user_ref
|
||||
git_proxy.branch
|
||||
end
|
||||
else
|
||||
ref
|
||||
|
||||
rev = " (at #{at}@#{shortref_for_display(revision)})"
|
||||
rescue GitError
|
||||
""
|
||||
end
|
||||
|
||||
rev = begin
|
||||
"@#{shortref_for_display(revision)}"
|
||||
rescue GitError
|
||||
nil
|
||||
end
|
||||
|
||||
"#{@safe_uri} (at #{at}#{rev})"
|
||||
"#{@safe_uri}#{rev}"
|
||||
end
|
||||
|
||||
def name
|
||||
|
@ -146,7 +148,7 @@ module Bundler
|
|||
|
||||
changed = cached_revision && cached_revision != git_proxy.revision
|
||||
|
||||
if changed && !@unlocked && !git_proxy.contains?(cached_revision)
|
||||
if !Bundler.settings[:disable_local_revision_check] && changed && !@unlocked && !git_proxy.contains?(cached_revision)
|
||||
raise GitError, "The Gemfile lock is pointing to revision #{shortref_for_display(cached_revision)} " \
|
||||
"but the current branch in your local override for #{name} does not contain such commit. " \
|
||||
"Please make sure your branch is up to date."
|
||||
|
|
|
@ -17,7 +17,7 @@ module Bundler
|
|||
class GitNotAllowedError < GitError
|
||||
def initialize(command)
|
||||
msg = String.new
|
||||
msg << "Bundler is trying to run a `git #{command}` at runtime. You probably need to run `bundle install`. However, "
|
||||
msg << "Bundler is trying to run `#{command}` at runtime. You probably need to run `bundle install`. However, "
|
||||
msg << "this error message could probably be more useful. Please submit a ticket at https://github.com/rubygems/rubygems/issues/new?labels=Bundler&template=bundler-related-issue.md "
|
||||
msg << "with steps to reproduce as well as the following\n\nCALLER: #{caller.join("\n")}"
|
||||
super msg
|
||||
|
@ -27,11 +27,11 @@ module Bundler
|
|||
class GitCommandError < GitError
|
||||
attr_reader :command
|
||||
|
||||
def initialize(command, path, destination_path, extra_info = nil)
|
||||
def initialize(command, path, extra_info = nil)
|
||||
@command = command
|
||||
|
||||
msg = String.new
|
||||
msg << "Git error: command `git #{command}` in directory #{destination_path} has failed."
|
||||
msg << "Git error: command `#{command}` in directory #{path} has failed."
|
||||
msg << "\n#{extra_info}" if extra_info
|
||||
msg << "\nIf this error persists you could try removing the cache directory '#{path}'" if path.exist?
|
||||
super msg
|
||||
|
@ -39,9 +39,9 @@ module Bundler
|
|||
end
|
||||
|
||||
class MissingGitRevisionError < GitCommandError
|
||||
def initialize(command, path, destination_path, ref, repo)
|
||||
def initialize(command, destination_path, ref, repo)
|
||||
msg = "Revision #{ref} does not exist in the repository #{repo}. Maybe you misspelled it?"
|
||||
super command, path, destination_path, msg
|
||||
super command, destination_path, msg
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -132,7 +132,7 @@ module Bundler
|
|||
begin
|
||||
git "reset", "--hard", @revision, :dir => destination
|
||||
rescue GitCommandError => e
|
||||
raise MissingGitRevisionError.new(e.command, path, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
|
||||
raise MissingGitRevisionError.new(e.command, destination, @revision, URICredentialsFilter.credential_filtered_uri(uri))
|
||||
end
|
||||
|
||||
if submodules
|
||||
|
@ -145,32 +145,36 @@ module Bundler
|
|||
|
||||
private
|
||||
|
||||
def git_null(*command, dir: SharedHelpers.pwd)
|
||||
def git_null(*command, dir: nil)
|
||||
check_allowed(command)
|
||||
|
||||
out, status = SharedHelpers.with_clean_git_env do
|
||||
capture_and_ignore_stderr("git", "-C", dir.to_s, *command)
|
||||
capture_and_ignore_stderr(*capture3_args_for(command, dir))
|
||||
end
|
||||
|
||||
[URICredentialsFilter.credential_filtered_string(out, uri), status]
|
||||
end
|
||||
|
||||
def git_retry(*command, dir: SharedHelpers.pwd)
|
||||
Bundler::Retry.new("`git -C #{dir} #{URICredentialsFilter.credential_filtered_string(command.shelljoin, uri)}`", GitNotAllowedError).attempts do
|
||||
def git_retry(*command, dir: nil)
|
||||
command_with_no_credentials = check_allowed(command)
|
||||
|
||||
Bundler::Retry.new("`#{command_with_no_credentials}` at #{dir || SharedHelpers.pwd}").attempts do
|
||||
git(*command, :dir => dir)
|
||||
end
|
||||
end
|
||||
|
||||
def git(*command, dir: SharedHelpers.pwd)
|
||||
def git(*command, dir: nil)
|
||||
command_with_no_credentials = check_allowed(command)
|
||||
|
||||
out, status = SharedHelpers.with_clean_git_env do
|
||||
capture_and_filter_stderr("git", "-C", dir.to_s, *command)
|
||||
capture_and_filter_stderr(*capture3_args_for(command, dir))
|
||||
end
|
||||
|
||||
raise GitCommandError.new(command_with_no_credentials, path, dir) unless status.success?
|
||||
filtered_out = URICredentialsFilter.credential_filtered_string(out, uri)
|
||||
|
||||
URICredentialsFilter.credential_filtered_string(out, uri)
|
||||
raise GitCommandError.new(command_with_no_credentials, dir || SharedHelpers.pwd, filtered_out) unless status.success?
|
||||
|
||||
filtered_out
|
||||
end
|
||||
|
||||
def has_revision_cached?
|
||||
|
@ -187,10 +191,10 @@ module Bundler
|
|||
|
||||
def find_local_revision
|
||||
allowed_with_path do
|
||||
git("rev-parse", "--verify", ref, :dir => path).strip
|
||||
git("rev-parse", "--verify", ref || "HEAD", :dir => path).strip
|
||||
end
|
||||
rescue GitCommandError => e
|
||||
raise MissingGitRevisionError.new(e.command, path, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
|
||||
raise MissingGitRevisionError.new(e.command, path, ref, URICredentialsFilter.credential_filtered_uri(uri))
|
||||
end
|
||||
|
||||
# Adds credentials to the URI as Fetcher#configured_uri_for does
|
||||
|
@ -220,7 +224,7 @@ module Bundler
|
|||
end
|
||||
|
||||
def check_allowed(command)
|
||||
command_with_no_credentials = URICredentialsFilter.credential_filtered_string(command.shelljoin, uri)
|
||||
command_with_no_credentials = URICredentialsFilter.credential_filtered_string("git #{command.shelljoin}", uri)
|
||||
raise GitNotAllowedError.new(command_with_no_credentials) unless allow?
|
||||
command_with_no_credentials
|
||||
end
|
||||
|
@ -237,6 +241,20 @@ module Bundler
|
|||
return_value, _, status = Open3.capture3(*cmd)
|
||||
[return_value, status]
|
||||
end
|
||||
|
||||
def capture3_args_for(cmd, dir)
|
||||
return ["git", *cmd] unless dir
|
||||
|
||||
if Bundler.feature_flag.bundler_3_mode? || supports_minus_c?
|
||||
["git", "-C", dir.to_s, *cmd]
|
||||
else
|
||||
["git", *cmd, { :chdir => dir.to_s }]
|
||||
end
|
||||
end
|
||||
|
||||
def supports_minus_c?
|
||||
@supports_minus_c ||= Gem::Version.new(version) >= Gem::Version.new("1.8.5")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../../rubygems_gem_installer"
|
||||
|
||||
module Bundler
|
||||
class Source
|
||||
class Path
|
||||
|
|
|
@ -145,6 +145,8 @@ module Bundler
|
|||
|
||||
Bundler.mkdir_p bin_path, :no_sudo => true unless spec.executables.empty? || Bundler.rubygems.provides?(">= 2.7.5")
|
||||
|
||||
require_relative "../rubygems_gem_installer"
|
||||
|
||||
installed_spec = Bundler::RubyGemsGemInstaller.at(
|
||||
path,
|
||||
:install_dir => install_path.to_s,
|
||||
|
@ -351,7 +353,6 @@ module Bundler
|
|||
def installed_specs
|
||||
@installed_specs ||= Index.build do |idx|
|
||||
Bundler.rubygems.all_specs.reverse_each do |spec|
|
||||
next if spec.name == "bundler"
|
||||
spec.source = self
|
||||
if Bundler.rubygems.spec_missing_extensions?(spec, false)
|
||||
Bundler.ui.debug "Source #{self} is ignoring #{spec} because it is missing extensions"
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "set"
|
||||
|
||||
module Bundler
|
||||
class SourceList
|
||||
attr_reader :path_sources,
|
||||
:git_sources,
|
||||
:plugin_sources,
|
||||
:global_rubygems_source,
|
||||
:global_path_source,
|
||||
:metadata_source
|
||||
|
||||
def global_rubygems_source
|
||||
@global_rubygems_source ||= rubygems_aggregate_class.new
|
||||
end
|
||||
|
||||
def initialize
|
||||
@path_sources = []
|
||||
@git_sources = []
|
||||
@plugin_sources = []
|
||||
@global_rubygems_source = nil
|
||||
@rubygems_aggregate = rubygems_aggregate_class.new
|
||||
@global_path_source = nil
|
||||
@rubygems_sources = []
|
||||
@metadata_source = Source::Metadata.new
|
||||
end
|
||||
|
@ -24,7 +26,9 @@ module Bundler
|
|||
if options["gemspec"]
|
||||
add_source_to_list Source::Gemspec.new(options), path_sources
|
||||
else
|
||||
add_source_to_list Source::Path.new(options), path_sources
|
||||
path_source = add_source_to_list Source::Path.new(options), path_sources
|
||||
@global_path_source ||= path_source if options["global"]
|
||||
path_source
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -43,24 +47,20 @@ module Bundler
|
|||
end
|
||||
|
||||
def global_rubygems_source=(uri)
|
||||
if Bundler.feature_flag.disable_multisource?
|
||||
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
|
||||
end
|
||||
add_rubygems_remote(uri)
|
||||
@global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri)
|
||||
end
|
||||
|
||||
def add_rubygems_remote(uri)
|
||||
return if Bundler.feature_flag.disable_multisource?
|
||||
@rubygems_aggregate.add_remote(uri)
|
||||
@rubygems_aggregate
|
||||
global_rubygems_source.add_remote(uri)
|
||||
global_rubygems_source
|
||||
end
|
||||
|
||||
def default_source
|
||||
global_rubygems_source || @rubygems_aggregate
|
||||
global_path_source || global_rubygems_source
|
||||
end
|
||||
|
||||
def rubygems_sources
|
||||
@rubygems_sources + [default_source]
|
||||
@rubygems_sources + [global_rubygems_source]
|
||||
end
|
||||
|
||||
def rubygems_remotes
|
||||
|
@ -96,10 +96,9 @@ module Bundler
|
|||
|
||||
replacement_rubygems = !Bundler.feature_flag.disable_multisource? &&
|
||||
replacement_sources.detect {|s| s.is_a?(Source::Rubygems) }
|
||||
@rubygems_aggregate = replacement_rubygems if replacement_rubygems
|
||||
@global_rubygems_source = replacement_rubygems if replacement_rubygems
|
||||
|
||||
return true if !equal_sources?(lock_sources, replacement_sources) && !equivalent_sources?(lock_sources, replacement_sources)
|
||||
return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set
|
||||
|
||||
false
|
||||
end
|
||||
|
@ -112,10 +111,6 @@ module Bundler
|
|||
all_sources.each(&:remote!)
|
||||
end
|
||||
|
||||
def rubygems_primary_remotes
|
||||
@rubygems_aggregate.remotes
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rubygems_aggregate_class
|
||||
|
@ -153,7 +148,7 @@ module Bundler
|
|||
end
|
||||
|
||||
def equal_sources?(lock_sources, replacement_sources)
|
||||
lock_sources.to_set == replacement_sources.to_set
|
||||
lock_sources.sort_by(&:to_s) == replacement_sources.sort_by(&:to_s)
|
||||
end
|
||||
|
||||
def equal_source?(source, other_source)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "tsort"
|
||||
require "set"
|
||||
|
||||
module Bundler
|
||||
class SpecSet
|
||||
|
@ -13,14 +12,16 @@ module Bundler
|
|||
end
|
||||
|
||||
def for(dependencies, skip = [], check = false, match_current_platform = false, raise_on_missing = true)
|
||||
handled = Set.new
|
||||
handled = []
|
||||
deps = dependencies.dup
|
||||
specs = []
|
||||
skip += ["bundler"]
|
||||
|
||||
loop do
|
||||
break unless dep = deps.shift
|
||||
next if !handled.add?(dep) || skip.include?(dep.name)
|
||||
next if handled.include?(dep) || skip.include?(dep.name)
|
||||
|
||||
handled << dep
|
||||
|
||||
specs_for_dep = spec_for_dependency(dep, match_current_platform)
|
||||
if specs_for_dep.any?
|
||||
|
@ -28,7 +29,7 @@ module Bundler
|
|||
|
||||
specs_for_dep.first.dependencies.each do |d|
|
||||
next if d.type == :development
|
||||
d = DepProxy.new(d, dep.__platform) unless match_current_platform
|
||||
d = DepProxy.get_proxy(d, dep.__platform) unless match_current_platform
|
||||
deps << d
|
||||
end
|
||||
elsif check
|
||||
|
|
|
@ -26,11 +26,19 @@ module Bundler
|
|||
|
||||
# @!group Stub Delegates
|
||||
|
||||
def manually_installed?
|
||||
# This is for manually installed gems which are gems that were fixed in place after a
|
||||
# failed installation. Once the issue was resolved, the user then manually created
|
||||
# the gem specification using the instructions provided by `gem help install`
|
||||
installed_by_version == Gem::Version.new(0)
|
||||
end
|
||||
|
||||
# This is defined directly to avoid having to loading the full spec
|
||||
def missing_extensions?
|
||||
return false if default_gem?
|
||||
return false if extensions.empty?
|
||||
return false if File.exist? gem_build_complete_path
|
||||
return false if manually_installed?
|
||||
|
||||
true
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
## [Unreleased]
|
||||
|
||||
## [0.1.0] - <%= Time.now.strftime('%F') %>
|
||||
|
||||
- Initial release
|
|
@ -16,5 +16,5 @@ gem "<%= config[:test] %>", "~> <%= config[:test_framework_version] %>"
|
|||
<%- end -%>
|
||||
<%- if config[:rubocop] -%>
|
||||
|
||||
gem "rubocop", "~> 0.80"
|
||||
gem "rubocop", "~> <%= config[:rubocop_version] %>"
|
||||
<%- end -%>
|
||||
|
|
|
@ -29,19 +29,21 @@ TODO: Write usage instructions here
|
|||
After checking out the repo, run `bin/setup` to install dependencies.<% if config[:test] %> Then, run `rake <%= config[:test].sub('mini', '').sub('rspec', 'spec') %>` to run the tests.<% end %> You can also run `bin/console` for an interactive prompt that will allow you to experiment.<% if config[:bin] %> Run `bundle exec <%= config[:name] %>` to use the gem in this directory, ignoring other installed copies of this gem.<% end %>
|
||||
|
||||
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
||||
<% if config[:git] -%>
|
||||
|
||||
## 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/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).<% end %>
|
||||
<% end -%>
|
||||
<% if config[:mit] -%>
|
||||
|
||||
## License
|
||||
|
||||
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
||||
<% end -%>
|
||||
<% if config[:coc] -%>
|
||||
<% if config[:git] && config[:coc] -%>
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/master/CODE_OF_CONDUCT.md).
|
||||
Everyone interacting in the <%= config[:constant_name] %> project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/<%= config[:github_username] %>/<%= config[:name] %>/blob/<%= config[:git_default_branch] %>/CODE_OF_CONDUCT.md).
|
||||
<% end -%>
|
||||
|
|
|
@ -14,7 +14,7 @@ Gem::Specification.new do |spec|
|
|||
<%- if config[:mit] -%>
|
||||
spec.license = "MIT"
|
||||
<%- end -%>
|
||||
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
||||
spec.required_ruby_version = Gem::Requirement.new(">= <%= config[:required_ruby_version] %>")
|
||||
|
||||
spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
AllCops:
|
||||
TargetRubyVersion: <%= ::Gem::Version.new(config[:required_ruby_version]).segments[0..1].join(".") %>
|
||||
|
||||
Style/StringLiterals:
|
||||
Enabled: true
|
||||
EnforcedStyle: double_quotes
|
||||
|
|
|
@ -26,6 +26,13 @@ module Bundler::Molinillo
|
|||
end
|
||||
end
|
||||
|
||||
# (see Bundler::Molinillo::SpecificationProvider#dependencies_equal?)
|
||||
def dependencies_equal?(dependencies, other_dependencies)
|
||||
with_no_such_dependency_error_handling do
|
||||
specification_provider.dependencies_equal?(dependencies, other_dependencies)
|
||||
end
|
||||
end
|
||||
|
||||
# (see Bundler::Molinillo::SpecificationProvider#name_for)
|
||||
def name_for(dependency)
|
||||
with_no_such_dependency_error_handling do
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'set'
|
||||
require 'tsort'
|
||||
|
||||
require_relative 'dependency_graph/log'
|
||||
|
|
|
@ -59,7 +59,7 @@ module Bundler::Molinillo
|
|||
# @param [Set<Vertex>] vertices the set to add the predecessors to
|
||||
# @return [Set<Vertex>] the vertices of {#graph} where `self` is a
|
||||
# {#descendent?}
|
||||
def _recursive_predecessors(vertices = Set.new)
|
||||
def _recursive_predecessors(vertices = new_vertex_set)
|
||||
incoming_edges.each do |edge|
|
||||
vertex = edge.origin
|
||||
next unless vertices.add?(vertex)
|
||||
|
@ -85,7 +85,7 @@ module Bundler::Molinillo
|
|||
# @param [Set<Vertex>] vertices the set to add the successors to
|
||||
# @return [Set<Vertex>] the vertices of {#graph} where `self` is an
|
||||
# {#ancestor?}
|
||||
def _recursive_successors(vertices = Set.new)
|
||||
def _recursive_successors(vertices = new_vertex_set)
|
||||
outgoing_edges.each do |edge|
|
||||
vertex = edge.destination
|
||||
next unless vertices.add?(vertex)
|
||||
|
@ -128,7 +128,7 @@ module Bundler::Molinillo
|
|||
|
||||
# Is there a path from `self` to `other` following edges in the
|
||||
# dependency graph?
|
||||
# @return true iff there is a path following edges within this {#graph}
|
||||
# @return whether there is a path following edges within this {#graph}
|
||||
def path_to?(other)
|
||||
_path_to?(other)
|
||||
end
|
||||
|
@ -138,7 +138,7 @@ module Bundler::Molinillo
|
|||
# @param [Vertex] other the vertex to check if there's a path to
|
||||
# @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
|
||||
# @return [Boolean] whether there is a path to `other` from `self`
|
||||
def _path_to?(other, visited = Set.new)
|
||||
def _path_to?(other, visited = new_vertex_set)
|
||||
return false unless visited.add?(self)
|
||||
return true if equal?(other)
|
||||
successors.any? { |v| v._path_to?(other, visited) }
|
||||
|
@ -147,12 +147,18 @@ module Bundler::Molinillo
|
|||
|
||||
# Is there a path from `other` to `self` following edges in the
|
||||
# dependency graph?
|
||||
# @return true iff there is a path following edges within this {#graph}
|
||||
# @return whether there is a path following edges within this {#graph}
|
||||
def ancestor?(other)
|
||||
other.path_to?(self)
|
||||
end
|
||||
|
||||
alias is_reachable_from? ancestor?
|
||||
|
||||
def new_vertex_set
|
||||
require 'set'
|
||||
Set.new
|
||||
end
|
||||
private :new_vertex_set
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ module Bundler::Molinillo
|
|||
|
||||
# An error caused by attempting to fulfil a dependency that was circular
|
||||
#
|
||||
# @note This exception will be thrown iff a {Vertex} is added to a
|
||||
# @note This exception will be thrown if and only if a {Vertex} is added to a
|
||||
# {DependencyGraph} that has a {DependencyGraph::Vertex#path_to?} an
|
||||
# existing {DependencyGraph::Vertex}
|
||||
class CircularDependencyError < ResolverError
|
||||
|
@ -121,7 +121,7 @@ module Bundler::Molinillo
|
|||
t = ''.dup
|
||||
depth = 2
|
||||
tree.each do |req|
|
||||
t << ' ' * depth << req.to_s
|
||||
t << ' ' * depth << printable_requirement.call(req)
|
||||
unless tree.last == req
|
||||
if spec = conflict.activated_by_name[name_for(req)]
|
||||
t << %( was resolved to #{version_for_spec.call(spec)}, which)
|
||||
|
|
|
@ -45,6 +45,17 @@ module Bundler::Molinillo
|
|||
true
|
||||
end
|
||||
|
||||
# Determines whether two arrays of dependencies are equal, and thus can be
|
||||
# grouped.
|
||||
#
|
||||
# @param [Array<Object>] dependencies
|
||||
# @param [Array<Object>] other_dependencies
|
||||
# @return [Boolean] whether `dependencies` and `other_dependencies` should
|
||||
# be considered equal.
|
||||
def dependencies_equal?(dependencies, other_dependencies)
|
||||
dependencies == other_dependencies
|
||||
end
|
||||
|
||||
# Returns the name for the given `dependency`.
|
||||
# @note This method should be 'pure', i.e. the return value should depend
|
||||
# only on the `dependency` parameter.
|
||||
|
|
|
@ -329,11 +329,11 @@ module Bundler::Molinillo
|
|||
|
||||
# Look for past conflicts that could be unwound to affect the
|
||||
# requirement tree for the current conflict
|
||||
all_reqs = last_detail_for_current_unwind.all_requirements
|
||||
all_reqs_size = all_reqs.size
|
||||
relevant_unused_unwinds = unused_unwind_options.select do |alternative|
|
||||
intersecting_requirements =
|
||||
last_detail_for_current_unwind.all_requirements &
|
||||
alternative.requirements_unwound_to_instead
|
||||
next if intersecting_requirements.empty?
|
||||
diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
|
||||
next if diff_reqs.size == all_reqs_size
|
||||
# Find the highest index unwind whilst looping through
|
||||
current_detail = alternative if alternative > current_detail
|
||||
alternative
|
||||
|
@ -344,8 +344,12 @@ module Bundler::Molinillo
|
|||
state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
|
||||
|
||||
# Update the requirements_unwound_to_instead on any relevant unused unwinds
|
||||
relevant_unused_unwinds.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
|
||||
unwind_details.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
|
||||
relevant_unused_unwinds.each do |d|
|
||||
(d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
|
||||
end
|
||||
unwind_details.each do |d|
|
||||
(d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
|
||||
end
|
||||
|
||||
current_detail
|
||||
end
|
||||
|
@ -803,7 +807,7 @@ module Bundler::Molinillo
|
|||
|
||||
possibilities.reverse_each do |possibility|
|
||||
dependencies = dependencies_for(possibility)
|
||||
if current_possibility_set && current_possibility_set.dependencies == dependencies
|
||||
if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
|
||||
current_possibility_set.possibilities.unshift(possibility)
|
||||
else
|
||||
possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require "set"
|
||||
require_relative "thor/base"
|
||||
|
||||
class Bundler::Thor
|
||||
$thor_runner ||= false
|
||||
class << self
|
||||
# Allows for custom "Command" package naming.
|
||||
#
|
||||
|
@ -323,7 +323,7 @@ class Bundler::Thor
|
|||
# ==== Parameters
|
||||
# Symbol ...:: A list of commands that should be affected.
|
||||
def stop_on_unknown_option!(*command_names)
|
||||
stop_on_unknown_option.merge(command_names)
|
||||
@stop_on_unknown_option = stop_on_unknown_option | command_names
|
||||
end
|
||||
|
||||
def stop_on_unknown_option?(command) #:nodoc:
|
||||
|
@ -337,7 +337,7 @@ class Bundler::Thor
|
|||
# ==== Parameters
|
||||
# Symbol ...:: A list of commands that should be affected.
|
||||
def disable_required_check!(*command_names)
|
||||
disable_required_check.merge(command_names)
|
||||
@disable_required_check = disable_required_check | command_names
|
||||
end
|
||||
|
||||
def disable_required_check?(command) #:nodoc:
|
||||
|
@ -347,12 +347,12 @@ class Bundler::Thor
|
|||
protected
|
||||
|
||||
def stop_on_unknown_option #:nodoc:
|
||||
@stop_on_unknown_option ||= Set.new
|
||||
@stop_on_unknown_option ||= []
|
||||
end
|
||||
|
||||
# help command has the required check disabled by default.
|
||||
def disable_required_check #:nodoc:
|
||||
@disable_required_check ||= Set.new([:help])
|
||||
@disable_required_check ||= [:help]
|
||||
end
|
||||
|
||||
# The method responsible for dispatching given the args.
|
||||
|
@ -398,7 +398,6 @@ class Bundler::Thor
|
|||
# the namespace should be displayed as arguments.
|
||||
#
|
||||
def banner(command, namespace = nil, subcommand = false)
|
||||
$thor_runner ||= false
|
||||
command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage|
|
||||
"#{basename} #{formatted_usage}"
|
||||
end.join("\n")
|
||||
|
|
|
@ -219,7 +219,7 @@ class Bundler::Thor
|
|||
|
||||
contents = if is_uri
|
||||
require "open-uri"
|
||||
open(path, "Accept" => "application/x-thor-template", &:read)
|
||||
URI.open(path, "Accept" => "application/x-thor-template", &:read)
|
||||
else
|
||||
open(path, &:read)
|
||||
end
|
||||
|
|
|
@ -251,7 +251,8 @@ class Bundler::Thor
|
|||
# path<String>:: path of the file to be changed
|
||||
# flag<Regexp|String>:: the regexp or string to be replaced
|
||||
# replacement<String>:: the replacement, can be also given as a block
|
||||
# config<Hash>:: give :verbose => false to not log the status.
|
||||
# config<Hash>:: give :verbose => false to not log the status, and
|
||||
# :force => true, to force the replacement regardles of runner behavior.
|
||||
#
|
||||
# ==== Example
|
||||
#
|
||||
|
@ -262,9 +263,10 @@ class Bundler::Thor
|
|||
# end
|
||||
#
|
||||
def gsub_file(path, flag, *args, &block)
|
||||
return unless behavior == :invoke
|
||||
config = args.last.is_a?(Hash) ? args.pop : {}
|
||||
|
||||
return unless behavior == :invoke || config.fetch(:force, false)
|
||||
|
||||
path = File.expand_path(path, destination_root)
|
||||
say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class Bundler::Thor
|
||||
Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable)
|
||||
Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
|
||||
# In order to support versions of Ruby that don't have keyword
|
||||
# arguments, we need our own spell checker class that doesn't take key
|
||||
# words. Even though this code wouldn't be hit because of the check
|
||||
|
|
|
@ -30,7 +30,11 @@ class Bundler::Thor
|
|||
|
||||
arguments.each do |argument|
|
||||
if !argument.default.nil?
|
||||
@assigns[argument.human_name] = argument.default
|
||||
begin
|
||||
@assigns[argument.human_name] = argument.default.dup
|
||||
rescue TypeError # Compatibility shim for un-dup-able Fixnum in Ruby < 2.4
|
||||
@assigns[argument.human_name] = argument.default
|
||||
end
|
||||
elsif argument.required?
|
||||
@non_assigned_required << argument
|
||||
end
|
||||
|
|
|
@ -133,15 +133,16 @@ class Bundler::Thor
|
|||
|
||||
protected
|
||||
|
||||
def assign_result!(option, result)
|
||||
if option.repeatable && option.type == :hash
|
||||
(@assigns[option.human_name] ||= {}).merge!(result)
|
||||
elsif option.repeatable
|
||||
(@assigns[option.human_name] ||= []) << result
|
||||
else
|
||||
@assigns[option.human_name] = result
|
||||
def assign_result!(option, result)
|
||||
if option.repeatable && option.type == :hash
|
||||
(@assigns[option.human_name] ||= {}).merge!(result)
|
||||
elsif option.repeatable
|
||||
(@assigns[option.human_name] ||= []) << result
|
||||
else
|
||||
@assigns[option.human_name] = result
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Check if the current value in peek is a registered switch.
|
||||
#
|
||||
# Two booleans are returned. The first is true if the current value
|
||||
|
|
|
@ -94,6 +94,8 @@ class Bundler::Thor
|
|||
# say("I know you knew that.")
|
||||
#
|
||||
def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
|
||||
return if quiet?
|
||||
|
||||
buffer = prepare_message(message, *color)
|
||||
buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")
|
||||
|
||||
|
@ -230,8 +232,9 @@ class Bundler::Thor
|
|||
paras = message.split("\n\n")
|
||||
|
||||
paras.map! do |unwrapped|
|
||||
counter = 0
|
||||
unwrapped.split(" ").inject do |memo, word|
|
||||
words = unwrapped.split(" ")
|
||||
counter = words.first.length
|
||||
words.inject do |memo, word|
|
||||
word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
|
||||
counter = 0 if word.include? "\n"
|
||||
if (counter + word.length + 1) < width
|
||||
|
|
|
@ -97,7 +97,11 @@ class Bundler::Thor
|
|||
protected
|
||||
|
||||
def can_display_colors?
|
||||
stdout.tty? && !are_colors_disabled?
|
||||
are_colors_supported? && !are_colors_disabled?
|
||||
end
|
||||
|
||||
def are_colors_supported?
|
||||
stdout.tty? && ENV["TERM"] != "dumb"
|
||||
end
|
||||
|
||||
def are_colors_disabled?
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
class Bundler::Thor
|
||||
VERSION = "1.0.1"
|
||||
VERSION = "1.1.0"
|
||||
end
|
||||
|
|
|
@ -275,7 +275,7 @@ module Gem
|
|||
|
||||
unless spec = specs.first
|
||||
msg = "can't find gem #{dep} with executable #{exec_name}"
|
||||
if name == "bundler" && bundler_message = Gem::BundlerVersionFinder.missing_version_message
|
||||
if dep.filters_bundler? && bundler_message = Gem::BundlerVersionFinder.missing_version_message
|
||||
msg = bundler_message
|
||||
end
|
||||
raise Gem::GemNotFoundException, msg
|
||||
|
@ -469,7 +469,7 @@ An Array (#{env.inspect}) was passed in from #{caller[3]}
|
|||
next if File.exist? subdir
|
||||
begin
|
||||
FileUtils.mkdir_p subdir, **options
|
||||
rescue Errno::EACCES
|
||||
rescue SystemCallError
|
||||
end
|
||||
end
|
||||
ensure
|
||||
|
|
|
@ -634,6 +634,7 @@ RubyGems is a package manager for Ruby.
|
|||
gem install rake
|
||||
gem list --local
|
||||
gem build package.gemspec
|
||||
gem push package-0.0.1.gem
|
||||
gem help install
|
||||
|
||||
Further help:
|
||||
|
|
|
@ -45,6 +45,7 @@ class Gem::ConfigFile
|
|||
DEFAULT_UPDATE_SOURCES = true
|
||||
DEFAULT_CONCURRENT_DOWNLOADS = 8
|
||||
DEFAULT_CERT_EXPIRATION_LENGTH_DAYS = 365
|
||||
DEFAULT_IPV4_FALLBACK_ENABLED = false
|
||||
|
||||
##
|
||||
# For Ruby packagers to set configuration defaults. Set in
|
||||
|
@ -140,6 +141,12 @@ class Gem::ConfigFile
|
|||
|
||||
attr_accessor :cert_expiration_length_days
|
||||
|
||||
##
|
||||
# == Experimental ==
|
||||
# Fallback to IPv4 when IPv6 is not reachable or slow (default: false)
|
||||
|
||||
attr_accessor :ipv4_fallback_enabled
|
||||
|
||||
##
|
||||
# Path name of directory or file of openssl client certificate, used for remote https connection with client authentication
|
||||
|
||||
|
@ -175,6 +182,7 @@ class Gem::ConfigFile
|
|||
@update_sources = DEFAULT_UPDATE_SOURCES
|
||||
@concurrent_downloads = DEFAULT_CONCURRENT_DOWNLOADS
|
||||
@cert_expiration_length_days = DEFAULT_CERT_EXPIRATION_LENGTH_DAYS
|
||||
@ipv4_fallback_enabled = ENV['IPV4_FALLBACK_ENABLED'] == 'true' || DEFAULT_IPV4_FALLBACK_ENABLED
|
||||
|
||||
operating_system_config = Marshal.load Marshal.dump(OPERATING_SYSTEM_DEFAULTS)
|
||||
platform_config = Marshal.load Marshal.dump(PLATFORM_DEFAULTS)
|
||||
|
@ -203,6 +211,7 @@ class Gem::ConfigFile
|
|||
@disable_default_gem_server = @hash[:disable_default_gem_server] if @hash.key? :disable_default_gem_server
|
||||
@sources = @hash[:sources] if @hash.key? :sources
|
||||
@cert_expiration_length_days = @hash[:cert_expiration_length_days] if @hash.key? :cert_expiration_length_days
|
||||
@ipv4_fallback_enabled = @hash[:ipv4_fallback_enabled] if @hash.key? :ipv4_fallback_enabled
|
||||
|
||||
@ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
|
||||
@ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
require 'socket'
|
||||
|
||||
module CoreExtensions
|
||||
module TCPSocketExt
|
||||
def self.prepended(base)
|
||||
base.prepend Initializer
|
||||
end
|
||||
|
||||
module Initializer
|
||||
CONNECTION_TIMEOUT = 5
|
||||
IPV4_DELAY_SECONDS = 0.1
|
||||
|
||||
def initialize(host, serv, *rest)
|
||||
mutex = Mutex.new
|
||||
addrs = []
|
||||
threads = []
|
||||
cond_var = ConditionVariable.new
|
||||
|
||||
Addrinfo.foreach(host, serv, nil, :STREAM) do |addr|
|
||||
Thread.report_on_exception = false if defined? Thread.report_on_exception = ()
|
||||
|
||||
threads << Thread.new(addr) do
|
||||
# give head start to ipv6 addresses
|
||||
sleep IPV4_DELAY_SECONDS if addr.ipv4?
|
||||
|
||||
# raises Errno::ECONNREFUSED when ip:port is unreachable
|
||||
Socket.tcp(addr.ip_address, serv, connect_timeout: CONNECTION_TIMEOUT).close
|
||||
mutex.synchronize do
|
||||
addrs << addr.ip_address
|
||||
cond_var.signal
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mutex.synchronize do
|
||||
timeout_time = CONNECTION_TIMEOUT + Time.now.to_f
|
||||
while addrs.empty? && (remaining_time = timeout_time - Time.now.to_f) > 0
|
||||
cond_var.wait(mutex, remaining_time)
|
||||
end
|
||||
|
||||
host = addrs.shift unless addrs.empty?
|
||||
end
|
||||
|
||||
threads.each {|t| t.kill.join if t.alive? }
|
||||
|
||||
super(host, serv, *rest)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
TCPSocket.prepend CoreExtensions::TCPSocketExt
|
|
@ -277,7 +277,7 @@ class Gem::Dependency
|
|||
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
|
||||
end.map(&:to_spec)
|
||||
|
||||
Gem::BundlerVersionFinder.filter!(matches) if name == "bundler".freeze && !requirement.specific?
|
||||
Gem::BundlerVersionFinder.filter!(matches) if filters_bundler?
|
||||
|
||||
if platform_only
|
||||
matches.reject! do |spec|
|
||||
|
@ -295,6 +295,10 @@ class Gem::Dependency
|
|||
@requirement.specific?
|
||||
end
|
||||
|
||||
def filters_bundler?
|
||||
name == "bundler".freeze && !specific?
|
||||
end
|
||||
|
||||
def to_specs
|
||||
matches = matching_specs true
|
||||
|
||||
|
|
|
@ -28,13 +28,14 @@ class Gem::Ext::Builder
|
|||
unless make_program
|
||||
make_program = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
|
||||
end
|
||||
make_program = Shellwords.split(make_program)
|
||||
|
||||
destdir = 'DESTDIR=%s' % ENV['DESTDIR']
|
||||
|
||||
['clean', '', 'install'].each do |target|
|
||||
# Pass DESTDIR via command line to override what's in MAKEFLAGS
|
||||
cmd = [
|
||||
make_program,
|
||||
*make_program,
|
||||
destdir,
|
||||
target,
|
||||
].reject(&:empty?)
|
||||
|
|
|
@ -6,11 +6,16 @@
|
|||
module Gem::InstallerUninstallerUtils
|
||||
|
||||
def regenerate_plugins_for(spec, plugins_dir)
|
||||
plugins = spec.plugins
|
||||
return if plugins.empty?
|
||||
|
||||
require 'pathname'
|
||||
|
||||
spec.plugins.each do |plugin|
|
||||
plugin_script_path = File.join plugins_dir, "#{spec.name}_plugin#{File.extname(plugin)}"
|
||||
|
||||
File.open plugin_script_path, 'wb' do |file|
|
||||
file.puts "require '#{plugin}'"
|
||||
file.puts "require_relative '#{Pathname.new(plugin).relative_path_from(Pathname.new(plugins_dir))}'"
|
||||
end
|
||||
|
||||
verbose plugin_script_path
|
||||
|
|
|
@ -66,7 +66,7 @@ class Gem::Platform
|
|||
when String then
|
||||
arch = arch.split '-'
|
||||
|
||||
if arch.length > 2 and arch.last !~ /\d/ # reassemble x86-linux-gnu
|
||||
if arch.length > 2 and arch.last !~ /\d+(\.\d+)?$/ # reassemble x86-linux-{libc}
|
||||
extra = arch.pop
|
||||
arch.last << "-#{extra}"
|
||||
end
|
||||
|
@ -121,10 +121,6 @@ class Gem::Platform
|
|||
end
|
||||
end
|
||||
|
||||
def inspect
|
||||
"%s @cpu=%p, @os=%p, @version=%p>" % [super[0..-2], *to_a]
|
||||
end
|
||||
|
||||
def to_a
|
||||
[@cpu, @os, @version]
|
||||
end
|
||||
|
@ -150,7 +146,8 @@ class Gem::Platform
|
|||
##
|
||||
# Does +other+ match this platform? Two platforms match if they have the
|
||||
# same CPU, or either has a CPU of 'universal', they have the same OS, and
|
||||
# they have the same version, or either has no version.
|
||||
# they have the same version, or either has no version (except for 'linux'
|
||||
# where the version is the libc name, with no version standing for 'gnu')
|
||||
#
|
||||
# Additionally, the platform will match if the local CPU is 'arm' and the
|
||||
# other CPU starts with "arm" (for generic ARM family support).
|
||||
|
@ -166,7 +163,10 @@ class Gem::Platform
|
|||
@os == other.os and
|
||||
|
||||
# version
|
||||
(@version.nil? or other.version.nil? or @version == other.version)
|
||||
(
|
||||
(@os != 'linux' and (@version.nil? or other.version.nil?)) or
|
||||
@version == other.version
|
||||
)
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -78,6 +78,7 @@ class Gem::RemoteFetcher
|
|||
# fetching the gem.
|
||||
|
||||
def initialize(proxy=nil, dns=nil, headers={})
|
||||
require 'rubygems/core_ext/tcpsocket_init' if Gem.configuration.ipv4_fallback_enabled
|
||||
require 'net/http'
|
||||
require 'stringio'
|
||||
require 'uri'
|
||||
|
@ -295,7 +296,7 @@ class Gem::RemoteFetcher
|
|||
|
||||
data = fetch_path(uri, mtime)
|
||||
|
||||
if data == nil # indicates the server returned 304 Not Modified
|
||||
if data.nil? # indicates the server returned 304 Not Modified
|
||||
return Gem.read_binary(path)
|
||||
end
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ class Gem::Requirement
|
|||
end
|
||||
|
||||
def hash # :nodoc:
|
||||
requirements.sort.hash
|
||||
requirements.map {|r| r.first == "~>" ? [r[0], r[1].to_s] : r }.sort.hash
|
||||
end
|
||||
|
||||
def marshal_dump # :nodoc:
|
||||
|
|
|
@ -35,9 +35,12 @@ class Gem::Resolver::IndexSpecification < Gem::Resolver::Specification
|
|||
|
||||
##
|
||||
# The required_ruby_version constraint for this specification
|
||||
#
|
||||
# A fallback is included because when generated, some marshalled specs have it
|
||||
# set to +nil+.
|
||||
|
||||
def required_ruby_version
|
||||
spec.required_ruby_version
|
||||
spec.required_ruby_version || Gem::Requirement.default
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
@ -26,6 +26,13 @@ module Gem::Resolver::Molinillo
|
|||
end
|
||||
end
|
||||
|
||||
# (see Gem::Resolver::Molinillo::SpecificationProvider#dependencies_equal?)
|
||||
def dependencies_equal?(dependencies, other_dependencies)
|
||||
with_no_such_dependency_error_handling do
|
||||
specification_provider.dependencies_equal?(dependencies, other_dependencies)
|
||||
end
|
||||
end
|
||||
|
||||
# (see Gem::Resolver::Molinillo::SpecificationProvider#name_for)
|
||||
def name_for(dependency)
|
||||
with_no_such_dependency_error_handling do
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'set'
|
||||
require 'tsort'
|
||||
|
||||
require_relative 'dependency_graph/log'
|
||||
|
|
|
@ -59,7 +59,7 @@ module Gem::Resolver::Molinillo
|
|||
# @param [Set<Vertex>] vertices the set to add the predecessors to
|
||||
# @return [Set<Vertex>] the vertices of {#graph} where `self` is a
|
||||
# {#descendent?}
|
||||
def _recursive_predecessors(vertices = Set.new)
|
||||
def _recursive_predecessors(vertices = new_vertex_set)
|
||||
incoming_edges.each do |edge|
|
||||
vertex = edge.origin
|
||||
next unless vertices.add?(vertex)
|
||||
|
@ -85,7 +85,7 @@ module Gem::Resolver::Molinillo
|
|||
# @param [Set<Vertex>] vertices the set to add the successors to
|
||||
# @return [Set<Vertex>] the vertices of {#graph} where `self` is an
|
||||
# {#ancestor?}
|
||||
def _recursive_successors(vertices = Set.new)
|
||||
def _recursive_successors(vertices = new_vertex_set)
|
||||
outgoing_edges.each do |edge|
|
||||
vertex = edge.destination
|
||||
next unless vertices.add?(vertex)
|
||||
|
@ -138,7 +138,7 @@ module Gem::Resolver::Molinillo
|
|||
# @param [Vertex] other the vertex to check if there's a path to
|
||||
# @param [Set<Vertex>] visited the vertices of {#graph} that have been visited
|
||||
# @return [Boolean] whether there is a path to `other` from `self`
|
||||
def _path_to?(other, visited = Set.new)
|
||||
def _path_to?(other, visited = new_vertex_set)
|
||||
return false unless visited.add?(self)
|
||||
return true if equal?(other)
|
||||
successors.any? { |v| v._path_to?(other, visited) }
|
||||
|
@ -147,12 +147,18 @@ module Gem::Resolver::Molinillo
|
|||
|
||||
# Is there a path from `other` to `self` following edges in the
|
||||
# dependency graph?
|
||||
# @return true iff there is a path following edges within this {#graph}
|
||||
# @return whether there is a path following edges within this {#graph}
|
||||
def ancestor?(other)
|
||||
other.path_to?(self)
|
||||
end
|
||||
|
||||
alias is_reachable_from? ancestor?
|
||||
|
||||
def new_vertex_set
|
||||
require 'set'
|
||||
Set.new
|
||||
end
|
||||
private :new_vertex_set
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -121,7 +121,7 @@ module Gem::Resolver::Molinillo
|
|||
t = ''.dup
|
||||
depth = 2
|
||||
tree.each do |req|
|
||||
t << ' ' * depth << req.to_s
|
||||
t << ' ' * depth << printable_requirement.call(req)
|
||||
unless tree.last == req
|
||||
if spec = conflict.activated_by_name[name_for(req)]
|
||||
t << %( was resolved to #{version_for_spec.call(spec)}, which)
|
||||
|
|
|
@ -45,6 +45,17 @@ module Gem::Resolver::Molinillo
|
|||
true
|
||||
end
|
||||
|
||||
# Determines whether two arrays of dependencies are equal, and thus can be
|
||||
# grouped.
|
||||
#
|
||||
# @param [Array<Object>] dependencies
|
||||
# @param [Array<Object>] other_dependencies
|
||||
# @return [Boolean] whether `dependencies` and `other_dependencies` should
|
||||
# be considered equal.
|
||||
def dependencies_equal?(dependencies, other_dependencies)
|
||||
dependencies == other_dependencies
|
||||
end
|
||||
|
||||
# Returns the name for the given `dependency`.
|
||||
# @note This method should be 'pure', i.e. the return value should depend
|
||||
# only on the `dependency` parameter.
|
||||
|
|
|
@ -329,11 +329,11 @@ module Gem::Resolver::Molinillo
|
|||
|
||||
# Look for past conflicts that could be unwound to affect the
|
||||
# requirement tree for the current conflict
|
||||
all_reqs = last_detail_for_current_unwind.all_requirements
|
||||
all_reqs_size = all_reqs.size
|
||||
relevant_unused_unwinds = unused_unwind_options.select do |alternative|
|
||||
intersecting_requirements =
|
||||
last_detail_for_current_unwind.all_requirements &
|
||||
alternative.requirements_unwound_to_instead
|
||||
next if intersecting_requirements.empty?
|
||||
diff_reqs = all_reqs - alternative.requirements_unwound_to_instead
|
||||
next if diff_reqs.size == all_reqs_size
|
||||
# Find the highest index unwind whilst looping through
|
||||
current_detail = alternative if alternative > current_detail
|
||||
alternative
|
||||
|
@ -344,8 +344,12 @@ module Gem::Resolver::Molinillo
|
|||
state.unused_unwind_options += unwind_details.reject { |detail| detail.state_index == -1 }
|
||||
|
||||
# Update the requirements_unwound_to_instead on any relevant unused unwinds
|
||||
relevant_unused_unwinds.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
|
||||
unwind_details.each { |d| d.requirements_unwound_to_instead << current_detail.state_requirement }
|
||||
relevant_unused_unwinds.each do |d|
|
||||
(d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
|
||||
end
|
||||
unwind_details.each do |d|
|
||||
(d.requirements_unwound_to_instead << current_detail.state_requirement).uniq!
|
||||
end
|
||||
|
||||
current_detail
|
||||
end
|
||||
|
@ -803,7 +807,7 @@ module Gem::Resolver::Molinillo
|
|||
|
||||
possibilities.reverse_each do |possibility|
|
||||
dependencies = dependencies_for(possibility)
|
||||
if current_possibility_set && current_possibility_set.dependencies == dependencies
|
||||
if current_possibility_set && dependencies_equal?(current_possibility_set.dependencies, dependencies)
|
||||
current_possibility_set.possibilities.unshift(possibility)
|
||||
else
|
||||
possibility_sets.unshift(PossibilitySet.new(dependencies, [possibility]))
|
||||
|
|
|
@ -182,6 +182,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
@@default_value[k].nil?
|
||||
end
|
||||
|
||||
@@stubs = nil
|
||||
@@stubs_by_name = {}
|
||||
|
||||
# Sentinel object to represent "not found" stubs
|
||||
|
@ -665,6 +666,9 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
#
|
||||
# # Only prereleases or final releases after 2.6.0.preview2
|
||||
# spec.required_ruby_version = '> 2.6.0.preview2'
|
||||
#
|
||||
# # This gem will work with 2.3.0 or greater, including major version 3, but lesser than 4.0.0
|
||||
# spec.required_ruby_version = '>= 2.3', '< 4'
|
||||
|
||||
def required_ruby_version=(req)
|
||||
@required_ruby_version = Gem::Requirement.create req
|
||||
|
@ -800,10 +804,8 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
def self.stubs
|
||||
@@stubs ||= begin
|
||||
pattern = "*.gemspec"
|
||||
stubs = installed_stubs(dirs, pattern) + default_stubs(pattern)
|
||||
stubs = stubs.uniq {|stub| stub.full_name }
|
||||
stubs = stubs_for_pattern(pattern, false)
|
||||
|
||||
_resort!(stubs)
|
||||
@@stubs_by_name = stubs.select {|s| Gem::Platform.match_spec? s }.group_by(&:name)
|
||||
stubs
|
||||
end
|
||||
|
@ -820,31 +822,40 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
end
|
||||
end
|
||||
|
||||
EMPTY = [].freeze # :nodoc:
|
||||
|
||||
##
|
||||
# Returns a Gem::StubSpecification for installed gem named +name+
|
||||
# only returns stubs that match Gem.platforms
|
||||
|
||||
def self.stubs_for(name)
|
||||
if @@stubs_by_name[name]
|
||||
@@stubs_by_name[name]
|
||||
if @@stubs
|
||||
@@stubs_by_name[name] || []
|
||||
else
|
||||
pattern = "#{name}-*.gemspec"
|
||||
stubs = installed_stubs(dirs, pattern).select {|s| Gem::Platform.match_spec? s } + default_stubs(pattern)
|
||||
stubs = stubs.uniq {|stub| stub.full_name }.group_by(&:name)
|
||||
stubs.each_value {|v| _resort!(v) }
|
||||
|
||||
@@stubs_by_name.merge! stubs
|
||||
@@stubs_by_name[name] ||= EMPTY
|
||||
@@stubs_by_name[name] ||= stubs_for_pattern("#{name}-*.gemspec").select do |s|
|
||||
s.name == name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Finds stub specifications matching a pattern from the standard locations,
|
||||
# optionally filtering out specs not matching the current platform
|
||||
#
|
||||
def self.stubs_for_pattern(pattern, match_platform = true) # :nodoc:
|
||||
installed_stubs = installed_stubs(Gem::Specification.dirs, pattern)
|
||||
installed_stubs.select! {|s| Gem::Platform.match_spec? s } if match_platform
|
||||
stubs = installed_stubs + default_stubs(pattern)
|
||||
stubs = stubs.uniq {|stub| stub.full_name }
|
||||
_resort!(stubs)
|
||||
stubs
|
||||
end
|
||||
|
||||
def self._resort!(specs) # :nodoc:
|
||||
specs.sort! do |a, b|
|
||||
names = a.name <=> b.name
|
||||
next names if names.nonzero?
|
||||
b.version <=> a.version
|
||||
versions = b.version <=> a.version
|
||||
next versions if versions.nonzero?
|
||||
b.platform == Gem::Platform::RUBY ? -1 : 1
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1080,20 +1091,15 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
end
|
||||
|
||||
def self._latest_specs(specs, prerelease = false) # :nodoc:
|
||||
result = Hash.new {|h,k| h[k] = {} }
|
||||
native = {}
|
||||
result = {}
|
||||
|
||||
specs.reverse_each do |spec|
|
||||
next if spec.version.prerelease? unless prerelease
|
||||
|
||||
native[spec.name] = spec.version if spec.platform == Gem::Platform::RUBY
|
||||
result[spec.name][spec.platform] = spec
|
||||
result[spec.name] = spec
|
||||
end
|
||||
|
||||
result.map(&:last).map(&:values).flatten.reject do |spec|
|
||||
minimum = native[spec.name]
|
||||
minimum && spec.version < minimum
|
||||
end.sort_by{|tup| tup.name }
|
||||
result.map(&:last).flatten.sort_by{|tup| tup.name }
|
||||
end
|
||||
|
||||
##
|
||||
|
@ -1552,7 +1558,6 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
def build_extensions # :nodoc:
|
||||
return if default_gem?
|
||||
return if extensions.empty?
|
||||
return if installed_by_version < Gem::Version.new('2.2.0.preview.2')
|
||||
return if File.exist? gem_build_complete_path
|
||||
return if !File.writable?(base_dir)
|
||||
return if !File.exist?(File.join(base_dir, 'extensions'))
|
||||
|
@ -2123,7 +2128,6 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
def missing_extensions?
|
||||
return false if default_gem?
|
||||
return false if extensions.empty?
|
||||
return false if installed_by_version < Gem::Version.new('2.2.0.preview.2')
|
||||
return false if File.exist? gem_build_complete_path
|
||||
|
||||
true
|
||||
|
@ -2548,7 +2552,7 @@ class Gem::Specification < Gem::BasicSpecification
|
|||
begin
|
||||
dependencies.each do |dep|
|
||||
next unless dep.runtime?
|
||||
dep.to_specs.each do |dep_spec|
|
||||
dep.matching_specs(true).each do |dep_spec|
|
||||
next if visited.has_key?(dep_spec)
|
||||
visited[dep_spec] = true
|
||||
trail.push(dep_spec)
|
||||
|
|
|
@ -301,7 +301,9 @@ class Gem::TestCase < Minitest::Test
|
|||
|
||||
def setup
|
||||
@orig_env = ENV.to_hash
|
||||
@tmp = Dir.mktmpdir("tmp", Dir.pwd)
|
||||
@tmp = File.expand_path("tmp")
|
||||
|
||||
FileUtils.mkdir_p @tmp
|
||||
|
||||
ENV['GEM_VENDOR'] = nil
|
||||
ENV['GEMRC'] = nil
|
||||
|
@ -310,7 +312,6 @@ class Gem::TestCase < Minitest::Test
|
|||
ENV['XDG_DATA_HOME'] = nil
|
||||
ENV['SOURCE_DATE_EPOCH'] = nil
|
||||
ENV['BUNDLER_VERSION'] = nil
|
||||
ENV["TMPDIR"] = @tmp
|
||||
|
||||
@current_dir = Dir.pwd
|
||||
@fetcher = nil
|
||||
|
@ -321,13 +322,10 @@ class Gem::TestCase < Minitest::Test
|
|||
# capture output
|
||||
Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new
|
||||
|
||||
tmpdir = File.realpath Dir.tmpdir
|
||||
tmpdir.tap(&Gem::UNTAINT)
|
||||
|
||||
@tempdir = File.join(tmpdir, "test_rubygems_#{$$}")
|
||||
@tempdir = Dir.mktmpdir("test_rubygems_", @tmp)
|
||||
@tempdir.tap(&Gem::UNTAINT)
|
||||
|
||||
FileUtils.mkdir_p @tempdir
|
||||
ENV["TMPDIR"] = @tempdir
|
||||
|
||||
@orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
|
||||
Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
|
||||
|
@ -366,7 +364,9 @@ class Gem::TestCase < Minitest::Test
|
|||
Dir.chdir @tempdir
|
||||
|
||||
ENV['HOME'] = @userhome
|
||||
Gem.instance_variable_set :@config_file, nil
|
||||
Gem.instance_variable_set :@user_home, nil
|
||||
Gem.instance_variable_set :@config_home, nil
|
||||
Gem.instance_variable_set :@data_home, nil
|
||||
Gem.instance_variable_set :@gemdeps, nil
|
||||
Gem.instance_variable_set :@env_requirements_by_name, nil
|
||||
|
@ -449,7 +449,6 @@ class Gem::TestCase < Minitest::Test
|
|||
Dir.chdir @current_dir
|
||||
|
||||
FileUtils.rm_rf @tempdir
|
||||
FileUtils.rm_rf @tmp
|
||||
|
||||
ENV.replace(@orig_env)
|
||||
|
||||
|
|
|
@ -138,12 +138,12 @@ RSpec.describe "bundle executable" do
|
|||
|
||||
it "doesn't print defaults" do
|
||||
install_gemfile "", :verbose => true
|
||||
expect(out).to start_with("Running `bundle install --retry 0 --verbose` with bundler #{Bundler::VERSION}")
|
||||
expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}")
|
||||
end
|
||||
|
||||
it "doesn't print defaults" do
|
||||
install_gemfile "", :verbose => true
|
||||
expect(out).to start_with("Running `bundle install --retry 0 --verbose` with bundler #{Bundler::VERSION}")
|
||||
expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче