Skip to content

Commit

Permalink
Showing 171 changed files with 836 additions and 439 deletions.
220 changes: 114 additions & 106 deletions core/src/main/java/org/jruby/ext/nkf/RubyNKF.java

Large diffs are not rendered by default.

19 changes: 16 additions & 3 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -1733,7 +1733,12 @@ public Operand buildDAsgn(final DAsgnNode dasgnNode) {
int depth = dasgnNode.getDepth();
Variable arg = getLocalVariable(dasgnNode.getName(), depth);
Operand value = build(dasgnNode.getValueNode());

// no use copying a variable to itself
if (arg == value) return value;

addInstr(new CopyInstr(arg, value));

return value;

// IMPORTANT: The return value of this method is value, not arg!
@@ -1909,6 +1914,7 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
// Now for opt args
if (opt > 0) {
int optIndex = argsNode.getOptArgIndex();
Variable temp = createTemporaryVariable();
for (int j = 0; j < opt; j++, argIndex++) {
// Jump to 'l' if this arg is not null. If null, fall through and build the default value!
Label l = getNewLabel();
@@ -1917,10 +1923,12 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
Variable av = getNewLocalVariable(argName, 0);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.opt, argName);
// You need at least required+j+1 incoming args for this opt arg to get an arg at all
addInstr(new ReceiveOptArgInstr(av, signature.required(), signature.pre(), j));
addInstr(BNEInstr.create(l, av, UndefinedValue.UNDEFINED)); // if 'av' is not undefined, go to default
build(n.getValue());
addInstr(new ReceiveOptArgInstr(temp, signature.required(), signature.pre(), j));
addInstr(BNEInstr.create(l, temp, UndefinedValue.UNDEFINED)); // if 'av' is not undefined, go to default
Operand defaultResult = build(n.getValue());
addInstr(new CopyInstr(temp, defaultResult));
addInstr(new LabelInstr(l));
addInstr(new CopyInstr(av, temp));
}
}

@@ -2752,7 +2760,12 @@ public Operand buildLiteral(LiteralNode literalNode) {
public Operand buildLocalAsgn(LocalAsgnNode localAsgnNode) {
Variable var = getLocalVariable(localAsgnNode.getName(), localAsgnNode.getDepth());
Operand value = build(localAsgnNode.getValueNode());

// no use copying a variable to itself
if (var == value) return value;

addInstr(new CopyInstr(var, value));

return value;

// IMPORTANT: The return value of this method is value, not var!
1 change: 1 addition & 0 deletions lib/ruby/stdlib/gauntlet_rubygems.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'gauntlet'

60 changes: 50 additions & 10 deletions lib/ruby/stdlib/rubygems.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# -*- ruby -*-
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
@@ -9,7 +10,7 @@
require 'thread'

module Gem
VERSION = '2.5.1'
VERSION = '2.6.1'
end

# Must be first since it unloads the prelude from 1.9.2
@@ -173,6 +174,14 @@ module Gem
@pre_reset_hooks ||= []
@post_reset_hooks ||= []

def self.env_requirement(gem_name)
@env_requirements_by_name ||= {}
@env_requirements_by_name[gem_name] ||= begin
req = ENV["GEM_REQUIREMENT_#{gem_name.upcase}"] || '>= 0'.freeze
Gem::Requirement.create(req)
end
end

##
# Try to activate a gem containing +path+. Returns true if
# activation succeeded or wasn't needed because it was already
@@ -191,8 +200,13 @@ def self.try_activate path

begin
spec.activate
rescue Gem::LoadError # this could fail due to gem dep collisions, go lax
Gem::Specification.find_by_name(spec.name).activate
rescue Gem::LoadError => e # this could fail due to gem dep collisions, go lax
spec_by_name = Gem::Specification.find_by_name(spec.name)
if spec_by_name.nil?
raise e
else
spec_by_name.activate
end
end

return true
@@ -238,7 +252,7 @@ def self.bin_path(name, exec_name = nil, *requirements)
specs = dep.matching_specs(true)

raise Gem::GemNotFoundException,
"can't find gem #{name} (#{requirements})" if specs.empty?
"can't find gem #{dep}" if specs.empty?

specs = specs.find_all { |spec|
spec.executables.include? exec_name
@@ -325,16 +339,38 @@ def self.deflate(data)
# lookup files.

def self.paths
@paths ||= Gem::PathSupport.new
@paths ||= Gem::PathSupport.new(ENV)
end

# Initialize the filesystem paths to use from +env+.
# +env+ is a hash-like object (typically ENV) that
# is queried for 'GEM_HOME', 'GEM_PATH', and 'GEM_SPEC_CACHE'
# Keys for the +env+ hash should be Strings, and values of the hash should
# be Strings or +nil+.

def self.paths=(env)
clear_paths
@paths = Gem::PathSupport.new env
target = {}
env.each_pair do |k,v|
case k
when 'GEM_HOME', 'GEM_PATH', 'GEM_SPEC_CACHE'
case v
when nil, String
target[k] = v
when Array
unless Gem::Deprecate.skip
warn <<-eowarn
Array values in the parameter are deprecated. Please use a String or nil.
An Array was passed in from #{caller[3]}
eowarn
end
target[k] = v.join File::PATH_SEPARATOR
end
else
target[k] = v
end
end
@paths = Gem::PathSupport.new ENV.to_hash.merge(target)
Gem::Specification.dirs = @paths.path
end

@@ -429,7 +465,9 @@ def self.find_files(glob, check_load_path=true)

files = find_files_from_load_path glob if check_load_path

files.concat Gem::Specification.stubs.map { |spec|
gem_specifications = @gemdeps ? Gem.loaded_specs.values : Gem::Specification.stubs

files.concat gem_specifications.map { |spec|
spec.matches_for_glob("#{glob}#{Gem.suffix_pattern}")
}.flatten

@@ -938,9 +976,11 @@ def self.ui
# by the unit tests to provide environment isolation.

def self.use_paths(home, *paths)
paths = nil if paths == [nil]
paths = paths.first if Array === Array(paths).first
self.paths = { "GEM_HOME" => home, "GEM_PATH" => paths }
paths.flatten!
paths.compact!
hash = { "GEM_HOME" => home, "GEM_PATH" => paths.empty? ? home : paths.join(File::PATH_SEPARATOR) }
hash.delete_if { |_, v| v.nil? }
self.paths = hash
end

##
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/available_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
class Gem::AvailableSet

include Enumerable
11 changes: 5 additions & 6 deletions lib/ruby/stdlib/rubygems/basic_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# BasicSpecification is an abstract class which implements some common code
# used by both Specification and StubSpecification.
@@ -94,7 +95,7 @@ def extension_dir
# Returns path to the extensions directory.

def extensions_dir
@extensions_dir ||= Gem.default_ext_dir_for(base_dir) ||
Gem.default_ext_dir_for(base_dir) ||
File.join(base_dir, 'extensions', Gem::Platform.local.to_s,
Gem.extension_api_version)
end
@@ -124,9 +125,9 @@ def full_gem_path

def full_name
if platform == Gem::Platform::RUBY or platform.nil? then
"#{name}-#{version}".untaint
"#{name}-#{version}".dup.untaint
else
"#{name}-#{version}-#{platform}".untaint
"#{name}-#{version}-#{platform}".dup.untaint
end
end

@@ -195,7 +196,6 @@ def gems_dir

def internal_init # :nodoc:
@extension_dir = nil
@extensions_dir = nil
@full_gem_path = nil
@gem_dir = nil
@ignored = nil
@@ -281,7 +281,7 @@ def lib_dirs_glob
self.require_paths.first
end

"#{self.full_gem_path}/#{dirs}".untaint
"#{self.full_gem_path}/#{dirs}".dup.untaint
end

##
@@ -325,4 +325,3 @@ def have_file? file, suffixes
end

end

18 changes: 15 additions & 3 deletions lib/ruby/stdlib/rubygems/command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -153,7 +154,7 @@ def execute

def show_lookup_failure(gem_name, version, errors, domain)
if errors and !errors.empty?
msg = "Could not find a valid gem '#{gem_name}' (#{version}), here is why:\n"
msg = "Could not find a valid gem '#{gem_name}' (#{version}), here is why:\n".dup
errors.each { |x| msg << " #{x.wordy}\n" }
alert_error msg
else
@@ -299,6 +300,8 @@ def invoke_with_build_args(args, build_args)

options[:build_args] = build_args

self.ui = Gem::SilentUI.new if options[:silent]

if options[:help] then
show_help
elsif @when_invoked then
@@ -519,10 +522,15 @@ def wrap(text, width) # :doc:
end
end

add_common_option('-q', '--quiet', 'Silence commands') do |value, options|
add_common_option('-q', '--quiet', 'Silence command progress meter') do |value, options|
Gem.configuration.verbose = false
end

add_common_option("--silent",
"Silence rubygems output") do |value, options|
options[:silent] = true
end

# Backtrace and config-file are added so they show up in the help
# commands. Both options are actually handled before the other
# options get parsed.
@@ -539,6 +547,11 @@ def wrap(text, width) # :doc:
'Turn on Ruby debugging') do
end

add_common_option('--norc',
'Avoid loading any .gemrc file') do
end


# :stopdoc:

HELP = <<-HELP
@@ -579,4 +592,3 @@ def wrap(text, width) # :doc:

module Gem::Commands
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/command_manager.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
5 changes: 5 additions & 0 deletions lib/ruby/stdlib/rubygems/commands/build_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/package'

@@ -41,6 +42,10 @@ def usage # :nodoc:
def execute
gemspec = get_one_gem_name

unless File.exist? gemspec
gemspec += '.gemspec' if File.exist? gemspec + '.gemspec'
end

if File.exist? gemspec then
spec = Gem::Specification.load gemspec

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/cert_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/security'
begin
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/check_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/version_option'
require 'rubygems/validator'
12 changes: 9 additions & 3 deletions lib/ruby/stdlib/rubygems/commands/cleanup_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/dependency_list'
require 'rubygems/uninstaller'
@@ -75,6 +76,9 @@ def execute
end

def clean_gems
@original_home = Gem.dir
@original_path = Gem.path

get_primary_gems
get_candidate_gems
get_gems_to_cleanup
@@ -86,9 +90,6 @@ def clean_gems

deps = deplist.strongly_connected_components.flatten

@original_home = Gem.dir
@original_path = Gem.path

deps.reverse_each do |spec|
uninstall_dep spec
end
@@ -107,6 +108,7 @@ def get_candidate_gems
end

def get_gems_to_cleanup

gems_to_cleanup = @candidate_gems.select { |spec|
@primary_gems[spec.name].version != spec.version
}
@@ -115,6 +117,10 @@ def get_gems_to_cleanup
spec.default_gem?
}

gems_to_cleanup = gems_to_cleanup.select { |spec|
spec.base_dir == @original_home
}

@default_gems += default_gems
@default_gems.uniq!
@gems_to_cleanup = gems_to_cleanup.uniq
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/contents_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'English'
require 'rubygems/command'
require 'rubygems/version_option'
5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems/commands/dependency_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/version_option'
@@ -99,7 +100,7 @@ def display_pipe specs # :nodoc:
end

def display_readable specs, reverse # :nodoc:
response = ''
response = String.new

specs.each do |spec|
response << print_dependencies(spec)
@@ -152,7 +153,7 @@ def ensure_specs specs # :nodoc:
end

def print_dependencies(spec, level = 0) # :nodoc:
response = ''
response = String.new
response << ' ' * level + "Gem #{spec.full_name}\n"
unless spec.dependencies.empty? then
spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
6 changes: 3 additions & 3 deletions lib/ruby/stdlib/rubygems/commands/environment_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Commands::EnvironmentCommand < Gem::Command
@@ -71,7 +72,7 @@ def usage # :nodoc:
end

def execute
out = ''
out = String.new
arg = options[:args][0]
out <<
case arg
@@ -103,7 +104,7 @@ def add_path out, path
end

def show_environment # :nodoc:
out = "RubyGems Environment:\n"
out = "RubyGems Environment:\n".dup

out << " - RUBYGEMS VERSION: #{Gem::VERSION}\n"

@@ -157,4 +158,3 @@ def show_environment # :nodoc:
end

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/fetch_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/version_option'
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/indexer'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/help_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Commands::HelpCommand < Gem::Command
2 changes: 2 additions & 0 deletions lib/ruby/stdlib/rubygems/commands/install_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/install_update_options'
require 'rubygems/dependency_installer'
@@ -185,6 +186,7 @@ def check_version # :nodoc:
end

def execute

if options.include? :gemdeps then
install_from_gemdeps
return # not reached
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/list_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/commands/query_command'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/lock_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Commands::LockCommand < Gem::Command
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/mirror_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

unless defined? Gem::Commands::MirrorCommand
5 changes: 5 additions & 0 deletions lib/ruby/stdlib/rubygems/commands/open_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'English'
require 'rubygems/command'
require 'rubygems/version_option'
@@ -14,6 +15,10 @@ def initialize
"Opens gem sources in EDITOR") do |editor, options|
options[:editor] = editor || get_env_editor
end
add_option('-v', '--version VERSION', String,
"Opens specific gem version") do |version|
options[:version] = version
end
end

def arguments # :nodoc:
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/outdated_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/spec_fetcher'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/owner_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/pristine_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/package'
require 'rubygems/installer'
11 changes: 8 additions & 3 deletions lib/ruby/stdlib/rubygems/commands/push_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities'
@@ -75,13 +76,17 @@ def send_gem name
@host = gem_data.spec.metadata['default_gem_server']
end

# Always include this, even if it's nil
args << @host
push_host = nil

if gem_data.spec.metadata.has_key?('allowed_push_host')
args << gem_data.spec.metadata['allowed_push_host']
push_host = gem_data.spec.metadata['allowed_push_host']
end

@host ||= push_host

# Always include @host, even if it's nil
args += [ @host, push_host ]

say "Pushing gem to #{@host || Gem.host}..."

response = rubygems_api_request(*args) do |request|
17 changes: 12 additions & 5 deletions lib/ruby/stdlib/rubygems/commands/query_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/spec_fetcher'
@@ -49,6 +50,12 @@ def initialize(name = 'query',
options[:all] = value
end

add_option('-e', '--exact',
'Name of gem(s) to query on matches the',
'provided STRING') do |value, options|
options[:exact] = value
end

add_option( '--[no-]prerelease',
'Display prerelease versions') do |value, options|
options[:prerelease] = value
@@ -78,7 +85,8 @@ def execute
elsif !options[:name].source.empty?
name = Array(options[:name])
else
name = options[:args].to_a.map{|arg| /#{arg}/i }
args = options[:args].to_a
name = options[:exact] ? args : args.map{|arg| /#{arg}/i }
end

prerelease = options[:prerelease]
@@ -161,7 +169,7 @@ def show_gems name, prerelease
:latest
end

if name.source.empty?
if name.respond_to?(:source) && name.source.empty?
spec_tuples = fetcher.detect(type) { true }
else
spec_tuples = fetcher.detect(type) do |name_tuple|
@@ -276,7 +284,7 @@ def make_entry entry_tuples, platforms
end

def spec_authors entry, spec
authors = "Author#{spec.authors.length > 1 ? 's' : ''}: "
authors = "Author#{spec.authors.length > 1 ? 's' : ''}: ".dup
authors << spec.authors.join(', ')
entry << format_text(authors, 68, 4)
end
@@ -290,7 +298,7 @@ def spec_homepage entry, spec
def spec_license entry, spec
return if spec.license.nil? or spec.license.empty?

licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: "
licenses = "License#{spec.licenses.length > 1 ? 's' : ''}: ".dup
licenses << spec.licenses.join(', ')
entry << "\n" << format_text(licenses, 68, 4)
end
@@ -340,4 +348,3 @@ def spec_summary entry, spec
end

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/rdoc_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/version_option'
require 'rubygems/rdoc'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/search_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/commands/query_command'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/server_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/server'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/setup_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

##
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/sources_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/remote_fetcher'
require 'rubygems/spec_fetcher'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/specification_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/version_option'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/stale_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Commands::StaleCommand < Gem::Command
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/uninstall_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/version_option'
require 'rubygems/uninstaller'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/unpack_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/installer'
require 'rubygems/version_option'
2 changes: 2 additions & 0 deletions lib/ruby/stdlib/rubygems/commands/update_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/command_manager'
require 'rubygems/dependency_installer'
@@ -84,6 +85,7 @@ def check_update_arguments # :nodoc:
end

def execute

if options[:system] then
update_rubygems
return
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/commands/which_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Commands::WhichCommand < Gem::Command
26 changes: 11 additions & 15 deletions lib/ruby/stdlib/rubygems/commands/yank_command.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/version_option'
@@ -31,7 +32,7 @@ def arguments # :nodoc:
end

def usage # :nodoc:
"#{program_name} GEM -v VERSION [-p PLATFORM] [--undo] [--key KEY_NAME]"
"#{program_name} GEM -v VERSION [-p PLATFORM] [--key KEY_NAME] [--host HOST]"
end

def initialize
@@ -40,25 +41,25 @@ def initialize
add_version_option("remove")
add_platform_option("remove")

add_option('--undo') do |value, options|
options[:undo] = true
add_option('--host HOST',
'Yank from another gemcutter-compatible host') do |value, options|
options[:host] = value
end

add_key_option
@host = nil
end

def execute
sign_in
@host = options[:host]

sign_in @host

version = get_version_from_requirements(options[:version])
platform = get_platform_from_requirements(options)

if version then
if options[:undo] then
unyank_gem(version, platform)
else
yank_gem(version, platform)
end
yank_gem(version, platform)
else
say "A version argument is required: #{usage}"
terminate_interaction
@@ -70,16 +71,11 @@ def yank_gem(version, platform)
yank_api_request(:delete, version, platform, "api/v1/gems/yank")
end

def unyank_gem(version, platform)
say "Unyanking gem from #{host}..."
yank_api_request(:put, version, platform, "api/v1/gems/unyank")
end

private

def yank_api_request(method, version, platform, api)
name = get_one_gem_name
response = rubygems_api_request(method, api) do |request|
response = rubygems_api_request(method, api, host) do |request|
request.add_field("Authorization", api_key)

data = {
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/compatibility.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# :stopdoc:

#--
23 changes: 17 additions & 6 deletions lib/ruby/stdlib/rubygems/config_file.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -200,11 +201,12 @@ def initialize(args)
result.merge load_file file
end


@hash = operating_system_config.merge platform_config
@hash = @hash.merge system_config
@hash = @hash.merge user_config
@hash = @hash.merge environment_config
unless arg_list.index '--norc'
@hash = @hash.merge system_config
@hash = @hash.merge user_config
@hash = @hash.merge environment_config
end

# HACK these override command-line args, which is bad
@backtrace = @hash[:backtrace] if @hash.key? :backtrace
@@ -304,9 +306,18 @@ def rubygems_api_key
# Sets the RubyGems.org API key to +api_key+

def rubygems_api_key= api_key
set_api_key :rubygems_api_key, api_key

@rubygems_api_key = api_key
end

##
# Set a specific host's API key to +api_key+

def set_api_key host, api_key
check_credentials_permissions

config = load_file(credentials_path).merge(:rubygems_api_key => api_key)
config = load_file(credentials_path).merge(host => api_key)

dirname = File.dirname credentials_path
Dir.mkdir(dirname) unless File.exist? dirname
@@ -318,7 +329,7 @@ def rubygems_api_key= api_key
f.write config.to_yaml
end

@rubygems_api_key = api_key
load_api_keys # reload
end

def load_file(filename)
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/core_ext/kernel_gem.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# RubyGems adds the #gem method to allow activation of specific gem versions
# and overrides the #require method on Kernel to make gems appear as if they
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/core_ext/kernel_require.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/defaults.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem
DEFAULT_HOST = "https://rubygems.org"

8 changes: 5 additions & 3 deletions lib/ruby/stdlib/rubygems/dependency.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The Dependency class holds a Gem name and a Gem::Requirement.

@@ -274,8 +275,9 @@ def merge other
end

def matching_specs platform_only = false
env_req = Gem.env_requirement(name)
matches = Gem::Specification.stubs_for(name).find_all { |spec|
requirement.satisfied_by? spec.version
requirement.satisfied_by?(spec.version) && env_req.satisfied_by?(spec.version)
}.map(&:to_spec)

if platform_only
@@ -306,9 +308,9 @@ def to_specs

if specs.empty?
total = Gem::Specification.to_a.size
msg = "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)\n"
msg = "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)\n".dup
else
msg = "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]\n"
msg = "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]\n".dup
end
msg << "Checked in 'GEM_PATH=#{Gem.path.join(File::PATH_SEPARATOR)}', execute `gem env` for more information"

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/dependency_installer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/dependency_list'
require 'rubygems/package'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/dependency_list.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/deprecate.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Provides a single method +deprecate+ to be used to declare when
# something is going away.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/doctor.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/user_interaction'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/errors.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# This file contains all the various exceptions and other errors that are used
# inside of RubyGems.
4 changes: 2 additions & 2 deletions lib/ruby/stdlib/rubygems/exceptions.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# TODO: the documentation in here is terrible.
#
# Each exception needs a brief description and the scenarios where it is
@@ -137,7 +138,7 @@ def build_message # :nodoc:
requester = requester ? requester.spec.full_name : 'The user'
dependency = @request.dependency

message = "#{requester} requires #{dependency} but it conflicted:\n"
message = "#{requester} requires #{dependency} but it conflicted:\n".dup

@conflicts.each do |_, conflict|
message << conflict.explanation
@@ -267,4 +268,3 @@ def version
# Backwards compatible typo'd exception class for early RubyGems 2.0.x

Gem::UnsatisfiableDepedencyError = Gem::UnsatisfiableDependencyError # :nodoc:

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/ext.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/ext/build_error.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Raised when there is an error while building extensions.

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/ext/builder.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/ext/cmake_builder.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/command'

class Gem::Ext::CmakeBuilder < Gem::Ext::Builder
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/ext/configure_builder.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
19 changes: 15 additions & 4 deletions lib/ruby/stdlib/rubygems/ext/ext_conf_builder.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -11,9 +12,20 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
FileEntry = FileUtils::Entry_ # :nodoc:

def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil)
# relative path required as some versions of mktmpdir return an absolute
# path which breaks make if it includes a space in the name
tmp_dest = get_relative_path(Dir.mktmpdir(".gem.", "."))
tmp_dest = Dir.mktmpdir(".gem.", ".")

# Some versions of `mktmpdir` return absolute paths, which will break make
# if the paths contain spaces. However, on Ruby 1.9.x on Windows, relative
# paths cause all C extension builds to fail.
#
# As such, we convert to a relative path unless we are using Ruby 1.9.x on
# Windows. This means that when using Ruby 1.9.x on Windows, paths with
# spaces do not work.
#
# Details: https://github.com/rubygems/rubygems/issues/977#issuecomment-171544940
#
# TODO: Make this unconditional when rubygems no longer supports Ruby 1.9.x.
tmp_dest = get_relative_path(tmp_dest) unless Gem.win_platform? && RUBY_VERSION <= '2.0'

t = nil
Tempfile.open %w"siteconf .rb", "." do |siteconf|
@@ -80,4 +92,3 @@ def self.get_relative_path(path)
end

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/ext/rake_builder.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/gem_runner.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
22 changes: 18 additions & 4 deletions lib/ruby/stdlib/rubygems/gemcutter_utilities.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/remote_fetcher'

##
@@ -68,9 +69,14 @@ def rubygems_api_request(method, path, host = nil, allowed_push_host = nil, &blo
terminate_interaction 1 # TODO: question this
end

if allowed_push_host and self.host != allowed_push_host
alert_error "#{self.host.inspect} is not allowed by the gemspec, which only allows #{allowed_push_host.inspect}"
terminate_interaction 1
if allowed_push_host
allowed_host_uri = URI.parse(allowed_push_host)
host_uri = URI.parse(self.host)

unless (host_uri.scheme == allowed_host_uri.scheme) && (host_uri.host == allowed_host_uri.host)
alert_error "#{self.host.inspect} is not allowed by the gemspec, which only allows #{allowed_push_host.inspect}"
terminate_interaction 1
end
end

uri = URI.parse "#{self.host}/#{path}"
@@ -109,7 +115,7 @@ def sign_in sign_in_host = nil

with_response response do |resp|
say "Signed in."
Gem.configuration.rubygems_api_key = resp.body
set_api_key host, resp.body
end
end

@@ -150,5 +156,13 @@ def with_response response, error_prefix = nil
end
end

def set_api_key host, key
if host == Gem::DEFAULT_HOST
Gem.configuration.rubygems_api_key = key
else
Gem.configuration.set_api_key host, key
end
end

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/indexer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/package'
require 'time'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/install_default_message.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/user_interaction'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/install_message.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/user_interaction'

7 changes: 7 additions & 0 deletions lib/ruby/stdlib/rubygems/install_update_options.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -173,6 +174,12 @@ def add_install_update_options
"meet version requirements") do |value, options|
options[:minimal_deps] = true
end

add_option(:"Install/Update", "--[no-]post-install-message",
"Print post install message") do |value, options|
options[:post_install_message] = value
end

end

##
17 changes: 12 additions & 5 deletions lib/ruby/stdlib/rubygems/installer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -212,15 +213,21 @@ def check_executable_overwrite filename # :nodoc:
next unless io.gets =~ /This file was generated by RubyGems/

ruby_executable = true
existing = io.read.slice(/^gem (['"])(.*?)(\1),/, 2)
existing = io.read.slice(%r{
^(
gem \s |
load \s Gem\.bin_path\(
)
(['"])(.*?)(\2),
}x, 3)
end

return if spec.name == existing

# somebody has written to RubyGems' directory, overwrite, too bad
return if Gem.default_bindir != @bin_dir and not ruby_executable

question = "#{spec.name}'s executable \"#{filename}\" conflicts with "
question = "#{spec.name}'s executable \"#{filename}\" conflicts with ".dup

if ruby_executable then
question << existing
@@ -296,7 +303,7 @@ def install
write_cache_file
end

say spec.post_install_message unless spec.post_install_message.nil?
say spec.post_install_message if options[:post_install_message] && !spec.post_install_message.nil?

Gem::Installer.install_lock.synchronize { Gem::Specification.reset }

@@ -626,7 +633,8 @@ def process_options # :nodoc:
:bin_dir => nil,
:env_shebang => false,
:force => false,
:only_install_dir => false
:only_install_dir => false,
:post_install_message => true
}.merge options

@env_shebang = options[:env_shebang]
@@ -711,7 +719,6 @@ def app_script_text(bin_file_name)
end
end
gem '#{spec.name}', version
load Gem.bin_path('#{spec.name}', '#{bin_file_name}', version)
TEXT
end
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/installer_test_case.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/test_case'
require 'rubygems/installer'

3 changes: 2 additions & 1 deletion lib/ruby/stdlib/rubygems/local_remote_options.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -23,7 +24,7 @@ def accept_uri_http
raise OptionParser::InvalidArgument, value
end

unless ['http', 'https', 'file'].include?(uri.scheme)
unless ['http', 'https', 'file', 's3'].include?(uri.scheme)
raise OptionParser::InvalidArgument, value
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/mock_gem_ui.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'stringio'
require 'rubygems/user_interaction'

3 changes: 2 additions & 1 deletion lib/ruby/stdlib/rubygems/name_tuple.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
#
# Represents a gem of name +name+ at +version+ of +platform+. These
@@ -53,7 +54,7 @@ def full_name
"#{@name}-#{@version}"
else
"#{@name}-#{@version}-#{@platform}"
end.untaint
end.dup.untaint
end

##
5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems/package.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
@@ -58,7 +59,7 @@ def initialize message, source = nil
if source
@path = source.path

message << " in #{path}" if path
message = message + " in #{path}" if path
end

super message
@@ -382,7 +383,7 @@ def extract_tar_gz io, destination_dir, pattern = "*" # :nodoc:
FileUtils.chmod entry.header.mode, destination
end if entry.file?

File.symlink(install_location(entry.header.linkname, destination_dir), destination) if entry.symlink?
File.symlink(entry.header.linkname, destination) if entry.symlink?

verbose destination
end
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/digest_io.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# IO wrapper that creates digests of contents written to the IO it wraps.

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/file_source.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The primary source of gems is a file on disk, including all usages
# internal to rubygems.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/io_source.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Supports reading and writing gems from/to a generic IO object. This is
# useful for other applications built on top of rubygems, such as
8 changes: 4 additions & 4 deletions lib/ruby/stdlib/rubygems/package/old.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -63,7 +64,7 @@ def extract_files destination_dir

destination = install_location full_name, destination_dir

file_data = ''
file_data = String.new

read_until_dashes io do |line|
file_data << line
@@ -94,7 +95,7 @@ def extract_files destination_dir
# Reads the file list section from the old-format gem +io+

def file_list io # :nodoc:
header = ''
header = String.new

read_until_dashes io do |line|
header << line
@@ -134,7 +135,7 @@ def spec

return @spec if @spec

yaml = ''
yaml = String.new

@gem.with_read_io do |io|
skip_ruby io
@@ -175,4 +176,3 @@ def verify
end

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/source.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
class Gem::Package::Source # :nodoc:
end

2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/package/tar_header.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
@@ -226,4 +227,3 @@ def oct(num, len)
end

end

2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/package/tar_reader.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
@@ -120,4 +121,3 @@ def seek name # :yields: entry
end

require 'rubygems/package/tar_reader/entry'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/tar_reader/entry.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
#++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/tar_test_case.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/test_case'
require 'rubygems/package'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package/tar_writer.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/package_task.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# Copyright (c) 2003, 2004 Jim Weirich, 2009 Eric Hodel
#
# Permission is hereby granted, free of charge, to any person obtaining
50 changes: 25 additions & 25 deletions lib/ruby/stdlib/rubygems/path_support.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
#
# Gem::PathSupport facilitates the GEM_HOME and GEM_PATH environment settings
@@ -21,43 +22,36 @@ class Gem::PathSupport
# Constructor. Takes a single argument which is to be treated like a
# hashtable, or defaults to ENV, the system environment.
#
def initialize(env=ENV)
@env = env

# note 'env' vs 'ENV'...
@home = env["GEM_HOME"] || ENV["GEM_HOME"] || Gem.default_dir
def initialize(env)
@home = env["GEM_HOME"] || Gem.default_dir

if File::ALT_SEPARATOR then
@home = @home.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
end

self.path = env["GEM_PATH"] || ENV["GEM_PATH"]
@path = split_gem_path env["GEM_PATH"], @home

@spec_cache_dir =
env["GEM_SPEC_CACHE"] || ENV["GEM_SPEC_CACHE"] ||
Gem.default_spec_cache_dir
@spec_cache_dir = env["GEM_SPEC_CACHE"] || Gem.default_spec_cache_dir

@spec_cache_dir = @spec_cache_dir.dup.untaint
end

private

##
# Set the Gem search path (as reported by Gem.path).
# Split the Gem search path (as reported by Gem.path).

def path=(gpaths)
def split_gem_path gpaths, home
# FIX: it should be [home, *path], not [*path, home]

gem_path = []

# FIX: I can't tell wtf this is doing.
gpaths ||= (ENV['GEM_PATH'] || "").empty? ? nil : ENV["GEM_PATH"]

if gpaths
if gpaths.kind_of?(Array)
gem_path = gpaths.dup
else
gem_path = gpaths.split(Gem.path_separator)
gem_path = gpaths.split(Gem.path_separator)
# Handle the path_separator being set to a regexp, which will cause
# end_with? to error
if gpaths =~ /#{Gem.path_separator}\z/
gem_path += default_path
end

if File::ALT_SEPARATOR then
@@ -66,15 +60,21 @@ def path=(gpaths)
end
end

gem_path << @home
gem_path << home
else
gem_path = Gem.default_path + [@home]

if defined?(APPLE_GEM_HOME)
gem_path << APPLE_GEM_HOME
end
gem_path = default_path
end

@path = gem_path.uniq
gem_path.uniq
end

# Return the default Gem path
def default_path
gem_path = Gem.default_path + [@home]

if defined?(APPLE_GEM_HOME)
gem_path << APPLE_GEM_HOME
end
gem_path
end
end
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/platform.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require "rubygems/deprecate"

##
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/psych_additions.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# This exists just to satisfy bugs in marshal'd gemspecs that
# contain a reference to YAML::PrivateType. We prune these out
# in Specification._load, but if we don't have the constant, Marshal
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/psych_tree.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem
if defined? ::Psych::Visitors
class NoAliasYAMLTree < Psych::Visitors::YAMLTree
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/rdoc.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/user_interaction'
require 'fileutils'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/remote_fetcher.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'
require 'rubygems/request'
require 'rubygems/uri_formatter'
5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems/request.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'net/http'
require 'thread'
require 'time'
@@ -155,7 +156,7 @@ def perform_request request # :nodoc:
if Net::HTTPOK === incomplete_response
reporter.fetch(file_name, incomplete_response.content_length)
downloaded = 0
data = ''
data = String.new

incomplete_response.read_body do |segment|
data << segment
@@ -222,7 +223,7 @@ def reset(connection)
end

def user_agent
ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}"
ua = "RubyGems/#{Gem::VERSION} #{Gem::Platform.local}".dup

ruby_version = RUBY_VERSION
ruby_version += 'dev' if RUBY_PATCHLEVEL == -1
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/request/connection_pools.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'thread'

class Gem::Request::ConnectionPools # :nodoc:
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/request/http_pool.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A connection "pool" that only manages one connection for now. Provides
# thread safe `checkout` and `checkin` methods. The pool consists of one
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/request/https_pool.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
class Gem::Request::HTTPSPool < Gem::Request::HTTPPool # :nodoc:
private

22 changes: 14 additions & 8 deletions lib/ruby/stdlib/rubygems/request_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'tsort'

##
@@ -76,6 +77,11 @@ class Gem::RequestSet

attr_reader :vendor_set # :nodoc:

##
# The set of source gems imported via load_gemdeps.

attr_reader :source_set

##
# Creates a RequestSet for a list of Gem::Dependency objects, +deps+. You
# can then #resolve and #install the resolved list of dependencies.
@@ -105,6 +111,7 @@ def initialize *deps
@sorted = nil
@specs = nil
@vendor_set = nil
@source_set = nil

yield self if block_given?
end
@@ -142,7 +149,6 @@ def install options, &block # :yields: request, installer
return requests
end

cache_dir = options[:cache_dir] || Gem.dir
@prerelease = options[:prerelease]

requests = []
@@ -157,13 +163,11 @@ def install options, &block # :yields: request, installer
end
end

path = req.download cache_dir

inst = Gem::Installer.at path, options

yield req, inst if block_given?
spec = req.spec.install options do |installer|
yield req, installer if block_given?
end

requests << inst.install
requests << spec
end

return requests if options[:gemdeps]
@@ -271,10 +275,11 @@ def install_into dir, force = true, options = {}
def load_gemdeps path, without_groups = [], installing = false
@git_set = Gem::Resolver::GitSet.new
@vendor_set = Gem::Resolver::VendorSet.new
@source_set = Gem::Resolver::SourceSet.new

@git_set.root_dir = @install_dir

lock_file = "#{File.expand_path(path)}.lock".untaint
lock_file = "#{File.expand_path(path)}.lock".dup.untaint
begin
tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file lock_file
parser = tokenizer.make_parser self, []
@@ -338,6 +343,7 @@ def resolve set = Gem::Resolver::BestSet.new
@sets << set
@sets << @git_set
@sets << @vendor_set
@sets << @source_set

set = Gem::Resolver.compose_sets(*@sets)
set.remote = @remote
60 changes: 54 additions & 6 deletions lib/ruby/stdlib/rubygems/request_set/gem_dependency_api.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A semi-compatible DSL for the Bundler Gemfile and Isolate gem dependencies
# files.
@@ -204,6 +205,7 @@ def initialize set, path
@installing = false
@requires = Hash.new { |h, name| h[name] = [] }
@vendor_set = @set.vendor_set
@source_set = @set.source_set
@gem_sources = {}
@without_groups = []

@@ -362,6 +364,7 @@ def gem name, *requirements
source_set ||= gem_path name, options
source_set ||= gem_git name, options
source_set ||= gem_git_source name, options
source_set ||= gem_source name, options

duplicate = @dependencies.include? name

@@ -407,11 +410,7 @@ def gem_git name, options # :nodoc:

pin_gem_source name, :git, repository

reference = nil
reference ||= options.delete :ref
reference ||= options.delete :branch
reference ||= options.delete :tag
reference ||= 'master'
reference = gem_git_reference options

submodules = options.delete :submodules

@@ -420,6 +419,36 @@ def gem_git name, options # :nodoc:
true
end

##
# Handles the git options from +options+ for git gem.
#
# Returns reference for the git gem.

def gem_git_reference options # :nodoc:
ref = options.delete :ref
branch = options.delete :branch
tag = options.delete :tag

reference = nil
reference ||= ref
reference ||= branch
reference ||= tag
reference ||= 'master'

if ref && branch
warn <<-WARNING
Gem dependencies file #{@path} includes git reference for both ref and branch but only ref is used.
WARNING
end
if (ref||branch) && tag
warn <<-WARNING
Gem dependencies file #{@path} includes git reference for both ref/branch and tag but only ref/branch is used.
WARNING
end

reference
end

private :gem_git

##
@@ -480,6 +509,23 @@ def gem_path name, options # :nodoc:

private :gem_path

##
# Handles the source: option from +options+ for gem +name+.
#
# Returns +true+ if the source option was handled.

def gem_source name, options # :nodoc:
return unless source = options.delete(:source)

pin_gem_source name, :source, source

@source_set.add_source_gem name, source

true
end

private :gem_source

##
# Handles the platforms: option from +options+. Returns true if the
# platform matches the current platform.
@@ -526,6 +572,7 @@ def gem_requires name, options # :nodoc:
else
@requires[name] << name
end
raise ArgumentError, "Unhandled gem options #{options.inspect}" unless options.empty?
end

private :gem_requires
@@ -611,6 +658,7 @@ def gemspec options = {}

add_dependencies groups, spec.development_dependencies

@vendor_set.add_vendor_gem spec.name, path
gem_requires spec.name, options
end

@@ -650,6 +698,7 @@ def pin_gem_source name, type = :default, source = nil
when :default then '(default)'
when :path then "path: #{source}"
when :git then "git: #{source}"
when :source then "source: #{source}"
else '(unknown)'
end

@@ -798,4 +847,3 @@ def source url
Gem::RequestSet::GemDepedencyAPI = self # :nodoc:

end

6 changes: 3 additions & 3 deletions lib/ruby/stdlib/rubygems/request_set/lockfile.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Parses a gem.deps.rb.lock file and constructs a LockSet containing the
# dependencies found inside. If the lock file is missing no LockSet is
@@ -129,8 +130,8 @@ def add_GIT out, git_requests
[source.repository, source.rev_parse]
end

out << "GIT"
by_repository_revision.each do |(repository, revision), requests|
out << "GIT"
out << " remote: #{repository}"
out << " revision: #{revision}"
out << " specs:"
@@ -143,9 +144,8 @@ def add_GIT out, git_requests
out << " #{dep.name}#{dep.requirement.for_lockfile}"
end
end
out << nil
end

out << nil
end

def relative_path_from dest, base # :nodoc:
27 changes: 18 additions & 9 deletions lib/ruby/stdlib/rubygems/request_set/lockfile/parser.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
class Gem::RequestSet::Lockfile::Parser
###
# Parses lockfiles
@@ -324,15 +325,24 @@ def peek # :nodoc:
@tokens.peek
end

def pinned_requirement name # :nodoc:
spec = @set.sets.select { |set|
Gem::Resolver::GitSet === set or
Gem::Resolver::VendorSet === set
}.map { |set|
set.specs[name]
}.compact.first
if [].respond_to? :flat_map
def pinned_requirement name # :nodoc:
requirement = Gem::Dependency.new name
specification = @set.sets.flat_map { |set|
set.find_all(requirement)
}.compact.first

spec.version
specification && specification.version
end
else # FIXME: remove when 1.8 is dropped
def pinned_requirement name # :nodoc:
requirement = Gem::Dependency.new name
specification = @set.sets.map { |set|
set.find_all(requirement)
}.flatten(1).compact.first

specification && specification.version
end
end

##
@@ -342,4 +352,3 @@ def unget token # :nodoc:
@tokens.unshift token
end
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/request_set/lockfile/tokenizer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'strscan'
require 'rubygems/request_set/lockfile/parser'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/requirement.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require "rubygems/version"
require "rubygems/deprecate"

2 changes: 2 additions & 0 deletions lib/ruby/stdlib/rubygems/resolver.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/dependency'
require 'rubygems/exceptions'
require 'rubygems/util'
@@ -278,6 +279,7 @@ def allow_missing?(dependency)
require 'rubygems/resolver/installer_set'
require 'rubygems/resolver/lock_set'
require 'rubygems/resolver/vendor_set'
require 'rubygems/resolver/source_set'

require 'rubygems/resolver/specification'
require 'rubygems/resolver/spec_specification'
23 changes: 18 additions & 5 deletions lib/ruby/stdlib/rubygems/resolver/activation_request.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Specifies a Specification object that should be activated. Also contains a
# dependency that was used to introduce this activation.
@@ -49,15 +50,27 @@ def development?
# Downloads a gem at +path+ and returns the file path.

def download path
if @spec.respond_to? :source
Gem.ensure_gem_subdirectories path

if @spec.respond_to? :sources
exception = nil
path = @spec.sources.find{ |source|
begin
source.download full_spec, path
rescue exception
end
}
return path if path
raise exception if exception

elsif @spec.respond_to? :source
source = @spec.source
source.download full_spec, path

else
source = Gem.sources.first
source.download full_spec, path
end

Gem.ensure_gem_subdirectories path

source.download full_spec, path
end

##
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/api_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The global rubygems pool, available via the rubygems.org API.
# Returns instances of APISpecification.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/api_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Represents a specification retrieved via the rubygems.org API.
#
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/best_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The BestSet chooses the best available method to query a remote index.
#
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/composed_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A ComposedSet allows multiple sets to be queried like a single set.
#
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/conflict.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Used internally to indicate that a dependency conflicted
# with a spec that would be activated.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/current_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A set which represents the installed gems. Respects
# all the normal settings that control where to look
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/dependency_request.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Used Internally. Wraps a Dependency object to also track which spec
# contained the Dependency.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/git_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A GitSet represents gems that are sourced from git repositories.
#
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/git_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A GitSpecification represents a gem that is sourced from a git repository
# and is being loaded through a gem dependencies file through the +git:+
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/index_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The global rubygems pool represented via the traditional
# source index.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/index_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Represents a possible Specification object returned from IndexSet. Used to
# delay needed to download full Specification objects when only the +name+
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# An InstalledSpecification represents a gem that is already installed
# locally.
13 changes: 9 additions & 4 deletions lib/ruby/stdlib/rubygems/resolver/installer_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A set of gems for installation sourced from remote sources and local .gem
# files
@@ -137,10 +138,14 @@ def find_all req

local_source = Gem::Source::Local.new

if local_spec = local_source.find_gem(name, dep.requirement) then
res << Gem::Resolver::IndexSpecification.new(
self, local_spec.name, local_spec.version,
local_source, local_spec.platform)
begin
if local_spec = local_source.find_gem(name, dep.requirement) then
res << Gem::Resolver::IndexSpecification.new(
self, local_spec.name, local_spec.version,
local_source, local_spec.platform)
end
rescue Gem::Package::FormatError
# ignore
end
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/local_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A LocalSpecification comes from a .gem file on the local filesystem.

9 changes: 4 additions & 5 deletions lib/ruby/stdlib/rubygems/resolver/lock_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A set of gems from a gem dependencies lockfile.

@@ -27,11 +28,9 @@ def initialize sources

def add name, version, platform # :nodoc:
version = Gem::Version.new version

specs = @sources.map do |source|
Gem::Resolver::LockSpecification.new self, name, version, source,
platform
end
specs = [
Gem::Resolver::LockSpecification.new(self, name, version, @sources, platform)
]

@specs.concat specs

8 changes: 6 additions & 2 deletions lib/ruby/stdlib/rubygems/resolver/lock_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The LockSpecification comes from a lockfile (Gem::RequestSet::Lockfile).
#
@@ -6,13 +7,16 @@

class Gem::Resolver::LockSpecification < Gem::Resolver::Specification

def initialize set, name, version, source, platform
attr_reader :sources

def initialize set, name, version, sources, platform
super()

@name = name
@platform = platform
@set = set
@source = source
@source = sources.first
@sources = sources
@version = version

@dependencies = []
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/molinillo.rb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
# frozen_string_literal: true
require 'rubygems/resolver/molinillo/lib/molinillo'
5 changes: 5 additions & 0 deletions lib/ruby/stdlib/rubygems/resolver/molinillo/lib/molinillo.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# frozen_string_literal: true
require 'rubygems/resolver/molinillo/lib/molinillo/gem_metadata'
require 'rubygems/resolver/molinillo/lib/molinillo/errors'
require 'rubygems/resolver/molinillo/lib/molinillo/resolver'
require 'rubygems/resolver/molinillo/lib/molinillo/modules/ui'
require 'rubygems/resolver/molinillo/lib/molinillo/modules/specification_provider'

# Gem::Resolver::Molinillo is a generic dependency resolution algorithm.
module Gem::Resolver::Molinillo
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'set'
require 'tsort'

@@ -14,8 +15,10 @@ def each

include TSort

# @visibility private
alias_method :tsort_each_node, :each

# @visibility private
def tsort_each_child(vertex, &block)
vertex.successors.each(&block)
end
@@ -41,12 +44,14 @@ def self.tsort(vertices)
# by {Vertex#name}
attr_reader :vertices

# Initializes an empty dependency graph
def initialize
@vertices = {}
end

# Initializes a copy of a {DependencyGraph}, ensuring that all {#vertices}
# are properly copied.
# @param [DependencyGraph] other the graph to copy.
def initialize_copy(other)
super
@vertices = {}
@@ -100,6 +105,7 @@ def add_child_vertex(name, payload, parent_names, requirement)
vertex
end

# Adds a vertex with the given name, or updates the existing one.
# @param [String] name
# @param [Object] payload
# @return [Vertex] the vertex that was added to `self`
@@ -121,6 +127,10 @@ def detach_vertex_named(name)
v.incoming_edges.delete(e)
detach_vertex_named(v.name) unless v.root? || v.predecessors.any?
end
vertex.incoming_edges.each do |e|
v = e.origin
v.outgoing_edges.delete(e)
end
end

# @param [String] name
@@ -150,6 +160,8 @@ def add_edge(origin, destination, requirement)

private

# Adds a new {Edge} to the dependency graph without checking for
# circularity.
def add_edge_no_circular(origin, destination, requirement)
edge = Edge.new(origin, destination, requirement)
origin.outgoing_edges << edge
@@ -174,6 +186,7 @@ class Vertex
attr_accessor :root
alias_method :root?, :root

# Initializes a vertex with the given name and payload.
# @param [String] name see {#name}
# @param [Object] payload see {#payload}
def initialize(name, payload)
@@ -240,6 +253,7 @@ def ==(other)
successors.to_set == other.successors.to_set
end

# @param [Vertex] other the other vertex to compare to
# @return [Boolean] whether the two vertices are equal, determined
# solely by {#name} and {#payload} equality
def shallow_eql?(other)
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# An error that occurred during the resolution process
class ResolverError < StandardError; end
@@ -11,6 +12,7 @@ class NoSuchDependencyError < ResolverError
# @return [Array<Object>] the specifications that depended upon {#dependency}
attr_accessor :required_by

# Initializes a new error with the given missing dependency.
# @param [Object] dependency @see {#dependency}
# @param [Array<Object>] required_by @see {#required_by}
def initialize(dependency, required_by = [])
@@ -19,6 +21,8 @@ def initialize(dependency, required_by = [])
super()
end

# The error message for the missing dependency, including the specifications
# that had this dependency.
def message
sources = required_by.map { |r| "`#{r}`" }.join(' and ')
message = "Unable to find a specification for `#{dependency}`"
@@ -36,6 +40,7 @@ class CircularDependencyError < ResolverError
# [Set<Object>] the dependencies responsible for causing the error
attr_reader :dependencies

# Initializes a new error with the given circular vertices.
# @param [Array<DependencyGraph::Vertex>] nodes the nodes in the dependency
# that caused the error
def initialize(nodes)
@@ -50,6 +55,7 @@ class VersionConflict < ResolverError
# resolution to fail
attr_reader :conflicts

# Initializes a new error with the given version conflicts.
# @param [{String => Resolution::Conflict}] conflicts see {#conflicts}
def initialize(conflicts)
pairs = []
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
VERSION = '0.4.0'
# The version of Gem::Resolver::Molinillo.
VERSION = '0.4.3'.freeze
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# Provides information about specifcations and dependencies to the resolver,
# allowing the {Resolver} class to remain generic while still providing power
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# Conveys information about the resolution process to a user.
module UI
@@ -57,7 +58,8 @@ def debug(depth = 0)
#
# @return [Boolean]
def debug?
@debug_mode ||= ENV['MOLINILLO_DEBUG']
return @debug_mode if defined?(@debug_mode)
@debug_mode = ENV['MOLINILLO_DEBUG']
end
end
end
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
class Resolver
# A specific resolution from a given {Resolver}
@@ -38,6 +39,7 @@ class Resolution
# @return [Array] the dependencies that were explicitly required
attr_reader :original_requested

# Initializes a new resolution.
# @param [SpecificationProvider] specification_provider
# see {#specification_provider}
# @param [UI] resolver_ui see {#resolver_ui}
@@ -340,33 +342,56 @@ def attempt_to_activate_existing_spec(existing_node)
# @return [Boolean] Whether the possibility was swapped into {#activated}
def attempt_to_swap_possibility
swapped = activated.dup
swapped.vertex_named(name).payload = possibility
return unless swapped.vertex_named(name).requirements.
vertex = swapped.vertex_named(name)
vertex.payload = possibility
return unless vertex.requirements.
all? { |r| requirement_satisfied_by?(r, swapped, possibility) }
attempt_to_activate_new_spec
return unless new_spec_satisfied?
actual_vertex = activated.vertex_named(name)
actual_vertex.payload = possibility
fixup_swapped_children(actual_vertex)
activate_spec
end

# Ensures there are no orphaned successors to the given {vertex}.
# @param [DependencyGraph::Vertex] vertex the vertex to fix up.
# @return [void]
def fixup_swapped_children(vertex)
payload = vertex.payload
dep_names = dependencies_for(payload).map(&method(:name_for))
vertex.successors.each do |succ|
if !dep_names.include?(succ.name) && !succ.root? && succ.predecessors.to_a == [vertex]
debug(depth) { "Removing orphaned spec #{succ.name} after swapping #{name}" }
activated.detach_vertex_named(succ.name)
requirements.delete_if { |r| name_for(r) == succ.name }
end
end
end

# Attempts to activate the current {#possibility} (given that it hasn't
# already been activated)
# @return [void]
def attempt_to_activate_new_spec
satisfied = begin
locked_requirement = locked_requirement_named(name)
requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
locked_spec_satisfied = !locked_requirement ||
requirement_satisfied_by?(locked_requirement, activated, possibility)
debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
requested_spec_satisfied && locked_spec_satisfied
end
if satisfied
if new_spec_satisfied?
activate_spec
else
create_conflict
unwind_for_conflict
end
end

# @return [Boolean] whether the current spec is satisfied as a new
# possibility.
def new_spec_satisfied?
locked_requirement = locked_requirement_named(name)
requested_spec_satisfied = requirement_satisfied_by?(requirement, activated, possibility)
locked_spec_satisfied = !locked_requirement ||
requirement_satisfied_by?(locked_requirement, activated, possibility)
debug(depth) { 'Unsatisfied by requested spec' } unless requested_spec_satisfied
debug(depth) { 'Unsatisfied by locked spec' } unless locked_spec_satisfied
requested_spec_satisfied && locked_spec_satisfied
end

# @param [String] requirement_name the spec name to search for
# @return [Object] the locked spec named `requirement_name`, if one
# is found on {#base}
@@ -392,7 +417,7 @@ def activate_spec
# @return [void]
def require_nested_dependencies_for(activated_spec)
nested_dependencies = dependencies_for(activated_spec)
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.map(&:to_s).join(', ')})" }
debug(depth) { "Requiring nested dependencies (#{nested_dependencies.join(', ')})" }
nested_dependencies.each { |d| activated.add_child_vertex(name_for(d), nil, [name_for(activated_spec)], d) }

push_state_for_requirements(requirements + nested_dependencies, nested_dependencies.size > 0)
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# frozen_string_literal: true
require 'rubygems/resolver/molinillo/lib/molinillo/dependency_graph'

module Gem::Resolver::Molinillo
# This class encapsulates a dependency resolver.
# The resolver is responsible for determining which set of dependencies to
# activate, with feedback from the the {#specification_provider}
# activate, with feedback from the {#specification_provider}
#
#
class Resolver
@@ -17,6 +18,7 @@ class Resolver
# during the resolution process
attr_reader :resolver_ui

# Initializes a new resolver.
# @param [SpecificationProvider] specification_provider
# see {#specification_provider}
# @param [UI] resolver_ui
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# frozen_string_literal: true
module Gem::Resolver::Molinillo
# A state that a {Resolution} can be in
# @attr [String] name
# @attr [Array<Object>] requirements
# @attr [DependencyGraph] activated
# @attr [Object] requirement
# @attr [Object] possibility
# @attr [Integer] depth
# @attr [Set<Object>] conflicts
# @attr [String] name the name of the current requirement
# @attr [Array<Object>] requirements currently unsatisfied requirements
# @attr [DependencyGraph] activated the graph of activated dependencies
# @attr [Object] requirement the current requirement
# @attr [Object] possibilities the possibilities to satisfy the current requirement
# @attr [Integer] depth the depth of the resolution
# @attr [Set<Object>] conflicts unresolved conflicts
ResolutionState = Struct.new(
:name,
:requirements,
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/requirement_list.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The RequirementList is used to hold the requirements being considered
# while resolving a set of gems.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Resolver sets are used to look up specifications (and their
# dependencies) used in resolution. This set is abstract.
48 changes: 48 additions & 0 deletions lib/ruby/stdlib/rubygems/resolver/source_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
##
# The SourceSet chooses the best available method to query a remote index.
#
# Kind off like BestSet but filters the sources for gems

class Gem::Resolver::SourceSet < Gem::Resolver::Set

##
# Creates a SourceSet for the given +sources+ or Gem::sources if none are
# specified. +sources+ must be a Gem::SourceList.

def initialize
super()

@links = {}
@sets = {}
end

def find_all req # :nodoc:
if set = get_set(req.dependency.name)
set.find_all req
else
[]
end
end

# potentially no-op
def prefetch reqs # :nodoc:
reqs.each do |req|
if set = get_set(req.dependency.name)
set.prefetch reqs
end
end
end

def add_source_gem name, source
@links[name] = source
end

private

def get_set(name)
link = @links[name]
@sets[link] ||= Gem::Source.new(link).dependency_resolver_set if link
end

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/spec_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The Resolver::SpecSpecification contains common functionality for
# Resolver specifications that are backed by a Gem::Specification.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A Resolver::Specification contains a subset of the information
# contained in a Gem::Specification. Only the information necessary for
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/stats.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
class Gem::Resolver::Stats
def initialize
@max_depth = 0
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/vendor_set.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A VendorSet represents gems that have been unpacked into a specific
# directory that contains a gemspec.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/resolver/vendor_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A VendorSpecification represents a gem that has been unpacked into a project
# and is being loaded through a gem dependencies file through the +path:+
5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems/security.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -339,7 +340,7 @@ class Exception < Gem::Exception; end
# Digest algorithm used to sign gems

DIGEST_ALGORITHM =
if defined?(OpenSSL::Digest) then
if defined?(OpenSSL::Digest::SHA1) then
OpenSSL::Digest::SHA1
end

@@ -355,7 +356,7 @@ class Exception < Gem::Exception; end
# Algorithm for creating the key pair used to sign gems

KEY_ALGORITHM =
if defined?(OpenSSL::PKey) then
if defined?(OpenSSL::PKey::RSA) then
OpenSSL::PKey::RSA
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/security/policies.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem::Security

##
4 changes: 2 additions & 2 deletions lib/ruby/stdlib/rubygems/security/policy.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/user_interaction'

##
@@ -157,7 +158,7 @@ def check_trust chain, digester, trust_dir
path = Gem::Security.trust_dir.cert_path root

unless File.exist? path then
message = "root cert #{root.subject} is not trusted"
message = "root cert #{root.subject} is not trusted".dup

message << " (root of signing cert #{chain.last.subject})" if
chain.length > 1
@@ -292,4 +293,3 @@ def verify_signatures spec, digests, signatures
alias to_s name # :nodoc:

end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/security/signer.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Basic OpenSSL-based package signing class.

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/security/trust_dir.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The TrustDir manages the trusted certificates for gem signature
# verification.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/server.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'webrick'
require 'zlib'
require 'erb'
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'uri'
require 'fileutils'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source/git.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'digest'
require 'rubygems/util'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source/installed.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Represents an installed gem. This is used for dependency resolution.

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source/local.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The local source finds gems in the current directory for fulfilling
# dependencies.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source/lock.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A Lock source wraps an installed gem's source and sorts before other sources
# during dependency resolution. This allows RubyGems to prefer gems from
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source/specific_file.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# A source representing a single .gem file. This is used for installation of
# local gems.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source/vendor.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# This represents a vendored source that is similar to an installed gem.

5 changes: 3 additions & 2 deletions lib/ruby/stdlib/rubygems/source_list.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/source'

##
@@ -9,7 +10,7 @@
# Or by adding them:
#
# sources = Gem::SourceList.new
# sources.add 'https://rubygems.example'
# sources << 'https://rubygems.example'
#
# The most common way to get a SourceList is Gem.sources.

@@ -58,7 +59,7 @@ def <<(obj)
Gem::Source.new(URI.parse(obj))
end

@sources << src
@sources << src unless @sources.include?(src)
src
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source_local.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/source'
require 'rubygems/source_local'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/source_specific_file.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/source/specific_file'

# TODO warn upon require, this file is deprecated.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/spec_fetcher.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems/remote_fetcher'
require 'rubygems/user_interaction'
require 'rubygems/errors'
20 changes: 14 additions & 6 deletions lib/ruby/stdlib/rubygems/specification.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
@@ -1191,6 +1192,7 @@ def self.non_nil_attributes
def self.normalize_yaml_input(input)
result = input.respond_to?(:read) ? input.read : input
result = "--- " + result unless result =~ /\A--- /
result = result.dup
result.gsub!(/ !!null \n/, " \n")
# date: 2011-04-26 00:00:00.000000000Z
# date: 2011-04-26 00:00:00.000000000 Z
@@ -1682,6 +1684,8 @@ def conflicts
(conflicts[spec] ||= []) << dep
end
}
env_req = Gem.env_requirement(name)
(conflicts[self] ||= []) << env_req unless env_req.satisfied_by? version
conflicts
end

@@ -1699,6 +1703,7 @@ def conficts_when_loaded_with?(list_of_specs) # :nodoc:
# Return true if there are possible conflicts against the currently loaded specs.

def has_conflicts?
return true unless Gem.env_requirement(name).satisfied_by?(version)
self.dependencies.any? { |dep|
if dep.runtime? then
spec = Gem.loaded_specs[dep.name]
@@ -2333,7 +2338,7 @@ def ri_dir

def ruby_code(obj)
case obj
when String then obj.dump
when String then obj.dump + ".freeze"
when Array then '[' + obj.map { |x| ruby_code x }.join(", ") + ']'
when Hash then
seg = obj.keys.sort.map { |k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" }
@@ -2523,22 +2528,22 @@ def to_ruby
dependencies.each do |dep|
req = dep.requirements_list.inspect
dep.instance_variable_set :@type, :runtime if dep.type.nil? # HACK
result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>, #{req})"
result << " s.add_#{dep.type}_dependency(%q<#{dep.name}>.freeze, #{req})"
end

result << " else"

dependencies.each do |dep|
version_reqs_param = dep.requirements_list.inspect
result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
result << " s.add_dependency(%q<#{dep.name}>.freeze, #{version_reqs_param})"
end

result << ' end'

result << " else"
dependencies.each do |dep|
version_reqs_param = dep.requirements_list.inspect
result << " s.add_dependency(%q<#{dep.name}>, #{version_reqs_param})"
result << " s.add_dependency(%q<#{dep.name}>.freeze, #{version_reqs_param})"
end
result << " end"
end
@@ -2760,10 +2765,13 @@ def validate packaging = true
end

if !Gem::Licenses.match?(license)
warning <<-warning
WARNING: license value '#{license}' is invalid. Use a license identifier from
suggestions = Gem::Licenses.suggestions(license)
message = <<-warning
license value '#{license}' is invalid. Use a license identifier from
http://spdx.org/licenses or '#{Gem::Licenses::NONSTANDARD}' for a nonstandard license.
warning
message += "Did you mean #{suggestions.map { |s| "'#{s}'"}.join(', ')}?\n" unless suggestions.nil?
warning(message)
end
}

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/stub_specification.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# Gem::StubSpecification reads the stub: line from the gemspec. This prevents
# us having to eval the entire gemspec in order to find out certain
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/syck_hack.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# :stopdoc:

# Hack to handle syck's DefaultKey bug
20 changes: 16 additions & 4 deletions lib/ruby/stdlib/rubygems/test_case.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# TODO: $SAFE = 1

begin
@@ -541,7 +542,7 @@ def create_tmpdir
# Enables pretty-print for all tests

def mu_pp(obj)
s = ''
s = String.new
s = PP.pp obj, s
s = s.force_encoding(Encoding.default_external) if defined? Encoding
s.chomp
@@ -569,7 +570,7 @@ def read_binary(path)
def write_file(path)
path = File.join @gemhome, path unless Pathname.new(path).absolute?
dir = File.dirname path
FileUtils.mkdir_p dir
FileUtils.mkdir_p dir unless File.directory? dir

open path, 'wb' do |io|
yield io if block_given?
@@ -1306,12 +1307,22 @@ def v string
def vendor_gem name = 'a', version = 1
directory = File.join 'vendor', name

FileUtils.mkdir_p directory

save_gemspec name, version, directory
end

##
# create_gemspec creates gem specification in given +direcotry+ or '.'
# for the given +name+ and +version+.
#
# Yields the +specification+ to the block, if given

def save_gemspec name = 'a', version = 1, directory = '.'
vendor_spec = Gem::Specification.new name, version do |specification|
yield specification if block_given?
end

FileUtils.mkdir_p directory

open File.join(directory, "#{name}.gemspec"), 'w' do |io|
io.write vendor_spec.to_ruby
end
@@ -1482,3 +1493,4 @@ def self.key_path key_name
pid = $$
END {tmpdirs.each {|dir| Dir.rmdir(dir)} if $$ == pid}
Gem.clear_paths

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/test_utilities.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'tempfile'
require 'rubygems'
require 'rubygems/remote_fetcher'
2 changes: 1 addition & 1 deletion lib/ruby/stdlib/rubygems/text.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'rubygems'

##
@@ -70,4 +71,3 @@ def levenshtein_distance str1, str2
return x
end
end

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/uninstaller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/uri_formatter.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
require 'cgi'
require 'uri'

1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/user_interaction.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
3 changes: 2 additions & 1 deletion lib/ruby/stdlib/rubygems/util.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# This module contains various utility methods as module methods.

@@ -24,7 +25,7 @@ def self.gunzip(data)
def self.gzip(data)
require 'zlib'
require 'stringio'
zipped = StringIO.new('','w')
zipped = StringIO.new(String.new, 'w')
zipped.set_encoding Encoding::BINARY if Object.const_defined? :Encoding

Zlib::GzipWriter.wrap zipped do |io| io.write data end
14 changes: 14 additions & 0 deletions lib/ruby/stdlib/rubygems/util/licenses.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# frozen_string_literal: true
require 'rubygems/text'

class Gem::Licenses
extend Gem::Text

NONSTANDARD = 'Nonstandard'.freeze

# Software Package Data Exchange (SPDX) standard open-source software
@@ -326,4 +331,13 @@ class Gem::Licenses
def self.match?(license)
!REGEXP.match(license).nil?
end

def self.suggestions(license)
by_distance = IDENTIFIERS.group_by do |identifier|
levenshtein_distance(identifier, license)
end
lowest = by_distance.keys.min
return unless lowest < license.size
by_distance[lowest]
end
end
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/util/list.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
module Gem
class List
include Enumerable
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/validator.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
34 changes: 21 additions & 13 deletions lib/ruby/stdlib/rubygems/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
##
# The Version class processes string versions into comparable
# values. A version string should normally be a series of numbers
@@ -218,7 +219,7 @@ def initialize version

def bump
@bump ||= begin
segments = self.segments.dup
segments = self.segments
segments.pop while segments.any? { |s| String === s }
segments.pop if segments.size > 1

@@ -281,7 +282,10 @@ def encode_with coder # :nodoc:
# A version is considered a prerelease if it contains a letter.

def prerelease?
@prerelease ||= !!(@version =~ /[a-zA-Z]/)
unless instance_variable_defined? :@prerelease
@prerelease = !!(@version =~ /[a-zA-Z]/)
end
@prerelease
end

def pretty_print q # :nodoc:
@@ -294,7 +298,7 @@ def pretty_print q # :nodoc:

def release
@release ||= if prerelease?
segments = self.segments.dup
segments = self.segments
segments.pop while segments.any? { |s| String === s }
self.class.new segments.join('.')
else
@@ -303,20 +307,14 @@ def release
end

def segments # :nodoc:

# segments is lazy so it can pick up version values that come from
# old marshaled versions, which don't go through marshal_load.

@segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
/^\d+$/ =~ s ? s.to_i : s
end
_segments.dup
end

##
# A recommended version for use with a ~> Requirement.

def approximate_recommendation
segments = self.segments.dup
segments = self.segments

segments.pop while segments.any? { |s| String === s }
segments.pop while segments.size > 2
@@ -335,8 +333,8 @@ def <=> other
return unless Gem::Version === other
return 0 if @version == other._version

lhsegments = segments
rhsegments = other.segments
lhsegments = _segments
rhsegments = other._segments

lhsize = lhsegments.size
rhsize = rhsegments.size
@@ -363,4 +361,14 @@ def <=> other
def _version
@version
end

def _segments
# segments is lazy so it can pick up version values that come from
# old marshaled versions, which don't go through marshal_load.
# since this version object is cached in @@all, its @segments should be frozen

@segments ||= @version.scan(/[0-9]+|[a-z]+/i).map do |s|
/^\d+$/ =~ s ? s.to_i : s
end.freeze
end
end
1 change: 1 addition & 0 deletions lib/ruby/stdlib/rubygems/version_option.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
1 change: 1 addition & 0 deletions lib/ruby/stdlib/ubygems.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: true
# This file allows for the running of rubygems with a nice
# command line look-and-feel: ruby -rubygems foo.rb
#--
16 changes: 16 additions & 0 deletions spec/compiler/general_spec.rb
Original file line number Diff line number Diff line change
@@ -1068,5 +1068,21 @@ def a; __callee__; end
expect(y).to eq(1)
end
end

it "handles circular optional argument assignment" do
begin
verbose = $VERBOSE
$VERBOSE = nil

run('def foo(a = a, b = b, c = c); [a.inspect, b.inspect, c.inspect]; end; foo') do |x|
expect(x).to eq(["nil", "nil", "nil"])
end
run('def foo; yield; end; foo {|a = a, b = b, c = c|; [a.inspect, b.inspect, c.inspect]}') do |x|
expect(x).to eq(["nil", "nil", "nil"])
end
ensure
$VERBOSE = verbose
end
end
end
end
118 changes: 0 additions & 118 deletions test/jruby/test_nkf.rb

This file was deleted.

4 changes: 0 additions & 4 deletions test/mri/excludes/TestKconv.rb

This file was deleted.

File renamed without changes.

0 comments on commit 4b05809

Please sign in to comment.