ruby-changes:29821
From: drbrain <ko1@a...>
Date: Wed, 10 Jul 2013 08:21:58 +0900 (JST)
Subject: [ruby-changes:29821] drbrain:r41873 (trunk): * lib/rubygems: Import RubyGems 2.1
drbrain 2013-07-10 08:21:36 +0900 (Wed, 10 Jul 2013) New Revision: 41873 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41873 Log: * lib/rubygems: Import RubyGems 2.1 * test/rubygems: Ditto. Added directories: trunk/lib/rubygems/dependency_resolver/ trunk/lib/rubygems/request_set/ trunk/lib/rubygems/source/ trunk/lib/rubygems/util/ trunk/test/rubygems/specifications/ Added files: trunk/lib/rubygems/basic_specification.rb trunk/lib/rubygems/dependency_resolver/activation_request.rb trunk/lib/rubygems/dependency_resolver/api_set.rb trunk/lib/rubygems/dependency_resolver/api_specification.rb trunk/lib/rubygems/dependency_resolver/composed_set.rb trunk/lib/rubygems/dependency_resolver/current_set.rb trunk/lib/rubygems/dependency_resolver/dependency_conflict.rb trunk/lib/rubygems/dependency_resolver/dependency_request.rb trunk/lib/rubygems/dependency_resolver/index_set.rb trunk/lib/rubygems/dependency_resolver/index_specification.rb trunk/lib/rubygems/dependency_resolver/installed_specification.rb trunk/lib/rubygems/dependency_resolver/installer_set.rb trunk/lib/rubygems/install_default_message.rb trunk/lib/rubygems/request.rb trunk/lib/rubygems/request_set/gem_dependency_api.rb trunk/lib/rubygems/source/installed.rb trunk/lib/rubygems/source/local.rb trunk/lib/rubygems/source/specific_file.rb trunk/lib/rubygems/stub_specification.rb trunk/lib/rubygems/uri_formatter.rb trunk/lib/rubygems/util/list.rb trunk/test/rubygems/client.pem trunk/test/rubygems/encrypted_private_key.pem trunk/test/rubygems/invalid_client.pem trunk/test/rubygems/specifications/bar-0.0.2.gemspec trunk/test/rubygems/specifications/foo-0.0.1.gemspec trunk/test/rubygems/test_gem_dependency_resolver_dependency_conflict.rb trunk/test/rubygems/test_gem_impossible_dependencies_error.rb trunk/test/rubygems/test_gem_request.rb trunk/test/rubygems/test_gem_stub_specification.rb trunk/test/rubygems/test_gem_uri_formatter.rb Modified files: trunk/ChangeLog trunk/lib/rubygems/available_set.rb trunk/lib/rubygems/commands/cert_command.rb trunk/lib/rubygems/commands/cleanup_command.rb trunk/lib/rubygems/commands/environment_command.rb trunk/lib/rubygems/commands/help_command.rb trunk/lib/rubygems/commands/install_command.rb trunk/lib/rubygems/commands/owner_command.rb trunk/lib/rubygems/commands/pristine_command.rb trunk/lib/rubygems/commands/sources_command.rb trunk/lib/rubygems/commands/uninstall_command.rb trunk/lib/rubygems/config_file.rb trunk/lib/rubygems/core_ext/kernel_require.rb trunk/lib/rubygems/defaults.rb trunk/lib/rubygems/dependency.rb trunk/lib/rubygems/dependency_installer.rb trunk/lib/rubygems/dependency_resolver.rb trunk/lib/rubygems/exceptions.rb trunk/lib/rubygems/ext/builder.rb trunk/lib/rubygems/gem_runner.rb trunk/lib/rubygems/gemcutter_utilities.rb trunk/lib/rubygems/install_update_options.rb trunk/lib/rubygems/installer.rb trunk/lib/rubygems/name_tuple.rb trunk/lib/rubygems/package/tar_test_case.rb trunk/lib/rubygems/package/tar_writer.rb trunk/lib/rubygems/package.rb trunk/lib/rubygems/path_support.rb trunk/lib/rubygems/platform.rb trunk/lib/rubygems/remote_fetcher.rb trunk/lib/rubygems/request_set.rb trunk/lib/rubygems/security/policy.rb trunk/lib/rubygems/security/signer.rb trunk/lib/rubygems/security.rb trunk/lib/rubygems/source.rb trunk/lib/rubygems/source_local.rb trunk/lib/rubygems/source_specific_file.rb trunk/lib/rubygems/spec_fetcher.rb trunk/lib/rubygems/specification.rb trunk/lib/rubygems/test_case.rb trunk/lib/rubygems/uninstaller.rb trunk/lib/rubygems/version.rb trunk/lib/rubygems/version_option.rb trunk/lib/rubygems.rb trunk/test/rubygems/ca_cert.pem trunk/test/rubygems/test_gem.rb trunk/test/rubygems/test_gem_commands_cert_command.rb trunk/test/rubygems/test_gem_commands_cleanup_command.rb trunk/test/rubygems/test_gem_commands_contents_command.rb trunk/test/rubygems/test_gem_commands_environment_command.rb trunk/test/rubygems/test_gem_commands_help_command.rb trunk/test/rubygems/test_gem_commands_install_command.rb trunk/test/rubygems/test_gem_commands_owner_command.rb trunk/test/rubygems/test_gem_commands_pristine_command.rb trunk/test/rubygems/test_gem_commands_sources_command.rb trunk/test/rubygems/test_gem_commands_update_command.rb trunk/test/rubygems/test_gem_config_file.rb trunk/test/rubygems/test_gem_dependency_installer.rb trunk/test/rubygems/test_gem_dependency_resolver.rb trunk/test/rubygems/test_gem_gem_runner.rb trunk/test/rubygems/test_gem_install_update_options.rb trunk/test/rubygems/test_gem_installer.rb trunk/test/rubygems/test_gem_name_tuple.rb trunk/test/rubygems/test_gem_package.rb trunk/test/rubygems/test_gem_package_old.rb trunk/test/rubygems/test_gem_package_tar_reader.rb trunk/test/rubygems/test_gem_package_tar_reader_entry.rb trunk/test/rubygems/test_gem_package_tar_writer.rb trunk/test/rubygems/test_gem_path_support.rb trunk/test/rubygems/test_gem_platform.rb trunk/test/rubygems/test_gem_remote_fetcher.rb trunk/test/rubygems/test_gem_security.rb trunk/test/rubygems/test_gem_security_policy.rb trunk/test/rubygems/test_gem_security_signer.rb trunk/test/rubygems/test_gem_security_trust_dir.rb trunk/test/rubygems/test_gem_source.rb trunk/test/rubygems/test_gem_source_local.rb trunk/test/rubygems/test_gem_source_specific_file.rb trunk/test/rubygems/test_gem_specification.rb trunk/test/rubygems/test_gem_uninstaller.rb trunk/test/rubygems/test_gem_version.rb trunk/test/rubygems/test_gem_version_option.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 41872) +++ ChangeLog (revision 41873) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Jul 10 08:21:15 2013 Eric Hodel <drbrain@s...> + + * lib/rubygems: Import RubyGems 2.1 + * test/rubygems: Ditto. + Wed Jul 10 07:34:34 2013 Eric Hodel <drbrain@s...> * lib/rubygems/ext/ext_conf_builder.rb: Remove siteconf file after Index: lib/rubygems/basic_specification.rb =================================================================== --- lib/rubygems/basic_specification.rb (revision 0) +++ lib/rubygems/basic_specification.rb (revision 41873) @@ -0,0 +1,139 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/basic_specification.rb#L1 +module Gem + # BasicSpecification is an abstract class which implements some common code used by + # both Specification and StubSpecification. + class BasicSpecification + def self.default_specifications_dir + File.join(Gem.default_dir, "specifications", "default") + end + + ## + # Name of the gem + + def name + raise NotImplementedError + end + + ## + # Version of the gem + + def version + raise NotImplementedError + end + + ## + # Platform of the gem + + def platform + raise NotImplementedError + end + + ## + # Require paths of the gem + + def require_paths + raise NotImplementedError + end + + ## + # True when the gem has been activated + + def activated? + raise NotImplementedError + end + + ## + # Return a Gem::Specification from this gem + + def to_spec + raise NotImplementedError + end + + ## + # The filename of the gem specification + attr_reader :filename + + ## + # Set the filename of the Specification was loaded from. +path+ is converted + # to a String. + + def filename= path + @filename = path && path.to_s + + @full_gem_path = nil + @gems_dir = nil + @base_dir = nil + end + + ## + # Return true if this spec can require +file+. + + def contains_requirable_file? file + root = full_gem_path + suffixes = Gem.suffixes + + require_paths.any? do |lib| + base = "#{root}/#{lib}/#{file}" + suffixes.any? { |suf| File.file? "#{base}#{suf}" } + end + end + + ## + # The full path to the gem (install path + full name). + + def full_gem_path + # TODO: This is a heavily used method by gems, so we'll need + # to aleast just alias it to #gem_dir rather than remove it. + @full_gem_path ||= find_full_gem_path + end + + # :nodoc: + def find_full_gem_path + # TODO: also, shouldn't it default to full_name if it hasn't been written? + path = File.expand_path File.join(gems_dir, full_name) + path.untaint + path if File.directory? path + end + private :find_full_gem_path + + ## + # Returns the full path to the gems directory containing this spec's + # gem directory. eg: /usr/local/lib/ruby/1.8/gems + + def gems_dir + # TODO: this logic seems terribly broken, but tests fail if just base_dir + @gems_dir ||= File.join(filename && base_dir || Gem.dir, "gems") + end + + ## + # Returns the full path to the base gem directory. + # + # eg: /usr/local/lib/ruby/gems/1.8 + + def base_dir + return Gem.dir unless filename + @base_dir ||= if default_gem? then + File.dirname File.dirname File.dirname filename + else + File.dirname File.dirname filename + end + end + + def default_gem? + filename && + File.dirname(filename) == self.class.default_specifications_dir + end + + ## + # Returns the full name (name-version) of this Gem. Platform information + # is included (name-version-platform) if it is specified and not the + # default Ruby platform. + + def full_name + if platform == Gem::Platform::RUBY or platform.nil? then + "#{name}-#{version}".untaint + else + "#{name}-#{version}-#{platform}".untaint + end + end + end +end Property changes on: lib/rubygems/basic_specification.rb ___________________________________________________________________ Added: svn:eol-style + LF Index: lib/rubygems/path_support.rb =================================================================== --- lib/rubygems/path_support.rb (revision 41872) +++ lib/rubygems/path_support.rb (revision 41873) @@ -13,6 +13,10 @@ class Gem::PathSupport https://github.com/ruby/ruby/blob/trunk/lib/rubygems/path_support.rb#L13 attr_reader :path ## + # Directory with spec cache + attr_reader :spec_cache_dir # :nodoc: + + ## # # Constructor. Takes a single argument which is to be treated like a # hashtable, or defaults to ENV, the system environment. @@ -28,6 +32,10 @@ class Gem::PathSupport https://github.com/ruby/ruby/blob/trunk/lib/rubygems/path_support.rb#L32 end self.path = env["GEM_PATH"] || ENV["GEM_PATH"] + + @spec_cache_dir = + env["GEM_SPEC_CACHE"] || ENV["GEM_SPEC_CACHE"] || + Gem.default_spec_cache_dir end private Index: lib/rubygems/gemcutter_utilities.rb =================================================================== --- lib/rubygems/gemcutter_utilities.rb (revision 41872) +++ lib/rubygems/gemcutter_utilities.rb (revision 41873) @@ -1,11 +1,17 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/gemcutter_utilities.rb#L1 require 'rubygems/remote_fetcher' +## +# Utility methods for using the RubyGems API. + module Gem::GemcutterUtilities + # TODO: move to Gem::Command OptionParser.accept Symbol do |value| value.to_sym end + attr_writer :host + ## # Add the --key option @@ -17,6 +23,9 @@ module Gem::GemcutterUtilities https://github.com/ruby/ruby/blob/trunk/lib/rubygems/gemcutter_utilities.rb#L23 end end + ## + # The API key from the command options or from the user's configuration. + def api_key if options[:key] then verify_api_key options[:key] @@ -27,6 +36,47 @@ module Gem::GemcutterUtilities https://github.com/ruby/ruby/blob/trunk/lib/rubygems/gemcutter_utilities.rb#L36 end end + ## + # The host to connect to either from the RUBYGEMS_HOST environment variable + # or from the user's configuration + + def host + configured_host = Gem.host unless + Gem.configuration.disable_default_gem_server + + @host ||= + begin + env_rubygems_host = ENV['RUBYGEMS_HOST'] + env_rubygems_host = nil if + env_rubygems_host and env_rubygems_host.empty? + + env_rubygems_host|| configured_host + end + end + + ## + # Creates an RubyGems API to +host+ and +path+ with the given HTTP +method+. + + def rubygems_api_request(method, path, host = nil, &block) + require 'net/http' + + self.host = host if host + unless self.host + alert_error "You must specify a gem server" + terminate_interaction 1 # TODO: question this + end + + uri = URI.parse "#{self.host}/#{path}" + + request_method = Net::HTTP.const_get method.to_s.capitalize + + Gem::RemoteFetcher.fetcher.request(uri, request_method, &block) + end + + ## + # Signs in with the RubyGems API at +sign_in_host+ and sets the rubygems API + # key. + def sign_in sign_in_host = self.host return if Gem.configuration.rubygems_api_key @@ -55,47 +105,36 @@ module Gem::GemcutterUtilities https://github.com/ruby/ruby/blob/trunk/lib/rubygems/gemcutter_utilities.rb#L105 end end - attr_writer :host - def host - configured_host = Gem.host unless - Gem.configuration.disable_default_gem_server - - @host ||= - begin - env_rubygems_host = ENV['RUBYGEMS_HOST'] - env_rubygems_host = nil if - env_rubygems_host and env_rubygems_host.empty? - - env_rubygems_host|| configured_host - end - end - - def rubygems_api_request(method, path, host = nil, &block) - require 'net/http' + ## + # Retrieves the pre-configured API key +key+ or terminates interaction with + # an error. - self.host = host if host - unless self.host - alert_error "You must specify a gem server" + def verify_api_key(key) + if Gem.configuration.api_keys.key? key then + Gem.configuration.api_keys[key] + else + alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)." terminate_interaction 1 # TODO: question this end - - uri = URI.parse "#{self.host}/#{path}" - - request_method = Net::HTTP.const_get method.to_s.capitalize - - Gem::RemoteFetcher.fetcher.request(uri, request_method, &block) end - def with_response resp, error_prefix = nil - case resp + ## + # If +response+ is an HTTP Success (2XX) response, yields the response if a + # block was given or shows the response body to the user. + # + # If the response was not successful, shows an error to the user including + # the +error_prefix+ and the response body. + + def with_response response, error_prefix = nil + case response when Net::HTTPSuccess then if block_given? then - yield resp + yield response else - say resp.body + say response.body end else - message = resp.body + message = response.body message = "#{error_prefix}: #{message}" if error_prefix say message @@ -103,13 +142,5 @@ module Gem::GemcutterUtilities https://github.com/ruby/ruby/blob/trunk/lib/rubygems/gemcutter_utilities.rb#L142 end end - def verify_api_key(key) - if Gem.configuration.api_keys.key? key then - Gem.configuration.api_keys[key] - else - alert_error "No such API key. Please add it to your configuration (done automatically on initial `gem push`)." - terminate_interaction 1 # TODO: question this - end - end - end + Index: lib/rubygems/spec_fetcher.rb =================================================================== --- lib/rubygems/spec_fetcher.rb (revision 41872) +++ lib/rubygems/spec_fetcher.rb (revision 41873) @@ -38,7 +38,6 @@ class Gem::SpecFetcher https://github.com/ruby/ruby/blob/trunk/lib/rubygems/spec_fetcher.rb#L38 end def initialize - @dir = File.join Gem.user_home, '.gem', 'specs' @update_cache = File.stat(Gem.user_home).uid == Process.uid @specs = {} Index: lib/rubygems/available_set.rb =================================================================== --- lib/rubygems/available_set.rb (revision 41872) +++ lib/rubygems/available_set.rb (revision 41873) @@ -1,4 +1,7 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/available_set.rb#L1 class Gem::AvailableSet + + include Enumerable + Tuple = Struct.new(:spec, :source) def initialize @@ -36,6 +39,28 @@ class Gem::AvailableSet https://github.com/ruby/ruby/blob/trunk/lib/rubygems/available_set.rb#L39 self end + ## + # Yields each Tuple in this AvailableSet + + def each + return enum_for __method__ unless block_given? + + @set.each do |tuple| + yield tuple + end + end + + ## + # Yields the Gem::Specification for each Tuple in this AvailableSet + + def each_spec + return enum_for __method__ unless block_given? + + each do |tuple| + yield tuple.spec + end + end + def empty? @set.empty? end @@ -66,6 +91,49 @@ class Gem::AvailableSet https://github.com/ruby/ruby/blob/trunk/lib/rubygems/available_set.rb#L91 f.source end + ## + # Converts this AvailableSet into a RequestSet that can be used to install + # gems. + # + # If +development+ is :none then no development dependencies are installed. + # Other options are :shallow for only direct development dependencies of the + # gems in this set or :all for all development dependencies. + + def to_request_set development = :none + request_set = Gem::RequestSet.new + request_set.development = :all == development + + each_spec do |spec| + request_set.always_install << spec + + request_set.gem spec.name, spec.version + request_set.import spec.development_dependencies if + :shallow == development + end + + request_set + end + + ## + # + # Used by the DependencyResolver, the protocol to use a AvailableSet as a + # search Set. + + def find_all(req) + dep = req.dependency + + match = @set.find_all do |t| + dep.matches_spec? t.spec + end + + match.map do |t| + Gem::DependencyResolver::InstalledSpecification.new(self, t.spec, t.source) + end + end + + def prefetch(reqs) + end + def pick_best! return self if empty? Index: lib/rubygems/dependency_installer.rb =================================================================== --- lib/rubygems/dependency_installer.rb (revision 41872) +++ lib/rubygems/dependency_installer.rb (revision 41873) @@ -1,11 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L1 require 'rubygems' require 'rubygems/dependency_list' +require 'rubygems/dependency_resolver' require 'rubygems/package' require 'rubygems/installer' require 'rubygems/spec_fetcher' require 'rubygems/user_interaction' -require 'rubygems/source_local' -require 'rubygems/source_specific_file' +require 'rubygems/source/local' +require 'rubygems/source/specific_file' require 'rubygems/available_set' ## @@ -15,15 +16,7 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L16 include Gem::UserInteraction - attr_reader :gems_to_install - attr_reader :installed_gems - - ## - # Documentation types. For use by the Gem.done_installing hook - - attr_reader :document - - DEFAULT_OPTIONS = { + DEFAULT_OPTIONS = { # :nodoc: :env_shebang => false, :document => %w[ri], :domain => :both, # HACK dup @@ -35,9 +28,31 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L28 :wrappers => true, :build_args => nil, :build_docs_in_background => false, + :install_as_default => false }.freeze ## + # Documentation types. For use by the Gem.done_installing hook + + attr_reader :document + + ## + # Errors from SpecFetcher while searching for remote specifications + + attr_reader :errors + + ## + #-- + # TODO remove, no longer used + + attr_reader :gems_to_install # :nodoc: + + ## + # List of gems installed by #install in alphabetic order + + attr_reader :installed_gems + + ## # Creates a new installer instance. # # Options are: @@ -56,7 +71,8 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L71 # :wrappers:: See Gem::Installer::new # :build_args:: See Gem::Installer::new - def initialize(options = {}) + def initialize options = {} + @only_install_dir = !!options[:install_dir] @install_dir = options[:install_dir] || Gem.dir if options[:install_dir] then @@ -82,6 +98,7 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L98 @wrappers = options[:wrappers] @build_args = options[:build_args] @build_docs_in_background = options[:build_docs_in_background] + @install_as_default = options[:install_as_default] # Indicates that we should not try to update any deps unless # we absolutely must. @@ -93,13 +110,61 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L110 @cache_dir = options[:cache_dir] || @install_dir - # Set with any errors that SpecFetcher finds while search through - # gemspecs for a dep @errors = nil end - attr_reader :errors + ## + #-- + # TODO remove, no longer used + + def add_found_dependencies to_do, dependency_list # :nodoc: + seen = {} + dependencies = Hash.new { |h, name| h[name] = Gem::Dependency.new name } + + until to_do.empty? do + spec = to_do.shift + + # HACK why is spec nil? + next if spec.nil? or seen[spec.name] + seen[spec.name] = true + + deps = spec.runtime_dependencies + + if @development + if @dev_shallow + if @toplevel_specs.include? spec.full_name + deps |= spec.development_dependencies + end + else + deps |= spec.development_dependencies + end + end + + deps.each do |dep| + dependencies[dep.name] = dependencies[dep.name].merge dep + if @minimal_deps + next if Gem::Specification.any? do |installed_spec| + dep.name == installed_spec.name and + dep.requirement.satisfied_by? installed_spec.version + end + end + + results = find_gems_with_sources(dep) + + results.sorted.each do |t| + to_do.push t.spec + end + + results.remove_installed! dep + + @available << results + results.inject_into_list dependency_list + end + end + + dependency_list.remove_specs_unsatisfied_by dependencies + end ## # Creates an AvailableSet to install from based on +dep_or_name+ and # +version+ @@ -138,7 +203,7 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L203 # sources. Gems are sorted with newer gems preferred over older gems, and # local gems preferred over remote gems. - def find_gems_with_sources(dep) + def find_gems_with_sources dep # :nodoc: set = Gem::AvailableSet.new if consider_local? @@ -179,10 +244,52 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L244 end ## + # Finds a spec and the source_uri it came from for gem +gem_name+ and + # +version+. Returns an Array of specs and sources required for + # installation of the gem. + + def find_spec_by_name_and_version gem_name, + version = Gem::Requirement.default, + prerelease = false + + set = Gem::AvailableSet.new + + if consider_local? + if gem_name =~ /\.gem$/ and File.file? gem_name then + src = Gem::Source::SpecificFile.new(gem_name) + set.add src.spec, src + else + local = Gem::Source::Local.new + + if s = local.find_gem(gem_name, version) + set.add s, local + end + end + end + + if set.empty? + dep = Gem::Dependency.new gem_name, version + # HACK Dependency objects should be immutable + dep.prerelease = true if prerelease + + set = find_gems_with_sources(dep) + set.match_platform! + end + + if set.empty? + raise Gem::SpecificGemNotFoundException.new(gem_name, version, @errors) + end + + @available = set + end + + ## # Gathers all dependencies necessary for the installation from local and # remote sources unless the ignore_dependencies was given. + #-- + # TODO remove, no longer used - def gather_dependencies + def gather_dependencies # :nodoc: specs = @available.all_specs # these gems were listed by the user, always install them @@ -214,93 +321,19 @@ class Gem::DependencyInstaller https://github.com/ruby/ruby/blob/trunk/lib/rubygems/dependency_installer.rb#L321 @gems_to_install = dependency_list.dependency_order.reverse end - def add_found_dependencies to_do, dependency_list - seen = {} - dependencies = Hash.new { |h, name| h[name] = Gem::Dependency.new name } - - until to_do.empty? do - spec = to_do.shift - - # HACK why is spec nil? - next if spec.nil? or seen[spec.name] - seen[spec.name] = true - - deps = spec.runtime_dependencies - (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/