Merge RubyGems-3.2.13 and Bundler-2.2.13

This commit is contained in:
Hiroshi SHIBATA 2021-03-08 12:17:52 +09:00 committed by NARUSE, Yui
parent 06cd5711e0
commit 7efc7afcae
24 changed files with 477 additions and 267 deletions

View file

@ -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,6 +58,7 @@ 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",
}
@ -79,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
@ -175,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
@ -202,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

View file

@ -264,7 +264,7 @@ module Bundler
# 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, index, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
Resolver.resolve(expanded_dependencies, source_requirements, last_resolve, gem_version_promoter, additional_base_requirements_for_resolve, platforms)
end
end
end
@ -656,19 +656,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
@ -893,30 +894,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
@ -973,5 +962,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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -17,16 +17,21 @@ 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)
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 = {}
@ -40,7 +45,7 @@ module Bundler
@resolving_only_for_ruby = platforms == [Gem::Platform::RUBY]
@gem_version_promoter = gem_version_promoter
@use_gvp = Bundler.feature_flag.use_gem_version_promoter_for_major_updates? || !@gem_version_promoter.major?
@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"]
@ -125,8 +130,7 @@ module Bundler
dependency = dependency_proxy.dep
name = dependency.name
search_result = @search_for[dependency_proxy] ||= begin
index = index_for(dependency)
results = index.search(dependency, @base[name])
results = results_for(dependency, @base[name])
if vertex = @base_dg.vertex_named(name)
locked_requirement = vertex.payload.requirement
@ -196,22 +200,22 @@ module Bundler
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
@ -239,18 +243,20 @@ module Bundler
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,
@ -317,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?
@ -326,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
@ -392,7 +398,7 @@ module Bundler
if other_bundler_required
o << "\n\n"
candidate_specs = @source_requirements[:default_bundler].specs.search(conflict_dependency)
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(" ")
@ -411,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")
@ -455,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

View file

@ -5,15 +5,19 @@ module Bundler
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
@ -22,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
@ -41,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
@ -94,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.sort_by(&:to_s) != replacement_rubygems.remotes.sort_by(&:to_s)
false
end
@ -110,10 +111,6 @@ module Bundler
all_sources.each(&:remote!)
end
def rubygems_primary_remotes
@rubygems_aggregate.remotes
end
private
def rubygems_aggregate_class

View file

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

View file

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

View file

@ -8,7 +8,7 @@
require 'rbconfig'
module Gem
VERSION = "3.2.12".freeze
VERSION = "3.2.13".freeze
end
# Must be first since it unloads the prelude from 1.9.2

View file

@ -13,12 +13,13 @@ module CoreExtensions
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 = ()
Thread.new(addr) do
threads << Thread.new(addr) do
# give head start to ipv6 addresses
sleep IPV4_DELAY_SECONDS if addr.ipv4?
@ -40,6 +41,8 @@ module CoreExtensions
host = addrs.shift unless addrs.empty?
end
threads.each {|t| t.kill.join if t.alive? }
super(host, serv, *rest)
end
end

View file

@ -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
@ -146,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).
@ -162,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
##

View file

@ -112,6 +112,7 @@ RSpec.describe Bundler::Plugin do
before do
allow(Plugin::DSL).to receive(:new) { builder }
allow(builder).to receive(:eval_gemfile).with(gemfile)
allow(builder).to receive(:check_primary_source_safety)
allow(builder).to receive(:to_definition) { definition }
allow(builder).to receive(:inferred_plugins) { [] }
end

View file

@ -668,29 +668,40 @@ RSpec.describe "bundle exec" do
subject { bundle "exec #{path} arg1 arg2", :raise_on_error => false }
shared_examples_for "it runs" do
it "like a normally executed executable" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
it_behaves_like "it runs"
context "the executable exits explicitly" do
let(:executable) { super() << "\nexit #{exit_code}\nputs 'POST_EXIT'\n" }
context "with exit 0" do
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "with exit 99" do
let(:exit_code) { 99 }
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
end
@ -707,7 +718,15 @@ RSpec.describe "bundle exec" do
# this is specified by C99
128 + 15
end
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "the executable is empty" do
@ -716,7 +735,15 @@ RSpec.describe "bundle exec" do
let(:exit_code) { 0 }
let(:expected_err) { "#{path} is empty" }
let(:expected) { "" }
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "the executable raises" do
@ -743,12 +770,27 @@ RSpec.describe "bundle exec" do
let(:expected_err) { "bundler: failed to load command: #{path} (#{path})\n#{system_gem_path("bin/bundle")}: Err (Err)" }
let(:expected) { super() }
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "when the file uses the current ruby shebang" do
let(:shebang) { "#!#{Gem.ruby}" }
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "when Bundler.setup fails", :bundler => "< 3" do
@ -762,11 +804,19 @@ RSpec.describe "bundle exec" do
let(:exit_code) { Bundler::GemNotFound.new.status_code }
let(:expected) { "" }
let(:expected_err) { <<-EOS.strip }
\e[31mCould not find gem 'rack (= 2)' in any of the gem sources listed in your Gemfile.\e[0m
\e[31mCould not find gem 'rack (= 2)' in locally installed gems.
The source contains the following versions of 'rack': 0.9.1, 1.0.0\e[0m
\e[33mRun `bundle install` to install missing gems.\e[0m
EOS
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "when Bundler.setup fails", :bundler => "3" do
@ -785,14 +835,28 @@ The source contains the following versions of 'rack': 1.0.0\e[0m
\e[33mRun `bundle install` to install missing gems.\e[0m
EOS
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "when the executable exits non-zero via at_exit" do
let(:executable) { super() + "\n\nat_exit { $! ? raise($!) : exit(1) }" }
let(:exit_code) { 1 }
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "when disable_exec_load is set" do
@ -803,7 +867,14 @@ The source contains the following versions of 'rack': 1.0.0\e[0m
bundle "config set disable_exec_load true"
end
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "regarding $0 and __FILE__" do
@ -819,12 +890,26 @@ $0: #{path.to_s.inspect}
__FILE__: #{path.to_s.inspect}
EOS
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
context "when the path is relative" do
let(:path) { super().relative_path_from(bundled_app) }
it_behaves_like "it runs"
it "runs" do
skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform?
subject
expect(exitstatus).to eq(exit_code)
expect(err).to eq(expected_err)
expect(out).to eq(expected)
end
end
context "when the path is relative with a leading ./" do

View file

@ -28,44 +28,9 @@ RSpec.describe "bundle gem" do
let(:require_path) { "mygem" }
before do
git_config_content = <<-EOF
[user]
name = "Bundler User"
email = user@example.com
[github]
user = bundleuser
EOF
@git_config_location = ENV["GIT_CONFIG"]
path = "#{tmp}/test_git_config.txt"
File.open(path, "w") {|f| f.write(git_config_content) }
ENV["GIT_CONFIG"] = path
end
after do
FileUtils.rm(ENV["GIT_CONFIG"]) if File.exist?(ENV["GIT_CONFIG"])
ENV["GIT_CONFIG"] = @git_config_location
end
shared_examples_for "git config is present" do
context "git config user.{name,email} present" do
it "sets gemspec author to git user.name if available" do
expect(generated_gemspec.authors.first).to eq("Bundler User")
end
it "sets gemspec email to git user.email if available" do
expect(generated_gemspec.email.first).to eq("user@example.com")
end
end
end
shared_examples_for "git config is absent" do
it "sets gemspec author to default message if git user.name is not set or empty" do
expect(generated_gemspec.authors.first).to eq("TODO: Write your name")
end
it "sets gemspec email to default message if git user.email is not set or empty" do
expect(generated_gemspec.email.first).to eq("TODO: Write your email address")
end
sys_exec("git config --global user.name 'Bundler User'")
sys_exec("git config --global user.email user@example.com")
sys_exec("git config --global github.user bundleuser")
end
describe "git repo initialization" do
@ -125,19 +90,24 @@ RSpec.describe "bundle gem" do
end
shared_examples_for "--coc flag" do
before do
bundle "gem #{gem_name} --coc"
end
it "generates a gem skeleton with MIT license" do
bundle "gem #{gem_name} --coc"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/CODE_OF_CONDUCT.md")).to exist
end
describe "README additions" do
it "generates the README with a section for the Code of Conduct" do
expect(bundled_app("#{gem_name}/README.md").read).to include("## Code of Conduct")
expect(bundled_app("#{gem_name}/README.md").read).to include("https://github.com/bundleuser/#{gem_name}/blob/master/CODE_OF_CONDUCT.md")
end
it "generates the README with a section for the Code of Conduct" do
bundle "gem #{gem_name} --coc"
expect(bundled_app("#{gem_name}/README.md").read).to include("## Code of Conduct")
expect(bundled_app("#{gem_name}/README.md").read).to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
end
it "generates the README with a section for the Code of Conduct, respecting the configured git default branch" do
sys_exec("git config --global init.defaultBranch main")
bundle "gem #{gem_name} --coc"
expect(bundled_app("#{gem_name}/README.md").read).to include("## Code of Conduct")
expect(bundled_app("#{gem_name}/README.md").read).to include("https://github.com/bundleuser/#{gem_name}/blob/main/CODE_OF_CONDUCT.md")
end
end
@ -150,11 +120,9 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/CODE_OF_CONDUCT.md")).to_not exist
end
describe "README additions" do
it "generates the README without a section for the Code of Conduct" do
expect(bundled_app("#{gem_name}/README.md").read).not_to include("## Code of Conduct")
expect(bundled_app("#{gem_name}/README.md").read).not_to include("https://github.com/bundleuser/#{gem_name}/blob/master/CODE_OF_CONDUCT.md")
end
it "generates the README without a section for the Code of Conduct" do
expect(bundled_app("#{gem_name}/README.md").read).not_to include("## Code of Conduct")
expect(bundled_app("#{gem_name}/README.md").read).not_to match(%r{https://github\.com/bundleuser/#{gem_name}/blob/.*/CODE_OF_CONDUCT.md})
end
end
@ -302,7 +270,7 @@ RSpec.describe "bundle gem" do
context "git config github.user is absent" do
before do
sys_exec("git config --unset github.user")
sys_exec("git config --global --unset github.user")
bundle "gem #{gem_name}"
end
@ -413,17 +381,29 @@ RSpec.describe "bundle gem" do
bundle "gem #{gem_name}"
end
it_should_behave_like "git config is present"
it "sets gemspec author to git user.name if available" do
expect(generated_gemspec.authors.first).to eq("Bundler User")
end
it "sets gemspec email to git user.email if available" do
expect(generated_gemspec.email.first).to eq("user@example.com")
end
end
context "git config user.{name,email} is not set" do
before do
sys_exec("git config --unset user.name", :dir => bundled_app)
sys_exec("git config --unset user.email", :dir => bundled_app)
sys_exec("git config --global --unset user.name")
sys_exec("git config --global --unset user.email")
bundle "gem #{gem_name}"
end
it_should_behave_like "git config is absent"
it "sets gemspec author to default message if git user.name is not set or empty" do
expect(generated_gemspec.authors.first).to eq("TODO: Write your name")
end
it "sets gemspec email to default message if git user.email is not set or empty" do
expect(generated_gemspec.email.first).to eq("TODO: Write your email address")
end
end
it "sets gemspec metadata['allowed_push_host']" do
@ -1140,7 +1120,7 @@ Usage: "bundle gem NAME [OPTIONS]"
it "should fail gracefully" do
FileUtils.touch(bundled_app("conflict-foobar"))
bundle "gem conflict-foobar", :raise_on_error => false
expect(err).to include("Errno::ENOTDIR")
expect(err).to eq("Couldn't create a new gem named `conflict-foobar` because there's an existing file named `conflict-foobar`.")
expect(exitstatus).to eql(32)
end
end

View file

@ -113,16 +113,7 @@ RSpec.describe "post bundle message" do
bundle "config set force_ruby_platform true"
end
it "should report a helpful error message", :bundler => "< 3" do
install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"
gem "not-a-gem", :group => :development
G
expect(err).to include("Could not find gem 'not-a-gem' in any of the gem sources listed in your Gemfile.")
end
it "should report a helpful error message", :bundler => "3" do
it "should report a helpful error message" do
install_gemfile <<-G, :raise_on_error => false
source "#{file_uri_for(gem_repo1)}"
gem "rack"

View file

@ -422,14 +422,13 @@ RSpec.describe "bundle install from an existing gemspec" do
end
end
%w[ruby jruby].each do |platform|
simulate_platform(platform) do
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gemspec
G
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gemspec
G
simulate_platform("ruby") { bundle "install" }
simulate_platform("jruby") { bundle "install" }
end
context "on ruby" do

View file

@ -173,7 +173,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
@ -187,25 +187,19 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when disable_multisource is set" do
before do
bundle "config set disable_multisource true"
end
it "installs from the same source without any warning" do
bundle :install
it "installs from the same source without any warning" do
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
# In https://github.com/bundler/bundler/issues/3585 this failed
# when there is already a lock file, and the gems are missing, so try again
system_gems []
bundle :install
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0")
end
expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.")
expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", :source => "remote3")
end
end
end
@ -301,6 +295,33 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when a top-level gem can only be found in an scoped source" do
before do
build_repo2
build_repo gem_repo3 do
build_gem "private_gem_1", "1.0.0"
build_gem "private_gem_2", "1.0.0"
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "private_gem_1"
source "#{file_uri_for(gem_repo3)}" do
gem "private_gem_2"
end
G
end
it "fails" do
bundle :install, :raise_on_error => false
expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository #{file_uri_for(gem_repo2)}/ or installed locally.")
expect(err).to include("The source does not contain any versions of 'private_gem_1'")
end
end
context "when a top-level gem has an indirect dependency" do
context "when disable_multisource is set" do
before do
@ -497,6 +518,83 @@ RSpec.describe "bundle install with gems on multiple sources" do
end
end
context "when a top-level gem has an indirect dependency present in the default source, but with a different version from the one resolved", :bundler => "< 3" do
before do
build_lib "activesupport", "7.0.0.alpha", :path => lib_path("rails/activesupport")
build_lib "rails", "7.0.0.alpha", :path => lib_path("rails") do |s|
s.add_dependency "activesupport", "= 7.0.0.alpha"
end
build_repo gem_repo2 do
build_gem "activesupport", "6.1.2"
build_gem "webpacker", "5.2.1" do |s|
s.add_dependency "activesupport", ">= 5.2"
end
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gemspec :path => "#{lib_path("rails")}"
gem "webpacker", "~> 5.0"
G
end
it "installs all gems without warning" do
bundle :install
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", "rails 7.0.0.alpha")
expect(the_bundle).to include_gems("activesupport 7.0.0.alpha", :source => "path@#{lib_path("rails/activesupport")}")
expect(the_bundle).to include_gems("rails 7.0.0.alpha", :source => "path@#{lib_path("rails")}")
end
end
context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source ", :bundler => "< 3" do
before do
build_repo gem_repo3 do
build_gem "handsoap", "0.2.5.5" do |s|
s.add_dependency "nokogiri", ">= 1.2.3"
end
end
update_repo gem_repo2 do
build_gem "nokogiri", "1.11.1" do |s|
s.add_dependency "racca", "~> 1.4"
end
build_gem "racca", "1.5.2"
end
gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
source "#{file_uri_for(gem_repo3)}" do
gem "handsoap"
end
gem "nokogiri"
G
end
it "installs from the proper sources without any warnings or errors" do
bundle "install --verbose"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
# Even if the gems are already installed
FileUtils.rm bundled_app_lock
bundle "install --verbose"
expect(err).not_to include("Warning")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", "nokogiri 1.11.1", "racca 1.5.2")
expect(the_bundle).to include_gems("handsoap 0.2.5.5", :source => "remote3")
expect(the_bundle).to include_gems("nokogiri 1.11.1", "racca 1.5.2", :source => "remote2")
end
end
context "with a gem that is only found in the wrong source" do
before do
build_repo gem_repo3 do

View file

@ -30,7 +30,7 @@ module Spec
args[1] ||= Bundler::GemVersionPromoter.new # gem_version_promoter
args[2] ||= [] # additional_base_requirements
args[3] ||= @platforms # platforms
Bundler::Resolver.resolve(deps, @index, source_requirements, *args)
Bundler::Resolver.resolve(deps, source_requirements, *args)
end
def should_resolve_as(specs)

View file

@ -1958,15 +1958,9 @@ class TestGem < Gem::TestCase
io.write 'gem "a"'
end
platform = Bundler::GemHelpers.generic_local_platform
if platform == Gem::Platform::RUBY
platform = ''
else
platform = " #{platform}"
end
expected = <<-EXPECTED
Could not find gem 'a#{platform}' in any of the gem sources listed in your Gemfile.
Could not find gem 'a' in locally installed gems.
The source does not contain any versions of 'a'
You may need to `gem install -g` to install missing gems
EXPECTED

View file

@ -134,7 +134,9 @@ class TestGemPlatform < Gem::TestCase
'i386-solaris2.8' => ['x86', 'solaris', '2.8'],
'mswin32' => ['x86', 'mswin32', nil],
'x86_64-linux' => ['x86_64', 'linux', nil],
'x86_64-linux-gnu' => ['x86_64', 'linux', nil],
'x86_64-linux-musl' => ['x86_64', 'linux', 'musl'],
'x86_64-linux-uclibc' => ['x86_64', 'linux', 'uclibc'],
'x86_64-openbsd3.9' => ['x86_64', 'openbsd', '3.9'],
'x86_64-openbsd4.0' => ['x86_64', 'openbsd', '4.0'],
'x86_64-openbsd' => ['x86_64', 'openbsd', nil],
@ -143,6 +145,7 @@ class TestGemPlatform < Gem::TestCase
test_cases.each do |arch, expected|
platform = Gem::Platform.new arch
assert_equal expected, platform.to_a, arch.inspect
assert_equal expected, Gem::Platform.new(platform.to_s).to_a, arch.inspect
end
end
@ -261,6 +264,32 @@ class TestGemPlatform < Gem::TestCase
assert((with_x86_arch === with_nil_arch), 'x86 =~ nil')
end
def test_nil_version_is_treated_as_any_version
x86_darwin_8 = Gem::Platform.new 'i686-darwin8.0'
x86_darwin_nil = Gem::Platform.new 'i686-darwin'
assert((x86_darwin_8 === x86_darwin_nil), '8.0 =~ nil')
assert((x86_darwin_nil === x86_darwin_8), 'nil =~ 8.0')
end
def test_nil_version_is_stricter_for_linux_os
x86_linux = Gem::Platform.new 'i686-linux'
x86_linux_gnu = Gem::Platform.new 'i686-linux-gnu'
x86_linux_musl = Gem::Platform.new 'i686-linux-musl'
x86_linux_uclibc = Gem::Platform.new 'i686-linux-uclibc'
assert((x86_linux === x86_linux_gnu), 'linux =~ linux-gnu')
assert((x86_linux_gnu === x86_linux), 'linux-gnu =~ linux')
assert(!(x86_linux_gnu === x86_linux_musl), 'linux-gnu =~ linux-musl')
assert(!(x86_linux_musl === x86_linux_gnu), 'linux-musl =~ linux-gnu')
assert(!(x86_linux_uclibc === x86_linux_musl), 'linux-uclibc =~ linux-musl')
assert(!(x86_linux_musl === x86_linux_uclibc), 'linux-musl =~ linux-uclibc')
assert(!(x86_linux === x86_linux_musl), 'linux =~ linux-musl')
assert(!(x86_linux_musl === x86_linux), 'linux-musl =~ linux')
assert(!(x86_linux === x86_linux_uclibc), 'linux =~ linux-uclibc')
assert(!(x86_linux_uclibc === x86_linux), 'linux-uclibc =~ linux')
end
def test_equals3_cpu_arm
arm = Gem::Platform.new 'arm-linux'
armv5 = Gem::Platform.new 'armv5-linux'