diff options
author | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-14 03:30:02 +0000 |
---|---|---|
committer | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-09-14 03:30:02 +0000 |
commit | 4de117a61517e839f2c45eaf45d56fc243d6d5b2 () | |
tree | 7cb5af7a7eb513e5dddf5e343746b1611e628387 | |
parent | e548c09d429a5136285ea81aed418685359ed124 (diff) |
* lib/rubygems: Update to RubyGems 2.4.1 master(713ab65)
Complete history at: https://.com/rubygems/rubygems/blob/master/History.txt#L3-L216 * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47582 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
153 files changed, 5394 insertions, 975 deletions
@@ -1,3 +1,11 @@ Sun Sep 14 11:03:24 2014 Aaron Patterson <[email protected]> * ext/psych/lib/psych.rb: update version @@ -6,9 +6,10 @@ #++ require 'rbconfig' module Gem - VERSION = '2.2.2' end # Must be first since it unloads the prelude from 1.9.2 @@ -56,8 +57,8 @@ require 'rubygems/errors' # RubyGems defaults are stored in rubygems/defaults.rb. If you're packaging # RubyGems or implementing Ruby you can change RubyGems' defaults. # -# For RubyGems packagers, provide lib/rubygems/operating_system.rb and -# override any defaults from lib/rubygems/defaults.rb. # # For Ruby implementers, provide lib/rubygems/defaults/#{RUBY_ENGINE}.rb and # override any defaults from lib/rubygems/defaults.rb. @@ -83,7 +84,7 @@ require 'rubygems/errors' # * Chad Fowler -- chad(at)chadfowler.com # * David Black -- dblack(at)wobblini.net # * Paul Brannan -- paul(at)atdesk.com -# * Jim Weirich -- jim(at)weirichhouse.org # # Contributors: # @@ -156,6 +157,7 @@ module Gem @configuration = nil @loaded_specs = {} @path_to_default_spec_map = {} @platforms = [] @ruby = nil @@ -298,7 +300,7 @@ module Gem end ## - # The path the the data directory specified by the gem name. If the # package is not available as a gem, return nil. def self.datadir(gem_name) @@ -544,9 +546,9 @@ module Gem # Fetching: minitest-3.0.1.gem (100%) # => [#<Gem::Specification:0x1013b4528 @name="minitest", ...>] - def self.install name, version = Gem::Requirement.default, **options require "rubygems/dependency_installer" - inst = Gem::DependencyInstaller.new(**options) inst.install name, version inst.installed_gems end @@ -995,19 +997,31 @@ module Gem end ## - # Looks for gem dependency files (gem.deps.rb, Gemfile, Isolate) from the - # current directory up and activates the gems in the first file found. # # You can run this automatically when rubygems starts. To enable, set # the <code>RUBYGEMS_GEMDEPS</code> environment variable to either the path - # of your Gemfile or "-" to auto-discover in parent directories. # # NOTE: Enabling automatic discovery on multiuser systems can lead to # execution of arbitrary code when used from directories outside your # control. - def self.use_gemdeps - return unless path = ENV['RUBYGEMS_GEMDEPS'] path = path.dup if path == "-" then @@ -1025,7 +1039,11 @@ module Gem path.untaint - return unless File.file? path rs = Gem::RequestSet.new rs.load_gemdeps path @@ -1035,6 +1053,10 @@ module Gem sp.activate sp end end class << self @@ -126,7 +126,7 @@ class Gem::AvailableSet dep = req.dependency match = @set.find_all do |t| - dep.matches_spec? t.spec end match.map do |t| @@ -15,6 +15,11 @@ class Gem::BasicSpecification attr_writer :extension_dir # :nodoc: ## # The path this gemspec was loaded from. This attribute is not persisted. attr_reader :loaded_from @@ -53,7 +58,16 @@ class Gem::BasicSpecification # Return true if this spec can require +file+. def contains_requirable_file? file - build_extensions suffixes = Gem.suffixes @@ -120,11 +134,11 @@ class Gem::BasicSpecification # activated. def full_require_paths - full_paths = @require_paths.map do |path| File.join full_gem_path, path end - full_paths.unshift extension_dir unless @extensions.empty? full_paths end @@ -176,7 +190,7 @@ class Gem::BasicSpecification end def raw_require_paths # :nodoc: - @require_paths end ## @@ -197,13 +211,9 @@ class Gem::BasicSpecification # spec.require_path = '.' def require_paths - return @require_paths if @extensions.empty? - - relative_extension_dir = - File.join '..', '..', 'extensions', Gem::Platform.local.to_s, - Gem.extension_api_version, full_name - [relative_extension_dir].concat @require_paths end ## @@ -148,6 +148,8 @@ class Gem::Command ## # Display to the user that a gem couldn't be found and reasons why def show_lookup_failure(gem_name, version, errors, domain) if errors and !errors.empty? @@ -557,7 +559,8 @@ basic help message containing pointers to more information. Further help: gem help commands list all 'gem' commands gem help examples show some examples of usage - gem help platforms show information about platforms gem help <COMMAND> show help on COMMAND (e.g. 'gem help install') gem server present a web page at @@ -48,6 +48,7 @@ class Gem::CommandManager :list, :lock, :mirror, :outdated, :owner, :pristine, @@ -129,23 +129,21 @@ class Gem::Commands::CertCommand < Gem::Command end def build_key # :nodoc: - if options[:key] then - options[:key] - else - passphrase = ask_for_password 'Passphrase for your Private Key:' - say "\n" - passphrase_confirmation = ask_for_password 'Please repeat the passphrase for your Private Key:' - say "\n" - raise Gem::CommandLineError, - "Passphrase and passphrase confirmation don't match" unless passphrase == passphrase_confirmation - key = Gem::Security.create_key - key_path = Gem::Security.write key, "gem-private_key.pem", 0600, passphrase - return key, key_path - end end def certificates_matching filter @@ -67,10 +67,10 @@ If no gems are named all gems in GEM_HOME are cleaned. say "Clean Up Complete" - if Gem.configuration.really_verbose then skipped = @default_gems.map { |spec| spec.full_name } - say "Skipped default gems: #{skipped.join ', '}" end end @@ -8,7 +8,8 @@ class Gem::Commands::ContentsCommand < Gem::Command def initialize super 'contents', 'Display the contents of the installed gems', - :specdirs => [], :lib_only => false, :prefix => true add_version_option @@ -32,6 +33,11 @@ class Gem::Commands::ContentsCommand < Gem::Command options[:prefix] = prefix end @path_kind = nil @spec_dirs = nil @version = nil @@ -65,7 +71,12 @@ prefix or only the files that are requireable. names = gem_names names.each do |name| - found = gem_contents name terminate_interaction 1 unless found or names.length > 1 end @@ -115,6 +126,16 @@ prefix or only the files that are requireable. true end def gem_names # :nodoc: if options[:all] then Gem::Specification.map(&:name) @@ -31,7 +31,7 @@ class Gem::Commands::DependencyCommand < Gem::Command end def arguments # :nodoc: - "GEMNAME name of gem to show dependencies for" end def defaults_str # :nodoc: @@ -50,7 +50,7 @@ use with other commands. end def usage # :nodoc: - "#{program_name} GEMNAME" end def fetch_remote_specs dependency # :nodoc: @@ -28,8 +28,9 @@ The RubyGems environment can be controlled through command line arguments, gemrc files, environment variables and built-in defaults. Command line argument defaults and some RubyGems defaults can be set in a -~/.gemrc file for individual users and a /etc/gemrc for all users. These -files are YAML files with the following YAML keys: :sources: A YAML array of remote gem repositories to install gems from :verbose: Verbosity of the gem command. false, true, and :really are the @@ -120,6 +121,8 @@ lib/rubygems/defaults/operating_system.rb out << " - SPEC CACHE DIRECTORY: #{Gem.spec_cache_dir}\n" out << " - RUBYGEMS PLATFORMS:\n" Gem.platforms.each do |platform| out << " - #{platform}\n" @@ -52,6 +52,183 @@ Some examples of 'gem' usage. gem update --system EOF PLATFORMS = <<-'EOF' RubyGems platforms are composed of three parts, a CPU, an OS, and a version. These values are taken from values in rbconfig.rb. You can view @@ -90,6 +267,16 @@ When building platform gems, set the platform in the gem specification to Gem::Platform::CURRENT. This will correctly mark the gem with your ruby's platform. EOF # :startdoc: def initialize @@ -98,15 +285,6 @@ platform. @command_manager = Gem::CommandManager.instance end - def arguments # :nodoc: - args = <<-EOF - commands List all 'gem' commands - examples Show examples of 'gem' usage - <command> Show specific help for <command> - EOF - return args.gsub(/^\s+/, '') - end - def usage # :nodoc: "#{program_name} ARGUMENT" end @@ -114,19 +292,20 @@ platform. def execute arg = options[:args][0] - if begins? "commands", arg then - show_commands - - elsif begins? "options", arg then - say Gem::Command::HELP - - elsif begins? "examples", arg then - say EXAMPLES - elsif begins? "platforms", arg then - say PLATFORMS - elsif options[:help] then show_help elsif arg then @@ -21,6 +21,8 @@ class Gem::Commands::InstallCommand < Gem::Command def initialize defaults = Gem::DependencyInstaller::DEFAULT_OPTIONS.merge({ :format_executable => false, :version => Gem::Requirement.default, :without_groups => [], }) @@ -69,6 +71,16 @@ class Gem::Commands::InstallCommand < Gem::Command o[:explain] = v end @installed_specs = [] end @@ -78,7 +90,7 @@ class Gem::Commands::InstallCommand < Gem::Command def defaults_str # :nodoc: "--both --version '#{Gem::Requirement.default}' --document --no-force\n" + - "--install-dir #{Gem.dir}" end def description # :nodoc: @@ -92,6 +104,25 @@ The wrapper allows you to choose among alternate gem versions using _version_. For example `rake _0.7.3_ --version` will run rake version 0.7.3 if a newer version is also installed. If an extension fails to compile during gem installation the gem specification is not written out, but the gem remains unpacked in the repository. You may need to specify the path to the library's headers and @@ -204,23 +235,20 @@ to write the specification by hand. For example: install_gem_without_dependencies name, req else inst = Gem::DependencyInstaller.new options if options[:explain] - request_set = inst.resolve_dependencies name, req - puts "Gems to install:" - request_set.specs.map { |s| s.full_name }.sort.each do |s| - puts " #{s}" end return else - inst.install name, req end - @installed_specs.push(*inst.installed_gems) - show_install_errors inst.errors end end @@ -250,6 +278,14 @@ to write the specification by hand. For example: inst = Gem::Installer.new gem, options inst.install @installed_specs.push(inst.spec) end @@ -264,8 +300,10 @@ to write the specification by hand. For example: rescue Gem::InstallError => e alert_error "Error installing #{gem_name}:\n\t#{e.message}" exit_code |= 1 - rescue Gem::GemNotFoundException => e - show_lookup_failure e.name, e.version, e.errors, options[:domain] exit_code |= 2 end @@ -8,13 +8,13 @@ require 'rubygems/commands/query_command' class Gem::Commands::ListCommand < Gem::Commands::QueryCommand def initialize - super 'list', 'Display local gems whose name starts with STRING' remove_option('--name-matches') end def arguments # :nodoc: - "STRING start of gem name to look for" end def defaults_str # :nodoc: @@ -0,0 +1,74 @@ @@ -86,7 +86,9 @@ permission to. request.add_field "Authorization", api_key end - with_response response, "Removing #{owner}" rescue # ignore end @@ -4,7 +4,7 @@ require 'rubygems/commands/query_command' class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand def initialize - super 'search', 'Display remote gems whose name contains STRING' remove_option '--name-matches' @@ -12,7 +12,7 @@ class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand end def arguments # :nodoc: - "STRING fragment of gem name to search for" end def defaults_str # :nodoc: @@ -21,8 +21,8 @@ class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand def description # :nodoc: <<-EOF -The search command displays remote gems whose name contains the given -string. The --details option displays additional details from the gem but will take a little longer to complete as it must download the information @@ -33,7 +33,7 @@ To list local gems use the list command. end def usage # :nodoc: - "#{program_name} [STRING]" end end @@ -446,7 +446,7 @@ abort "#{deprecation_message}" history.force_encoding Encoding::UTF_8 if Object.const_defined? :Encoding - history = history.sub(/^# coding:.*?^=/m, '') text = history.split(HISTORY_HEADER) text.shift # correct an off-by-one generated by split @@ -15,7 +15,7 @@ class Gem::Commands::UninstallCommand < Gem::Command def initialize super 'uninstall', 'Uninstall gems from the local repository', :version => Gem::Requirement.default, :user_install => true, - :check_dev => false add_option('-a', '--[no-]all', 'Uninstall all matching versions' @@ -76,6 +76,18 @@ class Gem::Commands::UninstallCommand < Gem::Command add_version_option add_platform_option end def arguments # :nodoc: @@ -16,6 +16,8 @@ class Gem::Commands::UpdateCommand < Gem::Command attr_reader :installer # :nodoc: def initialize super 'update', 'Update installed gems to the latest version', :document => %w[rdoc ri], @@ -45,7 +47,7 @@ class Gem::Commands::UpdateCommand < Gem::Command end def arguments # :nodoc: - "GEMNAME name of gem to update" end def defaults_str # :nodoc: @@ -56,13 +58,13 @@ class Gem::Commands::UpdateCommand < Gem::Command <<-EOF The update command will update your gems to the latest version. -The update comamnd does not remove the previous version. Use the cleanup command to remove old versions. EOF end def usage # :nodoc: - "#{program_name} GEMNAME [GEMNAME ...]" end def check_latest_rubygems version # :nodoc: @@ -97,10 +99,14 @@ command to remove old versions. updated = update_gems gems_to_update if updated.empty? then say "Nothing to update" else - say "Gems updated: #{updated.map { |spec| spec.name }.join ' '}" end end @@ -199,15 +205,11 @@ command to remove old versions. @installer ||= Gem::DependencyInstaller.new options - success = false - say "Updating #{name}" begin @installer.install name, Gem::Requirement.new(version) - success = true - rescue Gem::InstallError => e alert_error "Error installing #{name}:\n\t#{e.message}" - success = false end @installer.installed_gems.each do |spec| @@ -259,7 +261,7 @@ command to remove old versions. highest_installed_gems.each do |l_name, l_spec| next if not gem_names.empty? and - gem_names.all? { |name| /#{name}/ !~ l_spec.name } highest_remote_ver = highest_remote_version l_spec @@ -272,4 +274,3 @@ command to remove old versions. end end - @@ -44,10 +44,7 @@ as the reason for the removal request. options[:undo] = true end - add_option('-k', '--key KEY_NAME', - 'Use API key from your gem credentials file') do |value, options| - options[:key] = value - end end def execute @@ -55,14 +52,12 @@ as the reason for the removal request. version = get_version_from_requirements(options[:version]) platform = get_platform_from_requirements(options) - api_key = Gem.configuration.rubygems_api_key - api_key = Gem.configuration.api_keys[options[:key].to_sym] if options[:key] if version then if options[:undo] then - unyank_gem(version, platform, api_key) else - yank_gem(version, platform, api_key) end else say "A version argument is required: #{usage}" @@ -70,19 +65,19 @@ as the reason for the removal request. end end - def yank_gem(version, platform, api_key) say "Yanking gem from #{self.host}..." - yank_api_request(:delete, version, platform, "api/v1/gems/yank", api_key) end - def unyank_gem(version, platform, api_key) say "Unyanking gem from #{host}..." - yank_api_request(:put, version, platform, "api/v1/gems/unyank", api_key) end private - def yank_api_request(method, version, platform, api, api_key) name = get_one_gem_name response = rubygems_api_request(method, api) do |request| request.add_field("Authorization", api_key) @@ -57,7 +57,7 @@ class Gem::ConfigFile # :stopdoc: - system_config_path = begin require "etc" Etc.sysconfdir @@ -86,7 +86,7 @@ class Gem::ConfigFile # :startdoc: - SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc' ## # List of arguments supplied to the config file object. @@ -383,6 +383,8 @@ if you believe they were disclosed to a third party. @backtrace = true when /^--debug$/ then $DEBUG = true else @args << arg end @@ -428,6 +430,15 @@ if you believe they were disclosed to a third party. DEFAULT_VERBOSITY end keys = yaml_hash.keys.map { |key| key.to_s } keys << 'debug' re = Regexp.union(*keys) @@ -26,6 +26,11 @@ module Kernel # Kernel#gem should be called *before* any require statements (otherwise # RubyGems may load a conflicting library version). # # In older RubyGems versions, the environment variable GEM_SKIP could be # used to skip activation of specified gems, for example to test out changes # that haven't been installed yet. Now RubyGems defers to -I and the @@ -51,7 +56,9 @@ module Kernel end spec = Gem::Dependency.new(gem_name, *requirements).to_spec - spec.activate if spec end private :gem @@ -50,12 +50,8 @@ module Kernel # normal require handle loading a gem from the rescue below. if Gem::Specification.unresolved_deps.empty? then - begin - RUBYGEMS_ACTIVATION_MONITOR.exit - return gem_original_require(path) - ensure - RUBYGEMS_ACTIVATION_MONITOR.enter - end end # If +path+ is for a gem that has already been loaded, don't @@ -71,8 +67,6 @@ module Kernel begin RUBYGEMS_ACTIVATION_MONITOR.exit return gem_original_require(path) - ensure - RUBYGEMS_ACTIVATION_MONITOR.enter end if spec # Attempt to find +path+ in any unresolved gems... @@ -105,6 +99,7 @@ module Kernel names = found_specs.map(&:name).uniq if names.size > 1 then raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ', '}" end @@ -115,32 +110,27 @@ module Kernel unless valid then le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate" le.name = names.first raise le end valid.activate end - begin - RUBYGEMS_ACTIVATION_MONITOR.exit - return gem_original_require(path) - ensure - RUBYGEMS_ACTIVATION_MONITOR.enter - end rescue LoadError => load_error if load_error.message.start_with?("Could not find") or (load_error.message.end_with?(path) and Gem.try_activate(path)) then - begin - RUBYGEMS_ACTIVATION_MONITOR.exit - return gem_original_require(path) - ensure - RUBYGEMS_ACTIVATION_MONITOR.enter - end end raise load_error - ensure - RUBYGEMS_ACTIVATION_MONITOR.exit end private :require @@ -89,11 +89,11 @@ module Gem # Default gem load path def self.default_path - if Gem.user_home && File.exist?(Gem.user_home) then - [user_dir, default_dir] - else - [default_dir] - end end ## @@ -160,4 +160,18 @@ module Gem true end end @@ -74,7 +74,7 @@ class Gem::Dependency end def inspect # :nodoc: - if @prerelease "<%s type=%p name=%p requirements=%p prerelease=ok>" % [self.class, self.type, self.name, requirement.to_s] else @@ -145,7 +145,6 @@ class Gem::Dependency @requirement = @version_requirements if defined?(@version_requirements) end - # DOC: this method needs documentation or :nodoc''d def requirements_list requirement.as_list end @@ -205,9 +204,19 @@ class Gem::Dependency alias === =~ - # DOC: this method needs either documented or :nodoc'd - def match? obj, version=nil if !version name = obj.name version = obj.version @@ -216,12 +225,23 @@ class Gem::Dependency end return false unless self.name === name - return true if requirement.none? - requirement.satisfied_by? Gem::Version.new(version) end - # DOC: this method needs either documented or :nodoc'd def matches_spec? spec return false unless name === spec.name @@ -249,8 +269,6 @@ class Gem::Dependency self.class.new name, self_req.as_list.concat(other_req.as_list) end - # DOC: this method needs either documented or :nodoc'd - def matching_specs platform_only = false matches = Gem::Specification.stubs.find_all { |spec| self.name === spec.name and # TODO: == instead of === @@ -273,8 +291,6 @@ class Gem::Dependency @requirement.specific? end - # DOC: this method needs either documented or :nodoc'd - def to_specs matches = matching_specs true @@ -287,12 +303,13 @@ class Gem::Dependency if specs.empty? total = Gem::Specification.to_a.size - error = Gem::LoadError.new \ - "Could not find '#{name}' (#{requirement}) among #{total} total gem(s)" else - error = Gem::LoadError.new \ - "Could not find '#{name}' (#{requirement}) - did find: [#{specs.join ','}]" end error.name = self.name error.requirement = self.requirement raise error @@ -303,11 +320,15 @@ class Gem::Dependency matches end - # DOC: this method needs either documented or :nodoc'd - def to_spec matches = self.to_specs - matches.find { |spec| spec.activated? } or matches.last end end @@ -72,6 +72,7 @@ class Gem::DependencyInstaller def initialize options = {} @only_install_dir = !!options[:install_dir] @install_dir = options[:install_dir] || Gem.dir options = DEFAULT_OPTIONS.merge options @@ -102,7 +103,7 @@ class Gem::DependencyInstaller @cache_dir = options[:cache_dir] || @install_dir - @errors = nil end ## @@ -157,6 +158,7 @@ class Gem::DependencyInstaller dependency_list.remove_specs_unsatisfied_by dependencies end ## # Creates an AvailableSet to install from based on +dep_or_name+ and # +version+ @@ -243,9 +245,9 @@ class Gem::DependencyInstaller # FIX if there is a problem talking to the network, we either need to always tell # the user (no really_verbose) or fail hard, not silently tell them that we just # couldn't find their requested gem. - if Gem.configuration.really_verbose then - say "Error fetching remote data:\t\t#{e.message}" - say "Falling back to local-only install" end @domain = :local end @@ -375,13 +377,16 @@ class Gem::DependencyInstaller options = { :bin_dir => @bin_dir, :build_args => @build_args, :env_shebang => @env_shebang, :force => @force, :format_executable => @format_executable, :ignore_dependencies => @ignore_dependencies, :security_policy => @security_policy, :user_install => @user_install, :wrappers => @wrappers, :install_as_default => @install_as_default } options[:install_dir] = @install_dir if @only_install_dir @@ -415,25 +420,59 @@ class Gem::DependencyInstaller end def resolve_dependencies dep_or_name, version # :nodoc: - as = available_set_for dep_or_name, version - - request_set = as.to_request_set install_development_deps request_set.soft_missing = @force request_set.remote = false unless consider_remote? installer_set = Gem::Resolver::InstallerSet.new @domain - installer_set.always_install.concat request_set.always_install installer_set.ignore_installed = @only_install_dir if @ignore_dependencies then installer_set.ignore_dependencies = true request_set.ignore_dependencies = true request_set.soft_missing = true end - composed_set = Gem::Resolver.compose_sets as, installer_set - request_set.resolve composed_set request_set end @@ -105,7 +105,7 @@ class Gem::Doctor next if ent == "." || ent == ".." child = File.join(directory, ent) - next unless File.exists?(child) basename = File.basename(child, extension) next if installed_specs.include? basename @@ -19,6 +19,36 @@ module Gem attr_accessor :requirement end class ErrorReason; end # Generated when trying to lookup a gem to indicate that the gem @@ -27,7 +27,7 @@ class Gem::DependencyRemovalException < Gem::Exception; end # toplevel. Indicates which dependencies were incompatible through #conflict # and #conflicting_dependencies -class Gem::DependencyResolutionError < Gem::Exception attr_reader :conflict @@ -214,7 +214,7 @@ end # Raised by Resolver when a dependency requests a gem for which # there is no spec. -class Gem::UnsatisfiableDependencyError < Gem::Exception ## # The unsatisfiable dependency. This is a @@ -223,6 +223,11 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception attr_reader :dependency ## # Creates a new UnsatisfiableDependencyError for the unsatisfiable # Gem::Resolver::DependencyRequest +dep+ @@ -239,6 +244,21 @@ class Gem::UnsatisfiableDependencyError < Gem::Exception end @dependency = dep end end @@ -161,7 +161,7 @@ EOF results = builder.build(extension, @gem_dir, dest_path, results, @build_args, lib_dir) - say results.join("\n") if Gem.configuration.really_verbose end end @@ -11,13 +11,15 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder FileEntry = FileUtils::Entry_ # :nodoc: def self.build(extension, directory, dest_path, results, args=[], lib_dir=nil) - tmp_dest = Dir.mktmpdir(".gem.", ".") t = nil Tempfile.open %w"siteconf .rb", "." do |siteconf| t = siteconf siteconf.puts "require 'rbconfig'" - siteconf.puts "dest_path = #{(tmp_dest || dest_path).dump}" %w[sitearchdir sitelibdir].each do |dir| siteconf.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path" siteconf.puts "RbConfig::CONFIG['#{dir}'] = dest_path" @@ -25,14 +27,10 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder siteconf.flush - siteconf_path = File.expand_path siteconf.path - - rubyopt = ENV["RUBYOPT"] destdir = ENV["DESTDIR"] begin - ENV["RUBYOPT"] = ["-r#{siteconf_path}", rubyopt].compact.join(' ') - cmd = [Gem.ruby, File.basename(extension), *args].join ' ' begin run cmd, results @@ -42,7 +40,6 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder end ENV["DESTDIR"] = nil - ENV["RUBYOPT"] = rubyopt make dest_path, results @@ -57,11 +54,10 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder FileEntry.new(tmp_dest).traverse do |ent| destent = ent.class.new(dest_path, ent.rel) - destent.exist? or File.rename(ent.path, destent.path) end end ensure - ENV["RUBYOPT"] = rubyopt ENV["DESTDIR"] = destdir end end @@ -72,5 +68,11 @@ class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder FileUtils.rm_rf tmp_dest if tmp_dest end end @@ -86,7 +86,7 @@ module Gem::GemcutterUtilities def sign_in sign_in_host = nil sign_in_host ||= self.host - return if Gem.configuration.rubygems_api_key pretty_host = if Gem::DEFAULT_HOST == sign_in_host then 'RubyGems.org' @@ -59,6 +59,23 @@ module Gem::InstallUpdateOptions end end add_option(:"Install/Update", '-N', '--no-document', 'Disable documentation generation') do |value, options| options[:document] = [] @@ -39,7 +39,9 @@ class Gem::Installer include Gem::UserInteraction - # DOC: Missing docs or :nodoc:. attr_reader :gem ## @@ -47,6 +49,8 @@ class Gem::Installer attr_reader :bin_dir ## # The gem repository the gem will be installed into @@ -64,6 +68,8 @@ class Gem::Installer @path_warning = false class << self ## @@ -71,7 +77,19 @@ class Gem::Installer attr_accessor :path_warning - # DOC: Missing docs or :nodoc:. attr_writer :exec_format # Defaults to use Ruby's program prefix and suffix. @@ -240,7 +258,7 @@ class Gem::Installer say spec.post_install_message unless spec.post_install_message.nil? - Gem::Specification.add_spec spec unless Gem::Specification.include? spec run_post_install_hooks @@ -318,6 +336,7 @@ class Gem::Installer # True if the gems in the system satisfy +dependency+. def installation_satisfies_dependency?(dependency) return true if installed_specs.detect { |s| dependency.matches_spec? s } return false if @only_install_dir not dependency.matching_specs.empty? @@ -382,12 +401,11 @@ class Gem::Installer file.puts windows_stub_script(bindir, filename) end - say script_path if Gem.configuration.really_verbose end end - # DOC: Missing docs or :nodoc:. - def generate_bin return if spec.executables.nil? or spec.executables.empty? Dir.mkdir @bin_dir unless File.exist? @bin_dir @@ -433,7 +451,7 @@ class Gem::Installer file.print app_script_text(filename) end - say bin_script_path if Gem.configuration.really_verbose generate_windows_script filename, bindir end @@ -536,8 +554,7 @@ class Gem::Installer end end - # DOC: Missing docs or :nodoc:. - def ensure_required_ruby_version_met if rrv = spec.required_ruby_version then unless rrv.satisfied_by? Gem.ruby_version then raise Gem::InstallError, "#{spec.name} requires Ruby version #{rrv}." @@ -545,8 +562,7 @@ class Gem::Installer end end - # DOC: Missing docs or :nodoc:. - def ensure_required_rubygems_version_met if rrgv = spec.required_rubygems_version then unless rrgv.satisfied_by? Gem.rubygems_version then raise Gem::InstallError, @@ -556,8 +572,7 @@ class Gem::Installer end end - # DOC: Missing docs or :nodoc:. - def ensure_dependencies_met deps = spec.runtime_dependencies deps |= spec.development_dependencies if @development @@ -566,8 +581,7 @@ class Gem::Installer end end - # DOC: Missing docs or :nodoc:. - def process_options @options = { :bin_dir => nil, :env_shebang => false, @@ -590,12 +604,20 @@ class Gem::Installer # (or use) a new bin dir under the gem_home. @bin_dir = options[:bin_dir] || Gem.bindir(gem_home) @development = options[:development] @build_args = options[:build_args] || Gem::Command.build_args end - # DOC: Missing docs or :nodoc:. - def check_that_user_bin_dir_is_in_path user_bin_dir = @bin_dir || Gem.bindir(gem_home) user_bin_dir = user_bin_dir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR @@ -606,16 +628,19 @@ class Gem::Installer user_bin_dir = user_bin_dir.downcase end - unless path.split(File::PATH_SEPARATOR).include? user_bin_dir then - unless self.class.path_warning then - alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run." - self.class.path_warning = true end end end - # DOC: Missing docs or :nodoc:. - def verify_gem_home(unpack = false) FileUtils.mkdir_p gem_home raise Gem::FilePermissionError, gem_home unless unpack or File.writable?(gem_home) @@ -660,10 +685,10 @@ TEXT return <<-TEXT @ECHO OFF IF NOT "%~f0" == "~f0" GOTO :WinNT -@"#{ruby}" "#{File.join(bindir, bin_file_name)}" %1 %2 %3 %4 %5 %6 %7 %8 %9 GOTO :EOF :WinNT -@"#{ruby}" "%~dpn0" %* TEXT end @@ -101,6 +101,8 @@ class Gem::InstallerTestCase < Gem::TestCase @installer = util_installer @spec, @gemhome @user_installer = util_installer @user_spec, Gem.user_dir, :user end def util_gem_bindir spec = @spec # :nodoc: @@ -100,8 +100,8 @@ module Gem::LocalRemoteOptions def add_source_option accept_uri_http - add_option(:"Local/Remote", '--source URL', URI::HTTP, - 'Add URL as a remote source for gems') do |source, options| source << '/' if source !~ /\/\z/ @@ -53,7 +53,7 @@ class Gem::NameTuple "#{@name}-#{@version}" else "#{@name}-#{@version}-#{@platform}" - end end ## @@ -90,7 +90,9 @@ class Gem::NameTuple alias to_s inspect # :nodoc: def <=> other - to_a <=> other.to_a end include Comparable @@ -54,10 +54,12 @@ class Gem::Package class FormatError < Error attr_reader :path - def initialize message, path = nil - @path = path - message << " in #{path}" if path super message end @@ -80,6 +82,7 @@ class Gem::Package class TarInvalidError < Error; end attr_accessor :build_time # :nodoc: ## @@ -114,19 +117,26 @@ class Gem::Package end ## - # Creates a new Gem::Package for the file at +gem+. # # If +gem+ is an existing file in the old format a Gem::Package::Old will be # returned. def self.new gem - return super unless Gem::Package == self - return super unless File.exist? gem - start = File.read gem, 20 - return super unless start - return super unless start.include? 'MD5SUM =' Gem::Package::Old.new gem end @@ -227,7 +237,7 @@ class Gem::Package setup_signer - open @gem, 'wb' do |gem_io| Gem::Package::TarWriter.new gem_io do |gem| add_metadata gem add_contents gem @@ -255,7 +265,7 @@ EOM @contents = [] - open @gem, 'rb' do |io| gem_tar = Gem::Package::TarReader.new io gem_tar.each do |entry| @@ -312,7 +322,7 @@ EOM FileUtils.mkdir_p destination_dir - open @gem, 'rb' do |io| reader = Gem::Package::TarReader.new io reader.each do |entry| @@ -360,7 +370,7 @@ EOM out.write entry.read end if entry.file? - say destination if Gem.configuration.really_verbose end end end @@ -490,7 +500,7 @@ EOM @files = [] @spec = nil - open @gem, 'rb' do |io| Gem::Package::TarReader.new io do |reader| read_checksums reader @@ -592,6 +602,9 @@ EOM end require 'rubygems/package/digest_io' require 'rubygems/package/old' require 'rubygems/package/tar_header' require 'rubygems/package/tar_reader' @@ -0,0 +1,33 @@ @@ -0,0 +1,45 @@ @@ -37,7 +37,7 @@ class Gem::Package::Old < Gem::Package return @contents if @contents - open @gem, 'rb' do |io| read_until_dashes io # spec header = file_list io @@ -53,7 +53,7 @@ class Gem::Package::Old < Gem::Package errstr = "Error reading files from gem" - open @gem, 'rb' do |io| read_until_dashes io # spec header = file_list io raise Gem::Exception, errstr unless header @@ -83,7 +83,7 @@ class Gem::Package::Old < Gem::Package out.write file_data end - say destination if Gem.configuration.really_verbose end end rescue Zlib::DataError @@ -136,7 +136,7 @@ class Gem::Package::Old < Gem::Package yaml = '' - open @gem, 'rb' do |io| skip_ruby io read_until_dashes io do |line| yaml << line @@ -0,0 +1,3 @@ @@ -129,6 +129,8 @@ class Gem::Package::TarReader::Entry ret end ## # Rewinds to the beginning of the tar file entry @@ -17,7 +17,7 @@ class Gem::Platform def self.local arch = RbConfig::CONFIG['arch'] - arch = "#{arch}_60" if arch =~ /mswin32$/ @local ||= new(arch) end @@ -173,6 +173,7 @@ class Gem::Platform when /^dalvik(\d+)?$/ then [nil, 'dalvik', $1 ] when /dotnet(\-(\d+\.\d+))?/ then ['universal','dotnet', $2 ] when /mswin32(\_(\d+))?/ then ['x86', 'mswin32', $2 ] when 'powerpc-darwin' then ['powerpc', 'darwin', nil ] when /powerpc-darwin(\d)/ then ['powerpc', 'darwin', $1 ] when /sparc-solaris2.8/ then ['sparc', 'solaris', '2.8' ] @@ -263,7 +263,7 @@ class Gem::RDoc # :nodoc: all Gem::Requirement.new('>= 2.4.0') =~ self.class.rdoc_version r = new_rdoc - say "rdoc #{args.join ' '}" if Gem.configuration.really_verbose Dir.chdir @spec.full_gem_path do begin @@ -279,7 +279,6 @@ class Gem::RDoc # :nodoc: all ui.errs.puts "... RDOC args: #{args.join(' ')}" ui.backtrace ex ui.errs.puts "(continuing with the rest of the installation)" - ensure end end end @@ -2,6 +2,7 @@ require 'rubygems' require 'rubygems/request' require 'rubygems/uri_formatter' require 'rubygems/user_interaction' require 'resolv' ## @@ -73,6 +74,9 @@ class Gem::RemoteFetcher Socket.do_not_reverse_lookup = true @proxy = proxy @dns = dns end @@ -154,11 +158,10 @@ class Gem::RemoteFetcher # REFACTOR: split this up and dis on scheme (eg download_http) # REFACTOR: be sure to clean up fake fetcher when you do this... cleaner case scheme - when 'http', 'https' then unless File.exist? local_gem_path then begin - say "Downloading gem #{gem_file_name}" if - Gem.configuration.really_verbose remote_gem_path = source_uri + "gems/#{gem_file_name}" @@ -168,8 +171,7 @@ class Gem::RemoteFetcher alternate_name = "#{spec.original_name}.gem" - say "Failed, downloading gem #{alternate_name}" if - Gem.configuration.really_verbose remote_gem_path = source_uri + "gems/#{alternate_name}" @@ -188,8 +190,7 @@ class Gem::RemoteFetcher local_gem_path = source_uri.to_s end - say "Using local gem #{local_gem_path}" if - Gem.configuration.really_verbose when nil then # TODO test for local overriding cache source_path = if Gem.win_platform? && source_uri.scheme && !source_uri.path.include?(':') then @@ -207,8 +208,7 @@ class Gem::RemoteFetcher local_gem_path = source_uri.to_s end - say "Using local gem #{local_gem_path}" if - Gem.configuration.really_verbose else raise ArgumentError, "unsupported URI scheme #{source_uri.scheme}" end @@ -232,6 +232,7 @@ class Gem::RemoteFetcher case response when Net::HTTPOK, Net::HTTPNotModified then head ? response : response.body when Net::HTTPMovedPermanently, Net::HTTPFound, Net::HTTPSeeOther, Net::HTTPTemporaryRedirect then @@ -265,7 +266,7 @@ class Gem::RemoteFetcher data = send "fetch_#{uri.scheme}", uri, mtime, head - if data and !head and uri.to_s =~ /gz$/ begin data = Gem.gunzip data rescue Zlib::GzipFile::Error @@ -286,6 +287,11 @@ class Gem::RemoteFetcher end end ## # Downloads +uri+ to +path+ if necessary. If no path is given, it just # passes the data. @@ -332,18 +338,57 @@ class Gem::RemoteFetcher # connections to reduce connect overhead. def request(uri, request_class, last_modified = nil) - request = Gem::Request.new uri, request_class, last_modified, @proxy request.fetch do |req| yield req if block_given? end - ensure - request.close if request end def https?(uri) uri.scheme.downcase == 'https' end end @@ -7,41 +7,43 @@ class Gem::Request include Gem::UserInteraction - attr_reader :proxy_uri - def initialize(uri, request_class, last_modified, proxy) @uri = uri @request_class = request_class @last_modified = last_modified @requests = Hash.new 0 - @connections = {} - @connections_mutex = Mutex.new @user_agent = user_agent - @proxy_uri = - case proxy - when :no_proxy then nil - when nil then get_proxy_from_env uri.scheme - when URI::HTTP then proxy - else URI.parse(proxy) - end - @env_no_proxy = get_no_proxy_from_env end - def close - @connections.each_value do |conn| - conn.finish - end - end - def add_rubygems_trusted_certs(store) pattern = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__)) - Dir.glob(pattern).each do |ssl_cert_file| - store.add_file ssl_cert_file - end end - def configure_connection_for_https(connection) require 'net/https' connection.use_ssl = true connection.verify_mode = @@ -55,7 +57,9 @@ class Gem::Request end store.set_default_paths - add_rubygems_trusted_certs(store) if Gem.configuration.ssl_ca_cert if File.directory? Gem.configuration.ssl_ca_cert store.add_path Gem.configuration.ssl_ca_cert @@ -64,6 +68,7 @@ class Gem::Request end end connection.cert_store = store rescue LoadError => e raise unless (e.respond_to?(:path) && e.path == 'openssl') || e.message =~ / -- openssl$/ @@ -77,31 +82,7 @@ class Gem::Request # connection, using a proxy if needed. def connection_for(uri) - net_http_args = [uri.host, uri.port] - - if @proxy_uri and not no_proxy?(uri.host) then - net_http_args += [ - @proxy_uri.host, - @proxy_uri.port, - Gem::UriFormatter.new(@proxy_uri.user).unescape, - Gem::UriFormatter.new(@proxy_uri.password).unescape, - ] - end - - connection_id = [Thread.current.object_id, *net_http_args].join ':' - - connection = @connections_mutex.synchronize do - @connections[connection_id] ||= Net::HTTP.new(*net_http_args) - @connections[connection_id] - end - - if https?(uri) and not connection.started? then - configure_connection_for_https(connection) - end - - connection.start unless connection.started? - - connection rescue defined?(OpenSSL::SSL) ? OpenSSL::SSL::SSLError : Errno::EHOSTDOWN, Errno::EHOSTDOWN => e raise Gem::RemoteFetcher::FetchError.new(e.message, uri) @@ -125,6 +106,37 @@ class Gem::Request yield request if block_given? connection = connection_for @uri retried = false @@ -133,8 +145,7 @@ class Gem::Request begin @requests[connection.object_id] += 1 - say "#{request.method} #{@uri}" if - Gem.configuration.really_verbose file_name = File.basename(@uri.path) # perform download progress reporter only for gems @@ -163,11 +174,10 @@ class Gem::Request response = connection.request request end - say "#{response.code} #{response.message}" if - Gem.configuration.really_verbose rescue Net::HTTPBadResponse - say "bad response" if Gem.configuration.really_verbose reset connection @@ -182,8 +192,7 @@ class Gem::Request Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE requests = @requests[connection.object_id] - say "connection reset after #{requests} requests, retrying" if - Gem.configuration.really_verbose raise Gem::RemoteFetcher::FetchError.new('too many connection resets', @uri) if retried @@ -194,57 +203,8 @@ class Gem::Request end response - end - - ## - # Returns list of no_proxy entries (if any) from the environment - - def get_no_proxy_from_env - env_no_proxy = ENV['no_proxy'] || ENV['NO_PROXY'] - - return [] if env_no_proxy.nil? or env_no_proxy.empty? - - env_no_proxy.split(/\s*,\s*/) - end - - ## - # Returns a proxy URI for the given +scheme+ if one is set in the - # environment variables. - - def get_proxy_from_env scheme = 'http' - _scheme = scheme.downcase - _SCHEME = scheme.upcase - env_proxy = ENV["#{_scheme}_proxy"] || ENV["#{_SCHEME}_PROXY"] - - no_env_proxy = env_proxy.nil? || env_proxy.empty? - - return get_proxy_from_env 'http' if no_env_proxy and _scheme != 'http' - return nil if no_env_proxy - - uri = URI(Gem::UriFormatter.new(env_proxy).normalize) - - if uri and uri.user.nil? and uri.password.nil? then - user = ENV["#{_scheme}_proxy_user"] || ENV["#{_SCHEME}_PROXY_USER"] - password = ENV["#{_scheme}_proxy_pass"] || ENV["#{_SCHEME}_PROXY_PASS"] - - uri.user = Gem::UriFormatter.new(user).escape - uri.password = Gem::UriFormatter.new(password).escape - end - - uri - end - - def https?(uri) - uri.scheme.downcase == 'https' - end - - def no_proxy? host - host = host.downcase - @env_no_proxy.each do |pattern| - pattern = pattern.downcase - return true if host[-pattern.length, pattern.length ] == pattern - end - return false end ## @@ -278,3 +238,7 @@ class Gem::Request end @@ -0,0 +1,79 @@ @@ -0,0 +1,38 @@ @@ -0,0 +1,10 @@ @@ -1,4 +1,3 @@ -require 'rubygems' require 'tsort' ## @@ -21,13 +20,23 @@ class Gem::RequestSet ## # Array of gems to install even if already installed - attr_reader :always_install attr_reader :dependencies attr_accessor :development ## # The set of git gems imported via load_gemdeps. attr_reader :git_set # :nodoc: @@ -38,11 +47,20 @@ class Gem::RequestSet attr_accessor :ignore_dependencies ## # When false no remote sets are used for resolving gems. attr_accessor :remote ## # Sets used for resolution @@ -71,11 +89,15 @@ class Gem::RequestSet @dependencies = deps @always_install = [] @dependency_names = {} @development = false @git_set = nil @ignore_dependencies = false @install_dir = Gem.dir @remote = true @requests = [] @sets = [] @@ -116,12 +138,14 @@ class Gem::RequestSet def install options, &block # :yields: request, installer if dir = options[:install_dir] - return install_into dir, false, options, &block end cache_dir = options[:cache_dir] || Gem.dir - specs = [] sorted_requests.each do |req| if req.installed? then @@ -139,10 +163,30 @@ class Gem::RequestSet yield req, inst if block_given? - specs << inst.install end - specs end ## @@ -156,17 +200,19 @@ class Gem::RequestSet gemdeps = options[:gemdeps] @install_dir = options[:install_dir] || Gem.dir @remote = options[:domain] != :local - load_gemdeps gemdeps, options[:without_groups] resolve if options[:explain] puts "Gems to install:" - specs.map { |s| s.full_name }.sort.each do |s| - puts " #{s}" end if Gem.configuration.really_verbose @@ -175,8 +221,11 @@ class Gem::RequestSet else installed = install options, &block - lockfile = Gem::RequestSet::Lockfile.new self, gemdeps - lockfile.write installed end @@ -192,8 +241,10 @@ class Gem::RequestSet installed = [] options[:install_dir] = dir options[:only_install_dir] = true sorted_requests.each do |request| spec = request.spec @@ -218,7 +269,7 @@ class Gem::RequestSet ## # Load a dependency management file. - def load_gemdeps path, without_groups = [] @git_set = Gem::Resolver::GitSet.new @vendor_set = Gem::Resolver::VendorSet.new @@ -228,6 +279,7 @@ class Gem::RequestSet lockfile.parse gf = Gem::RequestSet::GemDependencyAPI.new self, path gf.without_groups = without_groups if without_groups gf.load end @@ -243,15 +295,29 @@ class Gem::RequestSet set = Gem::Resolver.compose_sets(*@sets) set.remote = @remote resolver = Gem::Resolver.new @dependencies, set resolver.development = @development resolver.ignore_dependencies = @ignore_dependencies resolver.soft_missing = @soft_missing @resolver = resolver @requests = resolver.resolve end ## @@ -284,16 +350,20 @@ class Gem::RequestSet node.spec.dependencies.each do |dep| next if dep.type == :development and not @development - match = @requests.find { |r| dep.match? r.spec.name, r.spec.version } - if match - begin - yield match - rescue TSort::Cyclic - end - else - unless @soft_missing - raise Gem::DependencyError, "Unresolved dependency found during sorting - #{dep} (requested by #{node.spec.full_name})" - end end end end @@ -1,5 +1,33 @@ ## -# A semi-compatible DSL for the Bundler Gemfile and Isolate formats. class Gem::RequestSet::GemDependencyAPI @@ -21,6 +49,8 @@ class Gem::RequestSet::GemDependencyAPI :ruby_21 => %w[ruby rbx maglev], } x86_mingw = Gem::Platform.new 'x86-mingw32' x64_mingw = Gem::Platform.new 'x64-mingw32' @@ -39,7 +69,15 @@ class Gem::RequestSet::GemDependencyAPI :mri_19 => Gem::Platform::RUBY, :mri_20 => Gem::Platform::RUBY, :mri_21 => Gem::Platform::RUBY, - :mswin => Gem::Platform::RUBY, :rbx => Gem::Platform::RUBY, :ruby => Gem::Platform::RUBY, :ruby_18 => Gem::Platform::RUBY, @@ -73,6 +111,14 @@ class Gem::RequestSet::GemDependencyAPI :mri_20 => tilde_gt_2_0_0, :mri_21 => tilde_gt_2_1_0, :mswin => gt_eq_0, :rbx => gt_eq_0, :ruby => gt_eq_0, :ruby_18 => tilde_gt_1_8_0, @@ -96,6 +142,14 @@ class Gem::RequestSet::GemDependencyAPI :mri_20 => :never, :mri_21 => :never, :mswin => :only, :rbx => :never, :ruby => :never, :ruby_18 => :never, @@ -108,6 +162,11 @@ class Gem::RequestSet::GemDependencyAPI } ## # A set of gems that are loaded via the +:git+ option to #gem attr_reader :git_set # :nodoc: @@ -136,14 +195,31 @@ class Gem::RequestSet::GemDependencyAPI @path = path @current_groups = nil - @current_platform = nil @current_repository = nil @default_sources = true @git_set = @set.git_set @requires = Hash.new { |h, name| h[name] = [] } @vendor_set = @set.vendor_set @gem_sources = {} @without_groups = [] end ## @@ -187,14 +263,26 @@ class Gem::RequestSet::GemDependencyAPI end ## - # Loads the gem dependency file def load instance_eval File.read(@path).untaint, @path, 1 end ## # :category: Gem Dependencies DSL # :call-seq: # gem(name) # gem(name, *requirements) @@ -202,6 +290,66 @@ class Gem::RequestSet::GemDependencyAPI # # Specifies a gem dependency with the given +name+ and +requirements+. You # may also supply +options+ following the +requirements+ def gem name, *requirements options = requirements.pop if requirements.last.kind_of?(Hash) @@ -211,9 +359,20 @@ class Gem::RequestSet::GemDependencyAPI source_set = false - source_set ||= gem_path name, options - source_set ||= gem_git name, options - source_set ||= gem_ name, options return unless gem_platforms options @@ -225,6 +384,12 @@ class Gem::RequestSet::GemDependencyAPI gem_requires name, options @set.gem name, *requirements end @@ -258,21 +423,27 @@ class Gem::RequestSet::GemDependencyAPI private :gem_git ## - # Handles the : option from +options+ for gem +name+. # - # Returns +true+ if the path option was handled. - def gem_ name, options # :nodoc: - return unless path = options.delete(:) - options[:git] = "git://.com/#{path}.git" gem_git name, options true end - private :gem_ ## # Handles the :group and :groups +options+ for the gem with the given @@ -314,8 +485,9 @@ class Gem::RequestSet::GemDependencyAPI # platform matches the current platform. def gem_platforms options # :nodoc: - platform_names = Array(options.delete :platforms) - platform_names << @current_platform if @current_platform return true if platform_names.empty? @@ -343,7 +515,7 @@ class Gem::RequestSet::GemDependencyAPI private :gem_platforms ## - # Handles the require: option from +options+ and adds those files, or the # default file to the require list for +name+. def gem_requires name, options # :nodoc: @@ -362,6 +534,11 @@ class Gem::RequestSet::GemDependencyAPI # :category: Gem Dependencies DSL # # Block form for specifying gems from a git +repository+. def git repository @current_repository = repository @@ -373,6 +550,15 @@ class Gem::RequestSet::GemDependencyAPI end ## # Returns the basename of the file the dependencies were loaded from def gem_deps_file # :nodoc: @@ -383,6 +569,23 @@ class Gem::RequestSet::GemDependencyAPI # :category: Gem Dependencies DSL # # Loads dependencies from a gemspec file. def gemspec options = {} name = options.delete(:name) || '{,*}' @@ -404,7 +607,20 @@ class Gem::RequestSet::GemDependencyAPI ## # :category: Gem Dependencies DSL # Block form for placing a dependency in the given +groups+. def group *groups @current_groups = groups @@ -440,28 +656,72 @@ class Gem::RequestSet::GemDependencyAPI ## # :category: Gem Dependencies DSL # - # Block form for restricting gems to a particular platform. - def platform what - @current_platform = what yield ensure - @current_platform = nil end ## # :category: Gem Dependencies DSL # - # Block form for restricting gems to a particular platform. alias :platforms :platform ## # :category: Gem Dependencies DSL - # Restricts this gem dependencies file to the given ruby +version+. The - # +:engine+ options from Bundler are currently ignored. def ruby version, options = {} engine = options[:engine] @@ -471,6 +731,8 @@ class Gem::RequestSet::GemDependencyAPI 'you must specify engine_version along with the ruby engine' if engine and not engine_version unless RUBY_VERSION == version then message = "Your Ruby version is #{RUBY_VERSION}, " + "but your #{gem_deps_file} requires #{version}" @@ -503,7 +765,16 @@ class Gem::RequestSet::GemDependencyAPI ## # :category: Gem Dependencies DSL # - # Sets +url+ as a source for gems for this dependency API. def source url Gem.sources.clear if @default_sources @@ -49,11 +49,14 @@ class Gem::RequestSet::Lockfile # Creates a new Lockfile for the given +request_set+ and +gem_deps_file+ # location. - def initialize request_set, gem_deps_file @set = request_set @gem_deps_file = File.expand_path(gem_deps_file) @gem_deps_dir = File.dirname(@gem_deps_file) @current_token = nil @line = 0 @line_pos = 0 @@ -64,19 +67,42 @@ class Gem::RequestSet::Lockfile def add_DEPENDENCIES out # :nodoc: out << "DEPENDENCIES" - @requests.sort_by { |r| r.name }.each do |request| - spec = request.spec - - if [Gem::Resolver::VendorSpecification, - Gem::Resolver::GitSpecification].include? spec.class then - out << " #{request.name}!" else - requirement = request.request.dependency.requirement - - out << " #{request.name}#{requirement.for_lockfile}" end end out << nil end @@ -93,12 +119,15 @@ class Gem::RequestSet::Lockfile out << " specs:" requests.sort_by { |request| request.name }.each do |request| platform = "-#{request.spec.platform}" unless Gem::Platform::RUBY == request.spec.platform out << " #{request.name} (#{request.version}#{platform})" request.full_spec.dependencies.sort.each do |dependency| requirement = dependency.requirement out << " #{dependency.name}#{requirement.for_lockfile}" end @@ -166,9 +195,8 @@ class Gem::RequestSet::Lockfile out << "PLATFORMS" platforms = @requests.map { |request| request.spec.platform }.uniq - platforms.delete Gem::Platform::RUBY if platforms.length > 1 - platforms.each do |platform| out << " #{platform}" end @@ -250,7 +278,7 @@ class Gem::RequestSet::Lockfile Gem::Resolver::VendorSet === set }.map { |set| set.specs[name] - }.first requirements << spec.version when :l_paren then @@ -277,26 +305,33 @@ class Gem::RequestSet::Lockfile end def parse_GEM # :nodoc: - get :entry, 'remote' - _, data, = get :text - source = Gem::Source.new data - skip :newline get :entry, 'specs' skip :newline - set = Gem::Resolver::LockSet.new source - last_spec = nil while not @tokens.empty? and :text == peek.first do _, name, column, = get :text case peek[0] when :newline then - last_spec.add_dependency Gem::Dependency.new name if column == 6 when :l_paren then get :l_paren @@ -308,11 +343,13 @@ class Gem::RequestSet::Lockfile platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY - last_spec = set.add name, version, platform else dependency = parse_dependency name, data - last_spec.add_dependency dependency end get :r_paren @@ -337,11 +374,21 @@ class Gem::RequestSet::Lockfile skip :newline get :entry, 'specs' skip :newline set = Gem::Resolver::GitSet.new last_spec = nil while not @tokens.empty? and :text == peek.first do @@ -360,7 +407,7 @@ class Gem::RequestSet::Lockfile else dependency = parse_dependency name, data - last_spec.spec.dependencies << dependency end get :r_paren @@ -403,7 +450,7 @@ class Gem::RequestSet::Lockfile else dependency = parse_dependency name, data - last_spec.spec.dependencies << dependency end get :r_paren @@ -432,7 +479,7 @@ class Gem::RequestSet::Lockfile # the first token of the requirements and returns a Gem::Dependency object. def parse_dependency name, op # :nodoc: - return Gem::Dependency.new name unless peek[0] == :text _, version, = get :text @@ -575,8 +622,10 @@ class Gem::RequestSet::Lockfile # Writes the lock file alongside the gem dependencies file def write open "#{@gem_deps_file}.lock", 'w' do |io| - io.write to_s end end @@ -8,6 +8,9 @@ Gem.load_yaml if defined? ::YAML ## # A Requirement is a set of one or more version restrictions. It supports a # few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators. class Gem::Requirement OPS = { #:nodoc: @@ -1,4 +1,3 @@ -require 'rubygems' require 'rubygems/dependency' require 'rubygems/exceptions' require 'rubygems/util/list' @@ -21,17 +20,24 @@ class Gem::Resolver DEBUG_RESOLVER = !ENV['DEBUG_RESOLVER'].nil? ## # Contains all the conflicts encountered while doing resolution attr_reader :conflicts ## - # Set to true if development dependencies should be considered. attr_accessor :development ## # When true, no dependencies are looked up for requested gems. attr_accessor :ignore_dependencies @@ -44,6 +50,12 @@ class Gem::Resolver attr_reader :stats ## # When a missing dependency, don't stop. Just go on and record what was # missing. @@ -100,26 +112,27 @@ class Gem::Resolver @conflicts = [] @development = false @ignore_dependencies = false @missing = [] @soft_missing = false @stats = Gem::Resolver::Stats.new end def explain stage, *data # :nodoc: - if DEBUG_RESOLVER - d = data.map { |x| x.inspect }.join(", ") - STDOUT.printf "%20s %s\n", stage.to_s.upcase, d - end end - def explain_list stage, data # :nodoc: - if DEBUG_RESOLVER - STDOUT.printf "%20s (%d entries)\n", stage.to_s.upcase, data.size - data.each do |d| - STDOUT.printf "%20s %s\n", "", d - end - end end ## @@ -132,6 +145,7 @@ class Gem::Resolver spec = possible.pop explain :activate, [spec.full_name, possible.size] activation_request = Gem::Resolver::ActivationRequest.new spec, dep, possible @@ -142,8 +156,15 @@ class Gem::Resolver def requests s, act, reqs=nil # :nodoc: return reqs if @ignore_dependencies s.dependencies.reverse_each do |d| next if d.type == :development and not @development reqs.add Gem::Resolver::DependencyRequest.new(d, act) @stats.requirement! end @@ -186,6 +207,15 @@ class Gem::Resolver def find_possible dependency # :nodoc: all = @set.find_all dependency matching_platform = select_local_platforms all return matching_platform, all @@ -270,8 +300,8 @@ class Gem::Resolver dep = needed.remove explain :try, [dep, dep.requester ? dep.requester.request : :toplevel] - explain_list :next5, needed.next5 - explain_list :specs, Array(specs).map { |x| x.full_name }.sort # If there is already a spec activated for the requested name... if specs && existing = specs.find { |s| dep.name == s.name } @@ -403,7 +433,10 @@ class Gem::Resolver @missing << dep unless @soft_missing - raise Gem::UnsatisfiableDependencyError.new(dep, platform_mismatch) end end @@ -39,6 +39,13 @@ class Gem::Resolver::ActivationRequest end ## # Downloads a gem at +path+ and returns the file path. def download path @@ -34,6 +34,8 @@ class Gem::Resolver::APISet < Gem::Resolver::Set @data = Hash.new { |h,k| h[k] = [] } @source = Gem::Source.new @uri end ## @@ -45,6 +47,10 @@ class Gem::Resolver::APISet < Gem::Resolver::Set return res unless @remote versions(req.name).each do |ver| if req.dependency.match? req.name, ver[:number] res << Gem::Resolver::APISpecification.new(self, ver) @@ -61,9 +67,13 @@ class Gem::Resolver::APISet < Gem::Resolver::Set def prefetch reqs return unless @remote names = reqs.map { |r| r.dependency.name } - needed = names - @data.keys - return if needed.empty? uri = @dep_uri + "?gems=#{needed.sort.join ','}" str = Gem::RemoteFetcher.fetcher.fetch_path uri @@ -34,6 +34,12 @@ class Gem::Resolver::APISpecification < Gem::Resolver::Specification @dependencies == other.dependencies end def installable_platform? # :nodoc: Gem::Platform.match @platform end @@ -28,6 +28,10 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet pick_sets if @remote and @sets.empty? super end def prefetch reqs # :nodoc: @@ -46,5 +50,29 @@ class Gem::Resolver::BestSet < Gem::Resolver::ComposedSet end end end @@ -22,6 +22,18 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set end ## # Sets the remote network access for all composed sets. def remote= remote @@ -30,6 +42,10 @@ class Gem::Resolver::ComposedSet < Gem::Resolver::Set @sets.each { |set| set.remote = remote } end ## # Finds all specs matching +req+ in all sets. @@ -52,11 +52,40 @@ class Gem::Resolver::Conflict def explanation activated = @activated.spec.full_name - requirement = @failed_dep.dependency.requirement - " Activated %s via:\n %s\n instead of (%s) via:\n %s\n" % [ - activated, request_path(@activated).join(', '), - requirement, request_path(requester).join(', '), ] end @@ -95,10 +124,19 @@ class Gem::Resolver::Conflict path = [] while current do - requirement = current.request.dependency.requirement - path << "#{current.spec.full_name} (#{requirement})" - current = current.parent end path = ['user request (gem command or Gemfile)'] if path.empty? @@ -35,7 +35,26 @@ class Gem::Resolver::DependencyRequest end ## - # Does this dependency request match +spec+ def matches_spec?(spec) @dependency.matches_spec? spec @@ -80,7 +80,7 @@ class Gem::Resolver::GitSet < Gem::Resolver::Set prefetch nil specs.values.select do |spec| - req.matches_spec? spec end end @@ -12,11 +12,15 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification @source == other.source end ## # Installing a git gem only involves building the extensions and generating # the executables. - def install options require 'rubygems/installer' installer = Gem::Installer.new '', options @@ -31,5 +35,25 @@ class Gem::Resolver::GitSpecification < Gem::Resolver::SpecSpecification installer.run_post_install_hooks end end @@ -18,7 +18,9 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set @all = Hash.new { |h,k| h[k] = [] } - list, = @f.available_specs :released list.each do |uri, specs| specs.each do |n| @@ -41,7 +43,7 @@ class Gem::Resolver::IndexSet < Gem::Resolver::Set name = req.dependency.name @all[name].each do |uri, n| - if req.dependency.match? n then res << Gem::Resolver::IndexSpecification.new( self, n.name, n.version, uri, n.platform) end @@ -14,7 +14,7 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification # This is a null install as this specification is already installed. # +options+ are ignored. - def install options yield nil end @@ -29,6 +29,24 @@ class Gem::Resolver::InstalledSpecification < Gem::Resolver::SpecSpecification super end ## # The source for this specification @@ -21,6 +21,11 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set attr_accessor :ignore_installed # :nodoc: ## # Creates a new InstallerSet that will look for gems in +domain+. def initialize domain @@ -34,11 +39,53 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set @always_install = [] @ignore_dependencies = false @ignore_installed = false @remote_set = Gem::Resolver::BestSet.new @specs = {} end ## # Should local gems should be considered? def consider_local? # :nodoc: @@ -53,6 +100,13 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set end ## # Returns an array of IndexSpecification objects matching DependencyRequest # +req+. @@ -62,30 +116,53 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set dep = req.dependency return res if @ignore_dependencies and - @always_install.none? { |spec| dep.matches_spec? spec } name = dep.name dep.matching_specs.each do |gemspec| - next if @always_install.include? gemspec res << Gem::Resolver::InstalledSpecification.new(self, gemspec) end unless @ignore_installed if consider_local? then local_source = Gem::Source::Local.new - if spec = local_source.find_gem(name, dep.requirement) then res << Gem::Resolver::IndexSpecification.new( - self, spec.name, spec.version, local_source, spec.platform) end end res.concat @remote_set.find_all req if consider_remote? res end def inspect # :nodoc: always_install = @always_install.map { |s| s.full_name } @@ -108,6 +185,15 @@ class Gem::Resolver::InstallerSet < Gem::Resolver::Set end end def pretty_print q # :nodoc: q.group 2, '[InstallerSet', ']' do q.breakable @@ -12,5 +12,30 @@ class Gem::Resolver::LocalSpecification < Gem::Resolver::SpecSpecification super end end @@ -6,13 +6,16 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set attr_reader :specs # :nodoc: ## - # Creates a new LockSet from the given +source+ - def initialize source super() - @source = Gem::Source::Lock.new source - @specs = [] end ## @@ -25,13 +28,14 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set def add name, version, platform # :nodoc: version = Gem::Version.new version - spec = - Gem::Resolver::LockSpecification.new self, name, version, @source, platform - @specs << spec - spec end ## @@ -40,7 +44,7 @@ class Gem::Resolver::LockSet < Gem::Resolver::Set def find_all req @specs.select do |spec| - req.matches_spec? spec end end @@ -23,7 +23,7 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification # This is a null install as a locked specification is considered installed. # +options+ are ignored. - def install options destination = options[:install_dir] || Gem.dir if File.exist? File.join(destination, 'specifications', spec.spec_name) then @@ -41,10 +41,36 @@ class Gem::Resolver::LockSpecification < Gem::Resolver::Specification @dependencies << dependency end ## # A specification constructed from the lockfile is returned def spec @spec ||= Gem::Specification.new do |s| s.name = @name s.version = @version @@ -9,8 +9,20 @@ class Gem::Resolver::Set attr_accessor :remote def initialize # :nodoc: - @remote = true end ## @@ -4,8 +4,6 @@ class Gem::Resolver::SpecSpecification < Gem::Resolver::Specification - attr_reader :spec # :nodoc: - ## # A SpecSpecification is created for a +set+ for a Gem::Specification in # +spec+. The +source+ is either where the +spec+ came from, or should be @@ -31,6 +31,14 @@ class Gem::Resolver::Specification attr_reader :source ## # The version of the gem for this specification. attr_reader :version @@ -48,6 +56,13 @@ class Gem::Resolver::Specification end ## # The name and version of the specification. # # Unlike Gem::Specification#full_name, the platform is not included. @@ -61,8 +76,11 @@ class Gem::Resolver::Specification # install method yields a Gem::Installer instance, which indicates the # gem will be installed, or +nil+, which indicates the gem is already # installed. - def install options require 'rubygems/installer' destination = options[:install_dir] || Gem.dir @@ -75,7 +93,7 @@ class Gem::Resolver::Specification yield installer if block_given? - installer.install end ## @@ -85,5 +103,8 @@ class Gem::Resolver::Specification Gem::Platform.match spec.platform end end @@ -43,6 +43,8 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set @specs[spec.name] = spec @directories[spec] = directory end ## @@ -51,7 +53,7 @@ class Gem::Resolver::VendorSet < Gem::Resolver::Set def find_all req @specs.values.select do |spec| - req.matches_spec? spec end.map do |spec| source = Gem::Source::Vendor.new @directories[spec] Gem::Resolver::VendorSpecification.new self, spec, source @@ -16,7 +16,7 @@ class Gem::Resolver::VendorSpecification < Gem::Resolver::SpecSpecification # This is a null install as this gem was unpacked into a directory. # +options+ are ignored. - def install options yield nil end @@ -218,6 +218,7 @@ class Gem::Security::Policy # against else alert_warning "#{full_name} is not signed" end end @@ -530,6 +530,36 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } end end def quick(req, res) reset_gems @@ -537,7 +567,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } add_date res case req.request_uri.path - when %r|^/quick/(Marshal.#{Regexp.escape Gem.marshal_version}/)?(.*?)-([0-9.]+)(-.*?)?\.gemspec\.rz$| then marshal_format, name, version, platform = $1, $2, $3, $4 specs = Gem::Specification.find_all_by_name name, version @@ -757,6 +787,11 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; } @server.mount_proc "/latest_specs.#{Gem.marshal_version}.gz", method(:latest_specs) @server.mount_proc "/quick/", method(:quick) @server.mount_proc("/gem-server-rdoc-style.css") do |req, res| @@ -78,15 +78,21 @@ class Gem::Source # Returns a Set that can fetch specifications from this source. def dependency_resolver_set # :nodoc: bundler_api_uri = api_uri + './api/v1/dependencies' begin fetcher = Gem::RemoteFetcher.fetcher - fetcher.fetch_path bundler_api_uri, nil, true rescue Gem::RemoteFetcher::FetchError Gem::Resolver::IndexSet.new self else - Gem::Resolver::APISet.new bundler_api_uri end end @@ -100,6 +106,8 @@ class Gem::Source def cache_dir(uri) # Correct for windows paths escaped_path = uri.path.sub(/^\/([a-z]):\//i, '/\\1-/') File.join Gem.spec_cache_dir, "#{uri.host}%#{uri.port}", File.dirname(escaped_path) end @@ -51,7 +51,7 @@ class Gem::Source::Git < Gem::Source # will be checked out when the gem is installed. def initialize name, repository, reference, submodules = false - super(nil) @name = name @repository = repository @@ -67,7 +67,7 @@ class Gem::Source::Git < Gem::Source case other when Gem::Source::Git then 0 - when Gem::Source::Installed, Gem::Source::Lock then -1 when Gem::Source then @@ -101,7 +101,7 @@ class Gem::Source::Git < Gem::Source Dir.chdir install_dir do system @git, 'fetch', '--quiet', '--force', '--tags', install_dir - success = system @git, 'reset', '--quiet', '--hard', @reference success &&= Gem::Util.silent_system @git, 'submodule', 'update', @@ -12,7 +12,8 @@ class Gem::Source::Installed < Gem::Source def <=> other case other - when Gem::Source::Lock, Gem::Source::Vendor then -1 when Gem::Source::Installed then @@ -31,5 +32,9 @@ class Gem::Source::Installed < Gem::Source nil end end @@ -5,6 +5,11 @@ class Gem::Source::SpecificFile < Gem::Source ## # Creates a new SpecificFile for the gem in +file+ def initialize(file) @@ -37,7 +42,7 @@ class Gem::Source::SpecificFile < Gem::Source end def pretty_print q # :nodoc: - q.group 2, '[Local:', ']' do q.breakable q.text @path end @@ -186,7 +186,7 @@ class Gem::SpecFetcher def suggest_gems_from_name gem_name gem_name = gem_name.downcase.tr('_-', '') max = gem_name.size / 2 - names = available_specs(:complete).first.values.flatten(1) matches = names.map { |n| next unless n.match_platform? @@ -258,18 +258,11 @@ class Gem::SpecFetcher # etc.). If +gracefully_ignore+ is true, errors are ignored. def tuples_for(source, type, gracefully_ignore=false) # :nodoc: - cache = @caches[type] - - tuples = - begin - cache[source.uri] ||= - source.load_specs(type).sort_by { |tup| tup.name } - rescue Gem::RemoteFetcher::FetchError - raise unless gracefully_ignore - [] - end - - tuples end end @@ -14,12 +14,6 @@ require 'rubygems/basic_specification' require 'rubygems/stub_specification' require 'rubygems/util/stringio' -# :stopdoc: -# date.rb can't be loaded for `make install` due to miniruby -# Date is needed for old gems that stored #date as Date instead of Time. -class Date; end -# :startdoc: - ## # The Specification class contains the information for a Gem. Typically # defined in a .gemspec file or a Rakefile, and looks like this: @@ -218,9 +212,11 @@ class Gem::Specification < Gem::BasicSpecification # Usage: # # # If all library files are in the root directory... - # spec.require_path = '.' - attr_writer :require_paths ## # The version of RubyGems used to create this gem. @@ -373,7 +369,9 @@ class Gem::Specification < Gem::BasicSpecification ## # A long description of this gem # - # The description should be more detailed than the summary. # # Usage: # @@ -413,6 +411,16 @@ class Gem::Specification < Gem::BasicSpecification attr_accessor :post_install_message ## # The key used to sign this gem. See Gem::Security for details. attr_accessor :signing_key @@ -472,6 +480,9 @@ class Gem::Specification < Gem::BasicSpecification # found in bindir. These files must be executable Ruby files. Files that # use bash or other interpreters will not work. # # Usage: # # spec.executables << 'rake' @@ -532,20 +543,26 @@ class Gem::Specification < Gem::BasicSpecification ## # :category: Recommended gemspec attributes # The license for this gem. # - # The license must be a short name, no more than 64 characters. # - # This should just be the name of your license. The full - # text of the license should be inside of the gem when you build it. # - # See http://opensource.org/licenses/alphabetical for a list of licenses and - # their abbreviations (or short names). also provides a - # license picker at http://choosealicense.com/ # - # According to copyright law, not having an OSI-approved open source license - # means you have no rights to use the code for any purpose-- in other words, - # "all rights reserved". # # You can set multiple licenses with #licenses= # @@ -608,6 +625,13 @@ class Gem::Specification < Gem::BasicSpecification end ## # Lists the external (to RubyGems) requirements that must be met for this gem # to work. It's simply information for the user. # @@ -628,7 +652,7 @@ class Gem::Specification < Gem::BasicSpecification # spec.test_files = Dir.glob('test/tc_*.rb') # spec.test_files = ['tests/test-suite.rb'] - def test_files= files @test_files = Array files end @@ -662,16 +686,6 @@ class Gem::Specification < Gem::BasicSpecification attr_writer :original_platform # :nodoc: ## - # The version of Ruby required by this gem - - attr_reader :required_ruby_version - - ## - # The RubyGems version required by this gem - - attr_reader :required_rubygems_version - - ## # The rubyforge project this gem lives under. i.e. RubyGems' # rubyforge_project is "rubygems". # @@ -1259,9 +1273,13 @@ class Gem::Specification < Gem::BasicSpecification # there are conflicts upon activation. def activate - raise_if_conflicts - return false if Gem.loaded_specs[self.name] activate_dependencies add_self_to_load_path @@ -1403,7 +1421,10 @@ class Gem::Specification < Gem::BasicSpecification def build_args if File.exist? build_info_file - File.readlines(build_info_file).map { |x| x.strip } else [] end @@ -1418,8 +1439,8 @@ class Gem::Specification < Gem::BasicSpecification return if extensions.empty? return if installed_by_version < Gem::Version.new('2.2.0.preview.2') return if File.exist? gem_build_complete_path - return if !File.writable?(base_dir) && - !File.exist?(File.join(base_dir, 'extensions')) begin # We need to require things in $LOAD_PATH without looking for the @@ -1477,13 +1498,12 @@ class Gem::Specification < Gem::BasicSpecification def conflicts conflicts = {} - Gem.loaded_specs.values.each do |spec| - bad = self.runtime_dependencies.find_all { |dep| - spec.name == dep.name and not spec.satisfies_requirement? dep - } - - conflicts[spec] = bad unless bad.empty? - end conflicts end @@ -1496,6 +1516,11 @@ class Gem::Specification < Gem::BasicSpecification @date ||= TODAY end DateTimeFormat = # :nodoc: /\A (\d{4})-(\d{2})-(\d{2}) @@ -1525,7 +1550,7 @@ class Gem::Specification < Gem::BasicSpecification raise(Gem::InvalidSpecificationException, "invalid date format in specification: #{date.inspect}") end - when Time, Date then Time.utc(date.year, date.month, date.day) else TODAY @@ -1779,7 +1804,7 @@ class Gem::Specification < Gem::BasicSpecification ## # True if this gem has files in test_files - def has_unit_tests? not test_files.empty? end @@ -1953,6 +1978,19 @@ class Gem::Specification < Gem::BasicSpecification end ## # Normalize the list of files so that: # * All file lists have redundancies removed. # * Files referenced in the extra_rdoc_files are included in the package @@ -2036,34 +2074,34 @@ class Gem::Specification < Gem::BasicSpecification end ## - # Check the spec for possible conflicts and freak out if there are any. - def raise_if_conflicts - other = Gem.loaded_specs[self.name] - if other and self.version != other.version then - # This gem is already loaded. If the currently loaded gem is not in the - # list of candidate gems, then we have a version conflict. - msg = "can't activate #{full_name}, already activated #{other.full_name}" - e = Gem::LoadError.new msg - e.name = self.name - # TODO: e.requirement = dep.requirement - raise e - end - conf = self.conflicts - unless conf.empty? then - y = conf.map { |act,con| - "#{act.full_name} conflicts with #{con.join(", ")}" - }.join ", " - # TODO: improve message by saying who activated `con` - raise Gem::LoadError, "Unable to activate #{self.full_name}, because #{y}" end end @@ -2087,14 +2125,7 @@ class Gem::Specification < Gem::BasicSpecification # Singular accessor for #require_paths def require_path= path - self.require_paths = [path] - end - - ## - # The RubyGems version required by this gem - - def required_rubygems_version= req - @required_rubygems_version = Gem::Requirement.create req end ## @@ -2129,7 +2160,7 @@ class Gem::Specification < Gem::BasicSpecification seg = obj.keys.sort.map { |k| "#{k.to_s.dump} => #{obj[k].to_s.dump}" } "{ #{seg.join(', ')} }" when Gem::Version then obj.to_s.dump - when Date then obj.strftime('%Y-%m-%d').dump when Time then obj.strftime('%Y-%m-%d').dump when Numeric then obj.inspect when true, false, nil then obj.inspect @@ -2217,14 +2248,14 @@ class Gem::Specification < Gem::BasicSpecification ## # Singular accessor for #test_files - def test_file val = test_files and val.first end ## # Singular mutator for #test_files - def test_file= file self.test_files = [file] end @@ -2232,7 +2263,7 @@ class Gem::Specification < Gem::BasicSpecification # Test files included in this gem. You cannot append to this accessor, you # must assign to it. - def test_files # Handle the possibility that we have @test_suite_file but not # @test_files. This will happen when an old gem is loaded via # YAML. @@ -2256,7 +2287,7 @@ class Gem::Specification < Gem::BasicSpecification mark_version result = [] result << "# -*- encoding: utf-8 -*-" - result << "#{Gem::StubSpecification::PREFIX}#{name} #{version} #{platform} #{@require_paths.join("\0")}" result << "#{Gem::StubSpecification::PREFIX}#{extensions.join "\0"}" unless extensions.empty? result << nil @@ -2273,7 +2304,7 @@ class Gem::Specification < Gem::BasicSpecification if metadata and !metadata.empty? result << " s.metadata = #{ruby_code metadata} if s.respond_to? :metadata=" end - result << " s.require_paths = #{ruby_code @require_paths}" handled = [ :dependencies, @@ -2443,7 +2474,7 @@ class Gem::Specification < Gem::BasicSpecification "invalid value for attribute name: \"#{name.inspect}\"" end - if @require_paths.empty? then raise Gem::InvalidSpecificationException, 'specification must have at least one require_path' end @@ -2627,7 +2658,8 @@ duplicate dependency on #{dep}, (#{prev.requirement}) use: dep.requirement.requirements.any? do |op, version| op == '~>' and not version.prerelease? and - version.segments.length > 2 end if overly_strict then @@ -120,6 +120,13 @@ class Gem::StubSpecification < Gem::BasicSpecification super end ## # Name of the gem @@ -147,7 +154,14 @@ class Gem::StubSpecification < Gem::BasicSpecification # The full Gem::Specification for this gem, loaded from evalling its gemspec def to_spec @spec ||= Gem::Specification.load(loaded_from) end ## @@ -218,8 +218,11 @@ class Gem::TestCase < MiniTest::Unit::TestCase def setup super - @orig_gem_home = ENV['GEM_HOME'] - @orig_gem_path = ENV['GEM_PATH'] @current_dir = Dir.pwd @fetcher = nil @@ -347,8 +350,9 @@ class Gem::TestCase < MiniTest::Unit::TestCase FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES'] - ENV['GEM_HOME'] = @orig_gem_home - ENV['GEM_PATH'] = @orig_gem_path Gem.ruby = @orig_ruby if @orig_ruby @@ -1263,7 +1267,7 @@ Also, a list: # The StaticSet is a static set of gem specifications used for testing only. # It is available by requiring Gem::TestCase. - class StaticSet ## # A StaticSet ignores remote because it has a fixed set of gems. @@ -1274,6 +1278,8 @@ Also, a list: # Creates a new StaticSet for the given +specs+ def initialize(specs) @specs = specs @remote = true @@ -1299,7 +1305,7 @@ Also, a list: # Finds all gems matching +dep+ in this set. def find_all(dep) - @specs.find_all { |s| dep.matches_spec? s } end ## @@ -38,6 +38,8 @@ class Gem::FakeFetcher end def find_data(path) if URI === path and "URI::#{path.scheme.upcase}" != path.class.name then raise ArgumentError, "mismatch for scheme #{path.scheme} and class #{path.class}" @@ -26,6 +26,16 @@ module Gem::Text result.join("\n").gsub(/^/, " " * indent) end # This code is based directly on the Text gem implementation # Returns a value representing the "cost" of transforming str1 into str2 def levenshtein_distance str1, str2 @@ -42,16 +52,16 @@ module Gem::Text d = (0..m).to_a x = nil - n.times do |i| e = i+1 - m.times do |j| - cost = (s[i] == t[j]) ? 0 : 1 - x = [ d[j+1] + 1, # insertion e + 1, # deletion d[j] + cost # substitution - ].min d[j] = e e = x end @@ -96,6 +96,8 @@ class Gem::Uninstaller (@user_install and spec.base_dir == Gem.user_dir) end if list.empty? then if other_repo_specs.empty? if default_specs.empty? @@ -120,7 +122,8 @@ class Gem::Uninstaller remove_all list elsif list.size > 1 then - gem_names = list.collect {|gem| gem.full_name} + ["All versions"] say _, index = choose_from_list "Select gem to uninstall:", gem_names @@ -157,6 +157,14 @@ module Gem::UserInteraction def terminate_interaction exit_code = 0 ui.terminate_interaction exit_code end end ## @@ -143,6 +143,10 @@ # "~> 3.0.0" 3.0.0 ... 3.1 # "~> 3.5" 3.5 ... 4.0 # "~> 3.5.0" 3.5.0 ... 3.6 class Gem::Version autoload :Requirement, 'rubygems/requirement' @@ -189,7 +193,7 @@ class Gem::Version @@all = {} def self.new version # :nodoc: - return super unless Gem::VERSION == self.class @@all[version] ||= super end @@ -75,6 +75,21 @@ class TestGem < Gem::TestCase end end def test_require_missing save_loaded_features do assert_raises ::LoadError do @@ -216,6 +231,58 @@ class TestGem < Gem::TestCase end end def test_self_default_sources assert_equal %w[https://rubygems.org/], Gem.default_sources end @@ -816,6 +883,23 @@ class TestGem < Gem::TestCase assert_match %r%Could not find 'b' %, e.message end def test_self_use_paths util_ensure_gem_dirs @@ -951,6 +1035,30 @@ class TestGem < Gem::TestCase end end def test_load_plugins skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" plugin_path = File.join "lib", "rubygems_plugin.rb" @@ -1251,13 +1359,28 @@ class TestGem < Gem::TestCase end def test_use_gemdeps rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil spec = util_spec 'a', 1 refute spec.activated? - open 'Gemfile', 'w' do |io| io.write 'gem "a"' end @@ -1268,6 +1391,29 @@ class TestGem < Gem::TestCase ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end def test_use_gemdeps_automatic skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' @@ -1287,6 +1433,17 @@ class TestGem < Gem::TestCase ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end def test_use_gemdeps_disabled rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '' @@ -1294,7 +1451,7 @@ class TestGem < Gem::TestCase refute spec.activated? - open 'Gemfile', 'w' do |io| io.write 'gem "a"' end @@ -1305,6 +1462,27 @@ class TestGem < Gem::TestCase ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps end def test_use_gemdeps_specific skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7" rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x' @@ -3,6 +3,7 @@ require 'rubygems/available_set' require 'rubygems/security' class TestGemAvailableSet < Gem::TestCase def setup super @@ -23,22 +24,24 @@ class TestGemAvailableSet < Gem::TestCase end def test_find_all - a1, a1_gem = util_gem 'a', 1 - source = Gem::Source::SpecificFile.new a1_gem set = Gem::AvailableSet.new - set.add a1, source dep = Gem::Resolver::DependencyRequest.new dep('a'), nil - specs = set.find_all dep - - spec = specs.first - assert_kind_of Gem::Resolver::LocalSpecification, spec - assert_equal 'a-1', spec.full_name end def test_match_platform @@ -184,5 +184,60 @@ class TestGemCommand < Gem::TestCase assert_equal ['-h', 'command'], args end end @@ -179,6 +179,7 @@ Added '/CN=alternate/DC=example' assert_empty @ui.error assert_path_exists File.join(@tempdir, 'gem-public_cert.pem') end def test_execute_build_encrypted_key @@ -9,8 +9,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase @cmd = Gem::Commands::ContentsCommand.new end - def gem name - spec = quick_gem name do |gem| gem.files = %W[lib/#{name}.rb Rakefile] end write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb]) @@ -135,6 +135,40 @@ class TestGemCommandsContentsCommand < Gem::TestCase assert_equal "", @ui.error end def test_execute_no_prefix @cmd.options[:args] = %w[foo] @cmd.options[:prefix] = false @@ -183,13 +217,22 @@ lib/foo.rb assert @cmd.options[:prefix] assert_empty @cmd.options[:specdirs] assert_nil @cmd.options[:version] - @cmd.send :handle_options, %w[-l -s foo --version 0.0.2 --no-prefix] assert @cmd.options[:lib_only] refute @cmd.options[:prefix] assert_equal %w[foo], @cmd.options[:specdirs] assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version] end end @@ -28,6 +28,7 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase assert_match %r|RUBYGEMS PREFIX: |, @ui.output assert_match %r|RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}|, @ui.output assert_match %r|EXECUTABLE DIRECTORY:|, @ui.output assert_match %r|RUBYGEMS PLATFORMS:|, @ui.output assert_match %r|- #{Gem::Platform.local}|, @ui.output @@ -22,6 +22,13 @@ class TestGemCommandsHelpCommand < Gem::TestCase end end def test_gem_help_platforms util_gem 'platforms' do |out, err| assert_match(/x86-freebsd/, out) @@ -24,6 +24,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase Gem::Command.build_args = @orig_args File.unlink @gemdeps if File.file? @gemdeps end def test_execute_exclude_prerelease @@ -194,6 +195,32 @@ class TestGemCommandsInstallCommand < Gem::TestCase assert_match(%r!Unable to download data from http://not-there.nothing!, errs.shift) end def test_execute_nonexistent_with_hint misspelled = "nonexistent_with_hint" correctly_spelled = "non_existent_with_hint" @@ -238,7 +265,10 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 2, e.exit_code end - expected = ["ERROR: Could not find a valid gem 'non-existent_with-hint' (>= 0) in any repository", "ERROR: Possible alternatives: nonexistent-with_hint"] output = @ui.error.split "\n" @@ -535,6 +565,11 @@ ERROR: Possible alternatives: non_existent_with_hint end def test_install_gem_ignore_dependencies_both spec = quick_spec 'a', 2 util_build_gem spec @@ -546,6 +581,8 @@ ERROR: Possible alternatives: non_existent_with_hint @cmd.install_gem 'a', '>= 0' assert_equal %w[a-2], @cmd.installed_specs.map { |s| s.full_name } end def test_install_gem_ignore_dependencies_remote @@ -622,8 +659,8 @@ ERROR: Possible alternatives: non_existent_with_hint end assert_equal 2, e.exit_code - assert_match %r!Could not find a valid gem 'blah' \(>= 0\)!, @ui.error - assert_match %r!Unable to download data from http://not-there\.nothing!, @ui.error end def test_show_source_problems_even_on_success @@ -648,7 +685,7 @@ ERROR: Possible alternatives: non_existent_with_hint e = @ui.error - x = "WARNING: Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/latest_specs.4.8.gz (http://nonexistent.example/latest_specs.4.8.gz)\n" assert_equal x, e end @@ -672,6 +709,56 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name } assert_match "Using a (2)", @ui.output end def test_execute_installs_from_a_gemdeps @@ -885,6 +972,18 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 'gem.deps.rb', @cmd.options[:gemdeps] end def test_handle_options_without @cmd.handle_options %w[--without test] @@ -0,0 +1,46 @@ @@ -111,6 +111,12 @@ class TestGemCommandsSetupCommand < Gem::TestCase end expected = <<-EXPECTED === 2.0.2 / 2013-03-06 * Bug fixes: @@ -118,6 +124,9 @@ class TestGemCommandsSetupCommand < Gem::TestCase EXPECTED assert_equal expected, @ui.output ensure capture_io do @@ -239,6 +239,42 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase assert_equal nil, @cmd.options[:install_dir] assert_equal true, @cmd.options[:user_install] assert_equal Gem::Requirement.default, @cmd.options[:version] end end @@ -52,6 +52,30 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_empty out end def test_execute_system spec_fetcher do |fetcher| fetcher.gem 'rubygems-update', 9 do |s| s.files = %w[setup.rb] end @@ -266,6 +290,30 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_empty out end def test_execute_named_up_to_date spec_fetcher do |fetcher| fetcher.spec 'a', 2 @@ -437,6 +485,21 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_equal expected, @cmd.options end def test_update_rubygems_arguments @cmd.options[:system] = true @@ -18,7 +18,7 @@ class TestGemCommandsYankCommand < Gem::TestCase @cmd.handle_options %w[a --version 1.0 --platform x86-darwin -k KEY] assert_equal %w[a], @cmd.options[:args] - assert_equal 'KEY', @cmd.options[:key] assert_nil @cmd.options[:platform] assert_equal req('= 1.0'), @cmd.options[:version] end @@ -61,7 +61,7 @@ class TestGemCommandsYankCommand < Gem::TestCase @cmd.options[:args] = %w[a] @cmd.options[:version] = req('= 1.0') - @cmd.options[:key] = 'KEY' use_ui @ui do @cmd.execute @@ -234,16 +234,19 @@ if you believe they were disclosed to a third party. end def test_handle_arguments_debug - old_dollar_DEBUG = $DEBUG assert_equal false, $DEBUG args = %w[--debug] - @cfg.handle_arguments args assert_equal true, $DEBUG ensure - $DEBUG = old_dollar_DEBUG end def test_handle_arguments_override @@ -377,6 +380,9 @@ if you believe they were disclosed to a third party. fp.puts ":verbose: false" fp.puts ":sources:" fp.puts " - http://more-gems.example.com" fp.puts "install: --wrappers" end @@ -399,6 +405,10 @@ if you believe they were disclosed to a third party. assert_equal false, @cfg.update_sources, 'update_sources' assert_equal false, @cfg.verbose, 'verbose' assert_equal '--wrappers --no-rdoc', @cfg[:install], 'install' assert_equal %w[http://even-more-gems.example.com], Gem.sources @@ -409,11 +419,13 @@ if you believe they were disclosed to a third party. fp.puts "some-non-yaml-hash-string" end - # Avoid writing stuff to output when running tests - Gem::ConfigFile.class_eval { def warn(args); end } - # This should not raise exception - util_config_file end def test_load_ssl_verify_mode_from_config @@ -2,6 +2,7 @@ require 'rubygems/test_case' require 'rubygems/dependency' class TestGemDependency < Gem::TestCase def test_initialize d = dep "pkg", "> 1.0" @@ -28,6 +29,16 @@ class TestGemDependency < Gem::TestCase assert_equal req(">= 0"), d.requirement end def test_initialize_type assert_equal :runtime, dep("pkg").type assert_equal :development, dep("pkg", [], :development).type @@ -115,6 +126,106 @@ class TestGemDependency < Gem::TestCase refute_equal dep("pkg", :development), dep("pkg", :runtime), "type" end def test_merge a1 = dep 'a', '~> 1.0' a2 = dep 'a', '= 1.0' @@ -182,6 +293,29 @@ class TestGemDependency < Gem::TestCase assert dep('a', '= 1').specific? end def test_to_specs_suggests_other_versions a = util_spec 'a', '1.0', 'b' => '>= 1.0' @@ -197,7 +331,7 @@ class TestGemDependency < Gem::TestCase dep.to_specs end - assert_equal "Could not find 'a' (= 2.0) - did find: [a-1.0]", e.message end def test_to_specs_indicates_total_gem_set_size @@ -215,7 +349,7 @@ class TestGemDependency < Gem::TestCase dep.to_specs end - assert_equal "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message end @@ -126,6 +126,27 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal [p1a], inst.installed_gems end def test_install_when_only_prerelease p1a, gem = util_gem 'p', '1.a' @@ -138,7 +159,9 @@ class TestGemDependencyInstaller < Gem::TestCase dep = Gem::Dependency.new "p" inst = Gem::DependencyInstaller.new - inst.install dep assert_equal %w[], Gem::Specification.map(&:full_name) assert_equal [], inst.installed_gems @@ -291,7 +314,7 @@ class TestGemDependencyInstaller < Gem::TestCase Gem.done_installing do |installer, specs| done_installing_ran = true - assert_equal inst, installer assert_equal [@a1, @b1], specs end @@ -455,6 +478,20 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } end def test_install_local_dependency util_setup_gems @@ -538,6 +575,23 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[a-1 e-1], inst.installed_gems.map { |s| s.full_name } end def test_install_env_shebang util_setup_gems @@ -682,7 +736,7 @@ class TestGemDependencyInstaller < Gem::TestCase inst.install 'b' end - expected = "Unable to resolve dependency: 'b (= 1)' requires 'a (>= 0)'" assert_equal expected, e.message end @@ -796,10 +850,10 @@ class TestGemDependencyInstaller < Gem::TestCase s.platform = Gem::Platform.new %w[cpu other_platform 1] end - util_clear_gems - si = util_setup_spec_fetcher @a1, a2_o @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml a1_data = nil @@ -1043,165 +1097,6 @@ class TestGemDependencyInstaller < Gem::TestCase assert_kind_of Gem::SourceFetchProblem, installer.errors.first end - def assert_resolve expected, *specs - util_clear_gems - util_setup_spec_fetcher(*specs) - Gem::Specification.reset - - inst = Gem::DependencyInstaller.new - inst.find_spec_by_name_and_version specs.first.name - inst.gather_dependencies - - actual = inst.gems_to_install.map { |s| s.full_name } - assert_equal expected, actual - end - - def assert_resolve_pre expected, *specs - util_clear_gems - - util_setup_spec_fetcher(*specs) - Gem::Specification.reset - - spec = specs.first - - inst = Gem::DependencyInstaller.new :prerelease => true - inst.find_spec_by_name_and_version spec.name, spec.version - inst.gather_dependencies - - actual = inst.gems_to_install.map { |s| s.full_name } - assert_equal expected, actual - end - - def test_gather_dependencies - util_setup_gems - util_reset_gems - - inst = Gem::DependencyInstaller.new - inst.find_spec_by_name_and_version 'b' - inst.gather_dependencies - - assert_equal %w[a-1 b-1], inst.gems_to_install.map { |s| s.full_name } - end - - ## - # [A1] depends on - # [B] > 0 (satisfied by 2.0) - # [B1] depends on - # [C] > 0 (satisfied by 1.0) - # [B2] depends on nothing! - # [C1] depends on nothing - - def test_gather_dependencies_dropped - a1, = util_spec 'a', '1', 'b' => nil - b1, = util_spec 'b', '1', 'c' => nil - b2, = util_spec 'b', '2' - c1, = util_spec 'c', '1' - - assert_resolve %w[b-2 a-1], a1, b1, b2, c1 - end - - ## - # [A] depends on - # [B] >= 1.0 (satisfied by 1.1) depends on - # [Z] - # [C] >= 1.0 depends on - # [B] = 1.0 - # - # and should backtrack to resolve using b-1.0, pruning Z from the - # resolve. - - def test_gather_dependencies_raggi_the_edgecase_generator - a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '>= 1.0' - b1, _ = util_spec 'b', '1.0' - b2, _ = util_spec 'b', '1.1', 'z' => '>= 1.0' - c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' - - assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b1, b2, c - end - - ## - # [A] depends on - # [B] >= 1.0 (satisfied by 2.0) - # [C] = 1.0 depends on - # [B] ~> 1.0 - # - # and should resolve using b-1.0 - - def test_gather_dependencies_over - a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0' - b1, _ = util_spec 'b', '1.0' - b2, _ = util_spec 'b', '2.0' - c, _ = util_spec 'c', '1.0', 'b' => '~> 1.0' - - assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b1, b2, c - end - - ## - # [A] depends on - # [B] ~> 1.0 (satisfied by 1.1) - # [C] = 1.0 depends on - # [B] = 1.0 - # - # and should resolve using b-1.0 - # - # TODO: this is not under, but over... under would require depth - # first resolve through a dependency that is later pruned. - - def test_gather_dependencies_under - a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' - b10, _ = util_spec 'b', '1.0' - b11, _ = util_spec 'b', '1.1' - c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' - - assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b10, b11, c - end - - # under - # - # [A] depends on - # [B] ~> 1.0 (satisfied by 1.0) - # [C] = 1.0 depends on - # [B] = 2.0 - - def test_gather_dependencies_divergent - a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' - b1, _ = util_spec 'b', '1.0' - b2, _ = util_spec 'b', '2.0' - c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' - - assert_raises Gem::DependencyError do - assert_resolve :ignored, a, b1, b2, c - end - end - - def test_gather_dependencies_platform_alternate - util_setup_wxyz - util_set_arch 'cpu-my_platform1' - - assert_resolve %w[x-1-cpu-my_platform-1 w-1], @w1, @x1_m - end - - def test_gather_dependencies_platform_bump - util_setup_wxyz - - assert_resolve %w[y-1 z-1], @z1, @y1 - end - - def test_gather_dependencies_prerelease - util_setup_gems - util_setup_c1_pre - - assert_resolve_pre %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1 - end - - def test_gather_dependencies_old_required - util_setup_d - e1, = util_spec 'e', '1', 'd' => '= 1' - util_clear_gems - - assert_resolve %w[d-1 e-1], e1, @d1, @d2 - end - def test_resolve_dependencies util_setup_gems @@ -1232,6 +1127,21 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[b-1], requests end def util_write_a1_bin write_file File.join('gems', 'a-1', 'bin', 'a_bin') do |fp| fp.puts "#!/usr/bin/ruby" @@ -132,6 +132,17 @@ install: assert_path_exists File.join @spec.gem_dir, 'lib', 'a', 'b.rb' end def test_build_extensions_install_ext_only class << Gem alias orig_install_extension_in_lib install_extension_in_lib @@ -226,7 +237,7 @@ install: gem_make_out = File.join @spec.extension_dir, 'gem_make.out' - assert_match %r%#{Regexp.escape Gem.ruby} extconf\.rb%, File.read(gem_make_out) assert_match %r%: No such file%, File.read(gem_make_out) @@ -33,7 +33,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase assert_same result, output end - assert_match(/^#{Gem.ruby} extconf.rb/, output[0]) assert_equal "creating Makefile\n", output[1] assert_contains_make_command 'clean', output[2] assert_contains_make_command '', output[4] @@ -106,7 +106,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase assert_equal 'extconf failed, exit code 1', error.message - assert_equal("#{Gem.ruby} extconf.rb", output[0]) assert_path_exists File.join @dest_path, 'mkmf.log' end @@ -148,6 +148,15 @@ class TestGemGemcutterUtilities < Gem::TestCase assert_equal "", @sign_in_ui.output end def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf' @@ -28,14 +28,30 @@ class TestGemImpossibleDependenciesError < Gem::TestCase expected = <<-EXPECTED rye-0.9.8 requires net-ssh (>= 2.0.13) but it conflicted: - Activated net-ssh-2.6.5 via: - net-ssh-2.6.5 (>= 2.0.13), rye-0.9.8 (= 0.9.8) - instead of (~> 2.2.2) via: - net-ssh-2.6.5 (>= 2.0.13), rye-0.9.8 (= 0.9.8) - Activated net-ssh-2.2.2 via: - net-ssh-2.2.2 (>= 2.0.13), rye-0.9.8 (= 0.9.8) - instead of (>= 2.6.5) via: - net-ssh-2.2.2 (>= 2.0.13), rye-0.9.8 (= 0.9.8) EXPECTED assert_equal expected, error.message @@ -17,6 +17,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase def test_add_install_update_options args = %w[ --document --format-exec --ignore-dependencies --rdoc @@ -25,6 +26,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase -f -i /install_to -w ] args.concat %w[-P HighSecurity] if defined?(OpenSSL::SSL) @@ -32,6 +34,12 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase assert @cmd.handles?(args) end def test_doc @cmd.handle_options %w[--doc] @@ -147,4 +155,30 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase ensure FileUtils.chmod 0755, @gemhome end end @@ -188,6 +188,56 @@ gem 'other', version assert_match %r|generated by RubyGems|, wrapper end unless Gem.win_platform? def test_ensure_dependency util_spec 'a' @@ -574,6 +624,9 @@ gem 'other', version def test_generate_bin_symlink_win32 old_win_platform = Gem.win_platform? Gem.win_platform = true @installer.wrappers = false util_make_exec @installer.gem_dir = util_gem_dir @@ -592,6 +645,8 @@ gem 'other', version wrapper = File.read installed_exec assert_match(/generated by RubyGems/, wrapper) ensure Gem.win_platform = old_win_platform end @@ -1053,7 +1108,7 @@ gem 'other', version path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out') - if File.exists?(path) puts File.read(path) puts '-' * 78 end @@ -1071,6 +1126,16 @@ gem 'other', version refute @installer.installation_satisfies_dependency?(dep) end def test_pre_install_checks_dependencies @spec.add_dependency 'b', '> 5' util_setup_gem @@ -1157,6 +1222,22 @@ gem 'other', version assert_equal "#!#{Gem.ruby}", shebang end def test_shebang_arguments util_make_exec @spec, "#!/usr/bin/ruby -ws" @@ -90,6 +90,19 @@ class TestGemLocalRemoteOptions < Gem::TestCase assert_equal original_sources, Gem.sources end def test_update_sources_option @cmd.add_update_sources_option @@ -33,5 +33,12 @@ class TestGemNameTuple < Gem::TestCase assert_equal "a-0.gemspec", n.spec_name end end @@ -638,7 +638,7 @@ class TestGemPackage < Gem::Package::TarTestCase e.message io end - tf.close! end def test_verify_empty @@ -780,6 +780,23 @@ class TestGemPackage < Gem::Package::TarTestCase assert_equal @spec, package.spec end def util_tar tar_io = StringIO.new @@ -244,6 +244,36 @@ gems: assert File.exist?(a1_cache_gem) end def test_download_cached FileUtils.mv @a1_gem, @cache_dir @@ -557,6 +587,40 @@ gems: assert_equal "too many redirects (#{url})", e.message end def test_observe_no_proxy_env_single_host use_ui @ui do ENV["http_proxy"] = @proxy_uri @@ -711,6 +775,8 @@ gems: @proxy_server ||= start_server(PROXY_DATA) @enable_yaml = true @enable_zip = false end def stop_servers @@ -11,6 +11,10 @@ class TestGemRequest < Gem::TestCase PUBLIC_CERT_FILE = cert_path 'public' SSL_CERT = load_cert 'ssl' def setup @proxies = %w[http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY] @old_proxies = @proxies.map {|k| ENV[k] } @@ -21,7 +25,7 @@ class TestGemRequest < Gem::TestCase @proxy_uri = "http://localhost:1234" @uri = URI('http://example') - @request = Gem::Request.new @uri, nil, nil, nil end def teardown @@ -33,7 +37,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy proxy_uri = 'http://proxy.example.com' - request = Gem::Request.new @uri, nil, nil, proxy_uri assert_equal proxy_uri, request.proxy_uri.to_s end @@ -41,7 +45,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy_URI proxy_uri = 'http://proxy.example.com' - request = Gem::Request.new @uri, nil, nil, URI(proxy_uri) assert_equal proxy_uri, request.proxy_uri.to_s end @@ -51,7 +55,7 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy_user'] = 'foo' ENV['http_proxy_pass'] = 'bar' - request = Gem::Request.new @uri, nil, nil, nil proxy = request.proxy_uri @@ -62,7 +66,7 @@ class TestGemRequest < Gem::TestCase def test_initialize_proxy_ENV_https ENV['https_proxy'] = @proxy_uri - request = Gem::Request.new URI('https://example'), nil, nil, nil proxy = request.proxy_uri @@ -72,13 +76,13 @@ class TestGemRequest < Gem::TestCase def test_configure_connection_for_https connection = Net::HTTP.new 'localhost', 443 - request = Gem::Request.new URI('https://example'), nil, nil, nil - - def request.add_rubygems_trusted_certs store - store.add_cert TestGemRequest::PUBLIC_CERT - end - request.configure_connection_for_https connection cert_store = connection.cert_store @@ -91,13 +95,13 @@ class TestGemRequest < Gem::TestCase connection = Net::HTTP.new 'localhost', 443 - request = Gem::Request.new URI('https://example'), nil, nil, nil - def request.add_rubygems_trusted_certs store - store.add_cert TestGemRequest::PUBLIC_CERT - end - - request.configure_connection_for_https connection cert_store = connection.cert_store @@ -109,16 +113,18 @@ class TestGemRequest < Gem::TestCase def test_get_proxy_from_env_fallback ENV['http_proxy'] = @proxy_uri - - proxy = @request.get_proxy_from_env 'https' assert_equal URI(@proxy_uri), proxy end def test_get_proxy_from_env_https ENV['https_proxy'] = @proxy_uri - proxy = @request.get_proxy_from_env 'https' assert_equal URI(@proxy_uri), proxy end @@ -127,8 +133,9 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy'] = @proxy_uri ENV['http_proxy_user'] = 'foo\user' ENV['http_proxy_pass'] = 'my bar' - proxy = @request.get_proxy_from_env assert_equal 'foo\user', Gem::UriFormatter.new(proxy.user).unescape assert_equal 'my bar', Gem::UriFormatter.new(proxy.password).unescape @@ -138,8 +145,9 @@ class TestGemRequest < Gem::TestCase ENV['http_proxy'] = @proxy_uri ENV['http_proxy_user'] = 'foo@user' ENV['http_proxy_pass'] = 'my@bar' - proxy = @request.get_proxy_from_env assert_equal 'foo%40user', proxy.user assert_equal 'my%40bar', proxy.password @@ -147,23 +155,26 @@ class TestGemRequest < Gem::TestCase def test_get_proxy_from_env_normalize ENV['HTTP_PROXY'] = 'fakeurl:12345' - assert_equal 'http://fakeurl:12345', @request.get_proxy_from_env.to_s end def test_get_proxy_from_env_empty ENV['HTTP_PROXY'] = '' ENV.delete 'http_proxy' - assert_nil @request.get_proxy_from_env end def test_fetch uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - util_stub_connection_for :body => :junk, :code => 200 - response = @request.fetch assert_equal 200, response.code assert_equal :junk, response.body @@ -171,34 +182,34 @@ class TestGemRequest < Gem::TestCase def test_fetch_basic_auth uri = URI.parse "https://user:[email protected]/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - conn = util_stub_connection_for :body => :junk, :code => 200 - - @request.fetch auth_header = conn.payload['Authorization'] - assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header end def test_fetch_basic_auth_encoded uri = URI.parse "https://user:%7BDEScede%[email protected]/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - conn = util_stub_connection_for :body => :junk, :code => 200 - - @request.fetch auth_header = conn.payload['Authorization'] - assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header end def test_fetch_head uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" - @request = Gem::Request.new(uri, Net::HTTP::Get, nil, nil) - util_stub_connection_for :body => '', :code => 200 - - response = @request.fetch assert_equal 200, response.code assert_equal '', response.body @@ -207,10 +218,10 @@ class TestGemRequest < Gem::TestCase def test_fetch_unmodified uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" t = Time.utc(2013, 1, 2, 3, 4, 5) - @request = Gem::Request.new(uri, Net::HTTP::Get, t, nil) - conn = util_stub_connection_for :body => '', :code => 304 - - response = @request.fetch assert_equal 304, response.code assert_equal '', response.body @@ -221,7 +232,7 @@ class TestGemRequest < Gem::TestCase end def test_user_agent - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%^RubyGems/\S+ \S+ Ruby/\S+ \(.*?\)%, ua assert_match %r%RubyGems/#{Regexp.escape Gem::VERSION}%, ua @@ -236,7 +247,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) Object.send :const_set, :RUBY_ENGINE, 'vroom' - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%\) vroom%, ua ensure @@ -249,7 +260,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) Object.send :const_set, :RUBY_ENGINE, 'ruby' - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%\)%, ua ensure @@ -262,7 +273,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_LEVEL Object.send :const_set, :RUBY_LEVEL, 5 - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r% level 5\)%, ua ensure @@ -277,7 +288,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) Object.send :const_set, :RUBY_REVISION, 6 - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r% revision 6\)%, ua assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}dev%, ua @@ -292,7 +303,7 @@ class TestGemRequest < Gem::TestCase Object.send :const_set, :RUBY_LEVEL, -1 Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) - ua = Gem::Request.new(@uri, nil, nil, nil).user_agent assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE}\)%, ua ensure @@ -318,21 +329,24 @@ class TestGemRequest < Gem::TestCase @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION end - def util_stub_connection_for hash - def @request.connection= conn - @conn = conn - end - - def @request.connection_for uri - @conn - end - - @request.connection = Conn.new OpenStruct.new(hash) end class Conn attr_accessor :payload def initialize(response) @response = response self.payload = nil @@ -0,0 +1,120 @@ @@ -42,6 +42,12 @@ class TestGemRequestSet < Gem::TestCase fetcher.gem 'a', 2 end rs = Gem::RequestSet.new installed = [] @@ -61,6 +67,29 @@ class TestGemRequestSet < Gem::TestCase assert_path_exists 'gem.deps.rb.lock' assert rs.remote end def test_install_from_gemdeps_install_dir @@ -153,6 +182,30 @@ DEPENDENCIES assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' end def test_load_gemdeps rs = Gem::RequestSet.new @@ -160,10 +213,12 @@ DEPENDENCIES io.puts 'gem "a"' io.flush - rs.load_gemdeps io.path io end - tf.close! assert_equal [dep('a')], rs.dependencies @@ -171,6 +226,24 @@ DEPENDENCIES assert rs.vendor_set end def test_load_gemdeps_without_groups rs = Gem::RequestSet.new @@ -181,7 +254,7 @@ DEPENDENCIES rs.load_gemdeps io.path, [:test] io end - tf.close! assert_empty rs.dependencies end @@ -193,12 +266,69 @@ DEPENDENCIES rs = Gem::RequestSet.new rs.gem "a" res = rs.resolve StaticSet.new([a, b]) assert_equal 2, res.size names = res.map { |s| s.full_name }.sort assert_equal ["a-2", "b-2"], names end def test_resolve_git @@ -216,7 +346,7 @@ DEPENDENCIES rs.load_gemdeps io.path io end - tf.close! res = rs.resolve assert_equal 1, res.size @@ -280,7 +410,7 @@ DEPENDENCIES rs.load_gemdeps io.path io end - tf.close! res = rs.resolve assert_equal 2, res.size @@ -308,6 +438,12 @@ DEPENDENCIES end def test_install spec_fetcher do |fetcher| fetcher.gem "a", "1", "b" => "= 1" fetcher.gem "b", "1" @@ -336,6 +472,8 @@ DEPENDENCIES assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' assert_equal %w[b-1 a-1], installed.map { |s| s.full_name } end def test_install_into @@ -358,4 +496,102 @@ DEPENDENCIES assert_equal %w!b-1 a-1!, installed.map { |s| s.full_name } end end @@ -68,6 +68,22 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal [dep('a')], @set.dependencies assert_equal %w[a], @gda.requires['a'] end def test_gem_git @@ -76,6 +92,36 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal [dep('a')], @set.dependencies assert_equal %w[git/a master], @git_set.repositories['a'] end def test_gem_git_branch @@ -127,6 +173,23 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal %w[git://.com/example/repository.git master], @git_set.repositories['a'] end def test_gem_group @@ -141,6 +204,10 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase @gda.gem 'a', :group => :test assert_empty @set.dependencies end def test_gem_groups @@ -159,6 +226,10 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase loaded = @vendor_set.load_spec(name, version, Gem::Platform::RUBY, nil) assert_equal "#{name}-#{version}", loaded.full_name end def test_gem_platforms @@ -254,6 +325,18 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase Gem.win_platform = win_platform end def test_gem_platforms_version with_engine_version 'ruby', '2.0.0' do @gda.gem 'a', :platforms => :ruby_18 @@ -270,7 +353,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal 'unknown platform :unknown', e.message end - def test_gem_require @gda.gem 'a', :require => %w[b c] @gda.gem 'd', :require => 'e' @@ -280,7 +363,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal %w[e], @gda.requires['d'] end - def test_gem_require_false @gda.gem 'a', :require => false assert_equal [dep('a')], @set.dependencies @@ -288,7 +371,7 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_empty @gda.requires end - def test_gem_require_without_group @gda.without_groups << :test @gda.gem 'a', :group => :test @@ -302,12 +385,20 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase @gda.gem 'a', '~> 1.0' assert_equal [dep('a', '~> 1.0')], @set.dependencies end def test_gem_requirements @gda.gem 'b', '~> 1.0', '>= 1.0.2' assert_equal [dep('b', '~> 1.0', '>= 1.0.2')], @set.dependencies end def test_gem_requirements_options @@ -483,6 +574,16 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal %w[git://example/repo.git master], @git_set.repositories['b'] end def test_group @gda.group :test do @gda.gem 'a' @@ -504,12 +605,12 @@ end gda = @GDA.new @set, io.path - gda.load assert_equal [dep('a'), dep('b')], @set.dependencies io end - tf.close! end def test_name_typo @@ -538,18 +639,42 @@ end end def test_platform_mswin win_platform, Gem.win_platform = Gem.win_platform?, false - @gda.platform :mswin do - @gda.gem 'a' end assert_empty @set.dependencies - Gem.win_platform = true - @gda.platform :mswin do - @gda.gem 'a' end refute_empty @set.dependencies @@ -570,30 +695,27 @@ end end def test_platforms - win_platform, Gem.win_platform = Gem.win_platform?, false - @gda.platforms :ruby do - @gda.gem 'a' - end - assert_equal [dep('a')], @set.dependencies - @gda.platforms :mswin do - @gda.gem 'b' end - assert_equal [dep('a')], @set.dependencies - - Gem.win_platform = true - @gda.platforms :mswin do - @gda.gem 'c' end - - assert_equal [dep('a'), dep('c')], @set.dependencies - - ensure - Gem.win_platform = win_platform end def test_ruby @@ -647,6 +769,12 @@ end assert_equal "Your Ruby version is #{RUBY_VERSION}, but your gem.deps.rb requires 1.8.0", e.message end def test_source sources = Gem.sources @@ -38,6 +38,127 @@ class TestGemRequestSetLockfile < Gem::TestCase end end def test_get @lockfile.instance_variable_set :@tokens, [:token] @@ -142,7 +263,106 @@ DEPENDENCIES assert_equal %w[a-2], lockfile_set.specs.map { |tuple| tuple.full_name } end def test_parse_GIT write_lockfile <<-LOCKFILE GIT remote: git://example/a.git @@ -150,6 +370,7 @@ GIT specs: a (2) b (>= 3) DEPENDENCIES a! @@ -173,7 +394,126 @@ DEPENDENCIES assert_equal %w[a-2], git_set.specs.values.map { |s| s.full_name } - assert_equal [dep('b', '>= 3')], git_set.specs.values.first.dependencies end def test_parse_PATH @@ -184,6 +524,7 @@ PATH remote: #{directory} specs: a (1) DEPENDENCIES a! @@ -206,6 +547,28 @@ DEPENDENCIES assert vendor_set, 'could not find a VendorSet' assert_equal %w[a-1], vendor_set.specs.values.map { |s| s.full_name } end def test_parse_gem_specs_dependency @@ -853,5 +1216,23 @@ DEPENDENCIES refute_empty File.read gem_deps_lock_file end end @@ -207,6 +207,14 @@ class TestGemRequirement < Gem::TestCase end end def test_satisfied_by_eh_good assert_satisfied_by "0.2.33", "= 0.2.33" assert_satisfied_by "0.2.34", "> 0.2.33" @@ -277,6 +285,11 @@ class TestGemRequirement < Gem::TestCase refute_satisfied_by "1.1.pre", "~> 1.1" refute_satisfied_by "2.0.a", "~> 1.0" refute_satisfied_by "2.0.a", "~> 2.0" end def test_satisfied_by_eh_multiple @@ -13,6 +13,12 @@ class TestGemResolver < Gem::TestCase end def set(*specs) StaticSet.new(specs) end @@ -20,7 +26,7 @@ class TestGemResolver < Gem::TestCase actual = resolver.resolve exp = expected.sort_by { |s| s.full_name } - act = actual.map { |a| a.spec }.sort_by { |s| s.full_name } msg = "Set of gems was not the same: #{exp.map { |x| x.full_name}.inspect} != #{act.map { |x| x.full_name}.inspect}" @@ -123,6 +129,30 @@ class TestGemResolver < Gem::TestCase assert_equal ['b (= 2)'], reqs.to_a.map { |req| req.to_s } end def test_requests_ignore_dependencies a1 = util_spec 'a', 1, 'b' => 2 @@ -140,6 +170,104 @@ class TestGemResolver < Gem::TestCase assert_empty reqs end def test_no_overlap_specificly a = util_spec "a", '1' b = util_spec "b", "1" @@ -215,7 +343,7 @@ class TestGemResolver < Gem::TestCase res = Gem::Resolver.new([ad], s) - assert_resolves_to [a2_p1], res end def test_only_returns_spec_once @@ -19,6 +19,16 @@ class TestGemResolverActivationRequest < Gem::TestCase @req = @DR::ActivationRequest.new @a3, @dep, [@a1, @a2] end def test_inspect assert_match 'a-3', @req.inspect assert_match 'from a (>= 0)', @req.inspect @@ -73,13 +73,13 @@ class TestGemResolverAPISet < Gem::TestCase set.prefetch [a_dep] - @fetcher.data.delete "#{@dep_uri}?gems=a" - expected = [ @DR::APISpecification.new(set, data.first) ] assert_equal expected, set.find_all(a_dep) end def test_find_all_local @@ -28,6 +28,46 @@ class TestGemResolverAPISpecification < Gem::TestCase assert_equal expected, spec.dependencies end def test_installable_platform_eh set = Gem::Resolver::APISet.new data = { @@ -32,6 +32,26 @@ class TestGemResolverBestSet < Gem::TestCase assert_equal %w[a-1], found.map { |s| s.full_name } end def test_find_all_local spec_fetcher do |fetcher| fetcher.spec 'a', 1 @@ -76,5 +96,42 @@ class TestGemResolverBestSet < Gem::TestCase assert_empty set.sets end end @@ -2,6 +2,33 @@ require 'rubygems/test_case' class TestGemResolverComposedSet < Gem::TestCase def test_remote_equals best_set = Gem::Resolver::BestSet.new current_set = Gem::Resolver::CurrentSet.new @@ -22,10 +22,17 @@ class TestGemResolverConflict < Gem::TestCase Gem::Resolver::Conflict.new child, active expected = <<-EXPECTED - Activated net-ssh-2.2.2 via: - net-ssh-2.2.2 (>= 2.0.13) - instead of (>= 2.6.5) via: - net-ssh-2.2.2 (>= 2.0.13), rye-0.9.8 (= 0.9.8) EXPECTED assert_equal expected, conflict.explanation @@ -44,10 +51,15 @@ class TestGemResolverConflict < Gem::TestCase conflict = @DR::Conflict.new a1_req, activated expected = <<-EXPECTED - Activated a-2 via: - a-2 (= 2) - instead of (= 1) via: - user request (gem command or Gemfile) EXPECTED assert_equal expected, conflict.explanation @@ -64,8 +76,8 @@ class TestGemResolverConflict < Gem::TestCase Gem::Resolver::Conflict.new nil, nil expected = [ - 'net-ssh-2.2.2 (>= 2.0.13)', - 'rye-0.9.8 (= 0.9.8)' ] assert_equal expected, conflict.request_path(child.requester) @@ -8,6 +8,70 @@ class TestGemResolverDependencyRequest < Gem::TestCase @DR = Gem::Resolver::DependencyRequest end def test_requirement dependency = dep 'a', '>= 1' @@ -85,6 +85,32 @@ class TestGemResolverGitSet < Gem::TestCase assert_empty @set.find_all dependency end def test_root_dir assert_equal Gem.dir, @set.root_dir @@ -32,6 +32,18 @@ class TestGemResolverGitSpecification < Gem::TestCase refute_equal g_spec_a, i_spec end def test_install git_gem 'a', 1 @@ -22,6 +22,8 @@ class TestGemResolverIndexSet < Gem::TestCase fetcher = set.instance_variable_get :@f refute_same Gem::SpecFetcher.fetcher, fetcher end def test_find_all @@ -31,7 +33,7 @@ class TestGemResolverIndexSet < Gem::TestCase fetcher.spec 'b', 1 end - set = @DR::BestSet.new dependency = dep 'a', '~> 1' @@ -49,7 +51,7 @@ class TestGemResolverIndexSet < Gem::TestCase fetcher.spec 'b', 1 end - set = @DR::BestSet.new set.remote = false dependency = dep 'a', '~> 1' @@ -59,5 +61,29 @@ class TestGemResolverIndexSet < Gem::TestCase assert_empty set.find_all req end end @@ -2,6 +2,101 @@ require 'rubygems/test_case' class TestGemResolverInstallerSet < Gem::TestCase def test_consider_local_eh set = Gem::Resolver::InstallerSet.new :remote @@ -30,6 +125,54 @@ class TestGemResolverInstallerSet < Gem::TestCase refute set.consider_remote? end def test_load_spec specs = spec_fetcher do |fetcher| fetcher.spec 'a', 2 @@ -46,6 +189,18 @@ class TestGemResolverInstallerSet < Gem::TestCase assert_equal specs["a-2-#{Gem::Platform.local}"].full_name, spec.full_name end def test_remote_equals_both set = Gem::Resolver::InstallerSet.new :both set.remote = true @@ -5,14 +5,15 @@ class TestGemResolverLockSet < Gem::TestCase def setup super - @source = Gem::Source.new @gem_repo - @lock_source = Gem::Source::Lock.new @source - @set = Gem::Resolver::LockSet.new @source end def test_add - spec = @set.add 'a', '2', Gem::Platform::RUBY assert_equal %w[a-2], @set.specs.map { |t| t.full_name } @@ -26,12 +27,17 @@ class TestGemResolverLockSet < Gem::TestCase end def test_find_all - @set.add 'a', '2', Gem::Platform::RUBY - @set.add 'b', '2', Gem::Platform::RUBY found = @set.find_all dep 'a' assert_equal %w[a-2], found.map { |s| s.full_name } end def test_load_spec @@ -9,7 +9,7 @@ class TestGemResolverLockSpecification < Gem::TestCase @LS = Gem::Resolver::LockSpecification @source = Gem::Source.new @gem_repo - @set = Gem::Resolver::LockSet.new @source end def test_initialize @@ -83,5 +83,16 @@ class TestGemResolverLockSpecification < Gem::TestCase assert_equal [b_dep, c_dep], l_spec.spec.dependencies end end @@ -3,6 +3,7 @@ require 'rubygems/test_case' class TestGemResolverSpecification < Gem::TestCase class TestSpec < Gem::Resolver::Specification attr_reader :spec def initialize spec @@ -12,6 +13,26 @@ class TestGemResolverSpecification < Gem::TestCase end end def test_installable_platform_eh a = util_spec 'a', 1 @@ -28,5 +49,16 @@ class TestGemResolverSpecification < Gem::TestCase refute b_spec.installable_platform? end end @@ -11,10 +11,12 @@ class TestGemResolverVendorSet < Gem::TestCase def test_add_vendor_gem name, version, directory = vendor_gem - @set.add_vendor_gem name, directory spec = @set.load_spec name, version, Gem::Platform::RUBY, nil assert_equal "#{name}-#{version}", spec.full_name assert_equal File.expand_path(directory), spec.full_gem_path @@ -55,6 +57,20 @@ class TestGemResolverVendorSet < Gem::TestCase assert_equal expected, found end def test_load_spec error = Object.const_defined?(:KeyError) ? KeyError : IndexError @@ -347,7 +347,7 @@ class TestGemSecurityPolicy < Gem::TestCase assert_match "WARNING: some_gem is not signed\n", @ui.error assert_raises Gem::Security::Exception do - @almost_no.verify [PUBLIC_CERT], nil, digests, {} end end @@ -513,7 +513,7 @@ class TestGemSecurityPolicy < Gem::TestCase digests['SHA1']['data.tar.gz'] = OpenSSL::Digest.new 'SHA1', 'hello' assert_raises Gem::Security::Exception do - @almost_no.verify_signatures @spec, digests, {} end end @@ -10,8 +10,9 @@ class TestGemServer < Gem::TestCase def setup super - @a1 = quick_gem 'a', '1' - @a2 = quick_gem 'a', '2' @server = Gem::Server.new Gem.dir, process_based_port, false @req = WEBrick::HTTPRequest.new :Logger => nil @@ -144,6 +145,36 @@ class TestGemServer < Gem::TestCase assert_equal 2, @server.server.listeners.length end def test_quick_gemdirs data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n" dir = "#{@gemhome}2" @@ -223,6 +254,38 @@ class TestGemServer < Gem::TestCase assert_equal Gem::Platform.local, spec.platform end def test_rdoc data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n" @req.parse data @@ -279,7 +342,8 @@ class TestGemServer < Gem::TestCase assert_equal 'application/octet-stream', @res['content-type'] assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY]], Marshal.load(@res.body) end @@ -318,7 +382,8 @@ class TestGemServer < Gem::TestCase assert_equal 'application/x-gzip', @res['content-type'] assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY]], Marshal.load(Gem.gunzip(@res.body)) end @@ -1,5 +1,6 @@ require 'rubygems/test_case' require 'rubygems/source' class TestGemSource < Gem::TestCase @@ -40,13 +41,28 @@ class TestGemSource < Gem::TestCase end def test_dependency_resolver_set_bundler_api - @fetcher.data["#{@gem_repo}api/v1/dependencies"] = 'data' set = @source.dependency_resolver_set assert_kind_of Gem::Resolver::APISet, set end def test_dependency_resolver_set_marshal_api set = @source.dependency_resolver_set @@ -27,6 +27,21 @@ class TestGemSourceGit < Gem::TestCase assert_path_exists File.join @source.install_dir, 'a.gemspec' end def test_checkout_local @source.remote = false @@ -179,14 +194,18 @@ class TestGemSourceGit < Gem::TestCase git = Gem::Source::Git.new 'a', 'git/a', 'master', false remote = Gem::Source.new @gem_repo installed = Gem::Source::Installed.new assert_equal( 0, git. <=>(git), 'git <=> git') assert_equal( 1, git. <=>(remote), 'git <=> remote') assert_equal(-1, remote. <=>(git), 'remote <=> git') - assert_equal( 1, installed.<=>(git), 'installed <=> git') - assert_equal(-1, git. <=>(installed), 'git <=> installed') end def test_specs @@ -254,6 +273,10 @@ class TestGemSourceGit < Gem::TestCase end end def test_uri_hash assert_equal @hash, @source.uri_hash @@ -11,6 +11,8 @@ class TestGemSourceInstalled < Gem::TestCase specific = Gem::Source::SpecificFile.new a1.cache_file installed = Gem::Source::Installed.new local = Gem::Source::Local.new assert_equal( 0, installed.<=>(installed), 'installed <=> installed') @@ -22,6 +24,12 @@ class TestGemSourceInstalled < Gem::TestCase assert_equal(-1, specific. <=>(installed), 'specific <=> installed') assert_equal( 1, installed.<=>(specific), 'installed <=> specific') end end @@ -43,8 +43,8 @@ class TestGemSourceLock < Gem::TestCase assert_equal( 0, i_lock.<=>(i_lock), 'i_lock <=> i_lock') assert_equal( 0, v_lock.<=>(v_lock), 'v_lock <=> v_lock') - assert_equal(-1, g_lock.<=>(i_lock), 'g_lock <=> i_lock') - assert_equal( 1, i_lock.<=>(g_lock), 'i_lock <=> g_lock') assert_equal(-1, g_lock.<=>(v_lock), 'g_lock <=> v_lock') assert_equal( 1, v_lock.<=>(g_lock), 'v_lock <=> g_lock') @@ -9,6 +9,10 @@ class TestGemSourceSpecificFile < Gem::TestCase @sf = Gem::Source::SpecificFile.new(@a_gem) end def test_spec assert_equal @a, @sf.spec end @@ -12,6 +12,7 @@ class TestGemSourceVendor < Gem::TestCase def test_spaceship vendor = Gem::Source::Vendor.new 'vendor/foo' remote = Gem::Source.new @gem_repo installed = Gem::Source::Installed.new assert_equal( 0, vendor. <=>(vendor), 'vendor <=> vendor') @@ -19,6 +20,9 @@ class TestGemSourceVendor < Gem::TestCase assert_equal( 1, vendor. <=>(remote), 'vendor <=> remote') assert_equal(-1, remote. <=>(vendor), 'remote <=> vendor') assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed') assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') end @@ -225,7 +225,7 @@ end util_spec 'b', '2.0' c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' - e = assert_raises Gem::LoadError do assert_activate nil, a, c, "b" end @@ -1135,6 +1135,24 @@ dependencies: [] assert_equal %w[lib/code.rb], @a2.files end def test_build_extensions ext_spec @@ -1231,11 +1249,10 @@ dependencies: [] FileUtils.chmod 0555, @ext.base_dir FileUtils.chmod 0555, File.join(@ext.base_dir, 'extensions') - assert_raises Errno::EACCES do - @ext.build_extensions - end ensure - unless Gem.win_platform? then FileUtils.chmod 0755, File.join(@ext.base_dir, 'extensions') FileUtils.chmod 0755, @ext.base_dir end @@ -1331,22 +1348,14 @@ dependencies: [] def test_contains_requirable_file_eh_extension ext_spec - extconf_rb = File.join @ext.gem_dir, @ext.extensions.first - FileUtils.mkdir_p File.dirname extconf_rb - - open extconf_rb, 'w' do |f| - f.write <<-'RUBY' - open 'Makefile', 'w' do |f| - f.puts "clean:\n\techo cleaned" - f.puts "default:\n\techo built" - f.puts "install:\n\techo installed" - end - RUBY end - refute @ext.contains_requirable_file? 'nonexistent' - assert_path_exists @ext.extension_dir end def test_date @@ -1791,13 +1800,33 @@ dependencies: [] enable_shared 'no' do ext_spec - @ext.require_path = 'lib' - ext_install_dir = Pathname(@ext.extension_dir) - full_gem_path = Pathname(@ext.full_gem_path) - relative_install_dir = ext_install_dir.relative_path_from full_gem_path - assert_equal [relative_install_dir.to_s, 'lib'], @ext.require_paths end end @@ -1824,7 +1853,7 @@ dependencies: [] def test_full_require_paths ext_spec - @ext.require_path = 'lib' expected = [ @ext.extension_dir, @@ -2268,6 +2297,7 @@ end @a1.add_runtime_dependency 'k', '> 1.2' @a1.add_runtime_dependency 'l', '> 1.2.3' @a1.add_runtime_dependency 'm', '~> 2.1.0' use_ui @ui do @a1.validate @@ -2874,14 +2904,76 @@ end assert_equal @m1.to_ruby, valid_ruby_spec end def test_find_by_name - util_make_gems - assert(Gem::Specification.find_by_name("a")) - assert(Gem::Specification.find_by_name("a", "1")) - assert(Gem::Specification.find_by_name("a", ">1")) - assert_raises(Gem::LoadError) do - Gem::Specification.find_by_name("monkeys") end end def test_find_by_path @@ -23,16 +23,11 @@ class TestStubSpecification < Gem::TestCase def test_initialize_extension stub = stub_with_extension - ext_install_dir = Pathname(stub.extension_dir) - full_gem_path = Pathname(stub.full_gem_path) - relative_install_dir = ext_install_dir.relative_path_from full_gem_path - relative_install_dir = relative_install_dir.to_s - - assert_equal 'stub_e', stub.name - assert_equal v(2), stub.version - assert_equal Gem::Platform::RUBY, stub.platform - assert_equal [relative_install_dir, 'lib'], stub.require_paths - assert_equal %w[ext/stub_e/extconf.rb], stub.extensions end def test_initialize_missing_stubline @@ -55,22 +50,14 @@ class TestStubSpecification < Gem::TestCase def test_contains_requirable_file_eh_extension stub_with_extension do |stub| - extconf_rb = File.join stub.gem_dir, stub.extensions.first - FileUtils.mkdir_p File.dirname extconf_rb - - open extconf_rb, 'w' do |f| - f.write <<-'RUBY' - open 'Makefile', 'w' do |f| - f.puts "clean:\n\techo cleaned" - f.puts "default:\n\techo built" - f.puts "install:\n\techo installed" - end - RUBY end - refute stub.contains_requirable_file? 'nonexistent' - assert_path_exists stub.extension_dir end end @@ -85,9 +72,70 @@ class TestStubSpecification < Gem::TestCase assert_equal expected, stub.full_require_paths end def test_to_spec assert @foo.to_spec.is_a?(Gem::Specification) assert_equal "foo", @foo.to_spec.name end def stub_with_extension @@ -325,6 +325,29 @@ create_makefile '#{@spec.name}' assert_equal expected, e.message end def test_uninstall_selection_greater_than_one util_make_gems @@ -0,0 +1,32 @@ @@ -33,6 +33,12 @@ class TestKernel < Gem::TestCase assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size end def test_gem_conflicting assert gem('a', '= 1'), "Should load" @@ -2,6 +2,26 @@ require 'rubygems/test_case' require 'rubygems' class TestGemRequire < Gem::TestCase def setup super @@ -17,6 +37,46 @@ class TestGemRequire < Gem::TestCase assert require(path), "'#{path}' was already required" end def test_require_is_not_lazy_with_exact_req a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" b1 = new_spec "b", "1", nil, "lib/b/c.rb" |