From e487a7f53cffbadf0bf15ff169c9cb5898503250 Mon Sep 17 00:00:00 2001 From: drbrain Date: Mon, 26 Aug 2013 20:24:51 +0000 Subject: * lib/rubygems: Import RubyGems 2.1.0 Release Candidate * test/rubygems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 + lib/rubygems.rb | 18 +- lib/rubygems/basic_specification.rb | 220 +++++++++++---------- lib/rubygems/commands/build_command.rb | 19 ++ lib/rubygems/commands/check_command.rb | 7 + lib/rubygems/commands/cleanup_command.rb | 10 +- lib/rubygems/commands/contents_command.rb | 8 + lib/rubygems/commands/dependency_command.rb | 11 ++ lib/rubygems/commands/environment_command.rb | 3 + lib/rubygems/commands/fetch_command.rb | 10 + lib/rubygems/commands/list_command.rb | 13 +- lib/rubygems/commands/mirror_command.rb | 6 + lib/rubygems/commands/outdated_command.rb | 9 + lib/rubygems/commands/owner_command.rb | 11 +- lib/rubygems/commands/pristine_command.rb | 23 +-- lib/rubygems/commands/push_command.rb | 10 +- lib/rubygems/commands/query_command.rb | 9 + lib/rubygems/commands/rdoc_command.rb | 8 +- lib/rubygems/commands/search_command.rb | 15 +- lib/rubygems/commands/sources_command.rb | 47 +++++ lib/rubygems/commands/specification_command.rb | 16 ++ lib/rubygems/commands/stale_command.rb | 10 + lib/rubygems/commands/uninstall_command.rb | 25 ++- lib/rubygems/commands/unpack_command.rb | 18 ++ lib/rubygems/commands/update_command.rb | 9 + lib/rubygems/commands/which_command.rb | 11 ++ lib/rubygems/commands/yank_command.rb | 18 +- lib/rubygems/core_ext/kernel_require.rb | 8 +- lib/rubygems/defaults.rb | 7 + lib/rubygems/dependency_installer.rb | 5 +- lib/rubygems/package_task.rb | 7 +- lib/rubygems/security/policy.rb | 5 + lib/rubygems/security/signer.rb | 20 +- lib/rubygems/source.rb | 10 +- lib/rubygems/source/local.rb | 9 +- lib/rubygems/source/specific_file.rb | 28 +++ lib/rubygems/specification.rb | 99 +++++----- lib/rubygems/stub_specification.rb | 185 ++++++++--------- lib/rubygems/test_case.rb | 19 +- test/rubygems/test_gem.rb | 22 +++ .../test_gem_commands_uninstall_command.rb | 21 +- test/rubygems/test_gem_package_task.rb | 25 ++- test/rubygems/test_gem_security_policy.rb | 11 ++ test/rubygems/test_gem_security_signer.rb | 6 + test/rubygems/test_gem_source.rb | 23 +++ test/rubygems/test_gem_source_installed.rb | 28 +++ test/rubygems/test_gem_source_local.rb | 35 +++- test/rubygems/test_gem_source_specific_file.rb | 38 ++++ test/rubygems/test_gem_specification.rb | 12 +- 49 files changed, 863 insertions(+), 329 deletions(-) create mode 100644 test/rubygems/test_gem_source_installed.rb diff --git a/ChangeLog b/ChangeLog index 13a4787221..2ae4b7fb14 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Aug 27 05:24:34 2013 Eric Hodel + + * lib/rubygems: Import RubyGems 2.1.0 Release Candidate + * test/rubygems: ditto. + Mon Aug 26 16:24:58 2013 Nobuyoshi Nakada * parse.y (parser_nextc): warn carriage return in middle of line. diff --git a/lib/rubygems.rb b/lib/rubygems.rb index bd81308ba6..79d9546296 100644 --- a/lib/rubygems.rb +++ b/lib/rubygems.rb @@ -8,7 +8,7 @@ require 'rbconfig' module Gem - VERSION = '2.1.0.rc.1' + VERSION = '2.1.0.rc.2' end # Must be first since it unloads the prelude from 1.9.2 @@ -36,9 +36,9 @@ require 'rubygems/errors' # # Further RubyGems documentation can be found at: # +# * {RubyGems Guides}[http://guides.rubygems.org] # * {RubyGems API}[http://rubygems.rubyforge.org/rdoc] (also available from # gem server) -# * {RubyGems Bookshelf}[http://docs.rubygems.org] # # == RubyGems Plugins # @@ -1048,16 +1048,14 @@ module Gem # def register_default_spec(spec) - new_format, prefix_pattern = nil + new_format = Gem.default_gems_use_full_paths? || spec.require_paths.any? {|path| spec.files.any? {|f| f.start_with? path } } - spec.files.each do |file| - if new_format == nil - new_format = spec.require_paths.any? {|path| file.start_with? path} - - prefix_group = spec.require_paths.map {|f| f + "/"}.join("|") - prefix_pattern = /^(#{prefix_group})/ - end + if new_format + prefix_group = spec.require_paths.map {|f| f + "/"}.join("|") + prefix_pattern = /^(#{prefix_group})/ + end + spec.files.each do |file| if new_format file = file.sub(prefix_pattern, "") next unless $~ diff --git a/lib/rubygems/basic_specification.rb b/lib/rubygems/basic_specification.rb index 2e47f32986..24bb4bc014 100644 --- a/lib/rubygems/basic_specification.rb +++ b/lib/rubygems/basic_specification.rb @@ -1,139 +1,143 @@ -module Gem - # BasicSpecification is an abstract class which implements some common code used by - # both Specification and StubSpecification. - class BasicSpecification - def self.default_specifications_dir - File.join(Gem.default_dir, "specifications", "default") - end +## +# BasicSpecification is an abstract class which implements some common code +# used by both Specification and StubSpecification. - ## - # Name of the gem +class Gem::BasicSpecification - def name - raise NotImplementedError - end + ## + # The path this gemspec was loaded from. This attribute is not persisted. - ## - # Version of the gem + attr_reader :loaded_from - def version - raise NotImplementedError - end + def self.default_specifications_dir + File.join(Gem.default_dir, "specifications", "default") + end - ## - # Platform of the gem + ## + # True when the gem has been activated - def platform - raise NotImplementedError - end + def activated? + raise NotImplementedError + end - ## - # Require paths of the gem + ## + # Returns the full path to the base gem directory. + # + # eg: /usr/local/lib/ruby/gems/1.8 + + def base_dir + return Gem.dir unless loaded_from + @base_dir ||= if default_gem? then + File.dirname File.dirname File.dirname loaded_from + else + File.dirname File.dirname loaded_from + end + end - def require_paths - raise NotImplementedError - end + ## + # Return true if this spec can require +file+. - ## - # True when the gem has been activated + def contains_requirable_file? file + root = full_gem_path + suffixes = Gem.suffixes - def activated? - raise NotImplementedError + require_paths.any? do |lib| + base = "#{root}/#{lib}/#{file}" + suffixes.any? { |suf| File.file? "#{base}#{suf}" } end + end - ## - # Return a Gem::Specification from this gem + def default_gem? + loaded_from && + File.dirname(loaded_from) == self.class.default_specifications_dir + end - def to_spec - raise NotImplementedError - end + def find_full_gem_path # :nodoc: + # TODO: also, shouldn't it default to full_name if it hasn't been written? + path = File.expand_path File.join(gems_dir, full_name) + path.untaint + path if File.directory? path + end + + private :find_full_gem_path - ## - # The filename of the gem specification - attr_reader :filename + ## + # The full path to the gem (install path + full name). - ## - # Set the filename of the Specification was loaded from. +path+ is converted - # to a String. + def full_gem_path + # TODO: This is a heavily used method by gems, so we'll need + # to aleast just alias it to #gem_dir rather than remove it. + @full_gem_path ||= find_full_gem_path + end - def filename= path - @filename = path && path.to_s + ## + # Returns the full name (name-version) of this Gem. Platform information + # is included (name-version-platform) if it is specified and not the + # default Ruby platform. - @full_gem_path = nil - @gems_dir = nil - @base_dir = nil + def full_name + if platform == Gem::Platform::RUBY or platform.nil? then + "#{name}-#{version}".untaint + else + "#{name}-#{version}-#{platform}".untaint end + end - ## - # Return true if this spec can require +file+. + ## + # Returns the full path to the gems directory containing this spec's + # gem directory. eg: /usr/local/lib/ruby/1.8/gems - def contains_requirable_file? file - root = full_gem_path - suffixes = Gem.suffixes + def gems_dir + # TODO: this logic seems terribly broken, but tests fail if just base_dir + @gems_dir ||= File.join(loaded_from && base_dir || Gem.dir, "gems") + end - require_paths.any? do |lib| - base = "#{root}/#{lib}/#{file}" - suffixes.any? { |suf| File.file? "#{base}#{suf}" } - end - end + ## + # Set the path the Specification was loaded from. +path+ is converted to a + # String. - ## - # The full path to the gem (install path + full name). + def loaded_from= path + @loaded_from = path && path.to_s - def full_gem_path - # TODO: This is a heavily used method by gems, so we'll need - # to aleast just alias it to #gem_dir rather than remove it. - @full_gem_path ||= find_full_gem_path - end + @full_gem_path = nil + @gems_dir = nil + @base_dir = nil + end - # :nodoc: - def find_full_gem_path - # TODO: also, shouldn't it default to full_name if it hasn't been written? - path = File.expand_path File.join(gems_dir, full_name) - path.untaint - path if File.directory? path - end - private :find_full_gem_path + ## + # Name of the gem - ## - # Returns the full path to the gems directory containing this spec's - # gem directory. eg: /usr/local/lib/ruby/1.8/gems + def name + raise NotImplementedError + end - def gems_dir - # TODO: this logic seems terribly broken, but tests fail if just base_dir - @gems_dir ||= File.join(filename && base_dir || Gem.dir, "gems") - end + ## + # Platform of the gem - ## - # Returns the full path to the base gem directory. - # - # eg: /usr/local/lib/ruby/gems/1.8 - - def base_dir - return Gem.dir unless filename - @base_dir ||= if default_gem? then - File.dirname File.dirname File.dirname filename - else - File.dirname File.dirname filename - end - end + def platform + raise NotImplementedError + end - def default_gem? - filename && - File.dirname(filename) == self.class.default_specifications_dir - end + ## + # Require paths of the gem - ## - # Returns the full name (name-version) of this Gem. Platform information - # is included (name-version-platform) if it is specified and not the - # default Ruby platform. - - def full_name - if platform == Gem::Platform::RUBY or platform.nil? then - "#{name}-#{version}".untaint - else - "#{name}-#{version}-#{platform}".untaint - end - end + def require_paths + raise NotImplementedError end + + ## + # Return a Gem::Specification from this gem + + def to_spec + raise NotImplementedError + end + + ## + # Version of the gem + + def version + raise NotImplementedError + end + end + diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb index 64563ed3db..d975429fe8 100644 --- a/lib/rubygems/commands/build_command.rb +++ b/lib/rubygems/commands/build_command.rb @@ -15,6 +15,25 @@ class Gem::Commands::BuildCommand < Gem::Command "GEMSPEC_FILE gemspec file name to build a gem for" end + def description # :nodoc: + <<-EOF +The build command allows you to create a gem from a ruby gemspec. + +The best way to build a gem is to use a Rakefile and the Gem::PackageTask +which ships with RubyGems. + +The gemspec can either be created by hand or extracted from an existing gem +with gem spec: + + $ gem unpack my_gem-1.0.gem + Unpacked gem: '.../my_gem-1.0' + $ gem spec my_gem-1.0.gem --ruby > my_gem-1.0/my_gem-1.0.gemspec + $ cd my_gem-1.0 + [edit gem contents] + $ gem build my_gem-1.0.gemspec + EOF + end + def usage # :nodoc: "#{program_name} GEMSPEC_FILE" end diff --git a/lib/rubygems/commands/check_command.rb b/lib/rubygems/commands/check_command.rb index d7677d47a1..8893b9c3b2 100644 --- a/lib/rubygems/commands/check_command.rb +++ b/lib/rubygems/commands/check_command.rb @@ -79,6 +79,13 @@ class Gem::Commands::CheckCommand < Gem::Command '--gems --alien' end + def description # :nodoc: + <<-EOF +The check command can list and repair problems with installed gems and +specifications and will clean up gems that have been partially uninstalled. + EOF + end + def usage # :nodoc: "#{program_name} [OPTIONS] [GEMNAME ...]" end diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb index cacfe89404..c8f0082bfb 100644 --- a/lib/rubygems/commands/cleanup_command.rb +++ b/lib/rubygems/commands/cleanup_command.rb @@ -6,7 +6,7 @@ class Gem::Commands::CleanupCommand < Gem::Command def initialize super 'cleanup', - 'Clean up old versions of installed gems in the local repository', + 'Clean up old versions of installed gems', :force => false, :install_dir => Gem.dir add_option('-n', '-d', '--dryrun', @@ -33,11 +33,11 @@ class Gem::Commands::CleanupCommand < Gem::Command def description # :nodoc: <<-EOF -The cleanup command removes old gems from GEM_HOME. If an older version is -installed elsewhere in GEM_PATH the cleanup command won't touch it. +The cleanup command removes old versions of gems from GEM_HOME that are not +required to meet a dependency. If a gem is installed elsewhere in GEM_PATH +the cleanup command won't delete it. -Older gems that are required to satisify the dependencies of gems -are not removed. +If no gems are named all gems in GEM_HOME are cleaned. EOF end diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb index 9ba24895dc..97218848ed 100644 --- a/lib/rubygems/commands/contents_command.rb +++ b/lib/rubygems/commands/contents_command.rb @@ -45,6 +45,14 @@ class Gem::Commands::ContentsCommand < Gem::Command "--no-lib-only --prefix" end + def description # :nodoc: + <<-EOF +The contents command lists the files in an installed gem. The listing can +be given as full file names, file names without the installed directory +prefix or only the files that are requireable. + EOF + end + def usage # :nodoc: "#{program_name} GEMNAME [GEMNAME ...]" end diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb index f444841ccb..c5d6dd7d70 100644 --- a/lib/rubygems/commands/dependency_command.rb +++ b/lib/rubygems/commands/dependency_command.rb @@ -38,6 +38,17 @@ class Gem::Commands::DependencyCommand < Gem::Command "--local --version '#{Gem::Requirement.default}' --no-reverse-dependencies" end + def description # :nodoc: + <<-EOF +The dependency commands lists which other gems a given gem depends on. For +local gems only the reverse dependencies can be shown (which gems depend on +the named gem). + +The dependency list can be displayed in a format suitable for piping for +use with other commands. + EOF + end + def usage # :nodoc: "#{program_name} GEMNAME" end diff --git a/lib/rubygems/commands/environment_command.rb b/lib/rubygems/commands/environment_command.rb index 034f2ccb49..d32d12b757 100644 --- a/lib/rubygems/commands/environment_command.rb +++ b/lib/rubygems/commands/environment_command.rb @@ -21,6 +21,9 @@ class Gem::Commands::EnvironmentCommand < Gem::Command def description # :nodoc: <<-EOF +The environment command lets you query rubygems for its configuration for +use in shell scripts or as a debugging aid. + The RubyGems environment can be controlled through command line arguments, gemrc files, environment variables and built-in defaults. diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb index ec021359b6..b35987c329 100644 --- a/lib/rubygems/commands/fetch_command.rb +++ b/lib/rubygems/commands/fetch_command.rb @@ -28,6 +28,16 @@ class Gem::Commands::FetchCommand < Gem::Command "--version '#{Gem::Requirement.default}'" end + def description # :nodoc: + <<-EOF +The fetch command fetches gem files that can be stored for later use or +unpacked to examine their contents. + +See the build command help for an example of unpacking a gem, modifying it, +then repackaging it. + EOF + end + def usage # :nodoc: "#{program_name} GEMNAME [GEMNAME ...]" end diff --git a/lib/rubygems/commands/list_command.rb b/lib/rubygems/commands/list_command.rb index f3e5da9551..0d15950475 100644 --- a/lib/rubygems/commands/list_command.rb +++ b/lib/rubygems/commands/list_command.rb @@ -8,7 +8,7 @@ require 'rubygems/commands/query_command' class Gem::Commands::ListCommand < Gem::Commands::QueryCommand def initialize - super 'list', 'Display gems whose name starts with STRING' + super 'list', 'Display local gems whose name starts with STRING' remove_option('--name-matches') end @@ -21,6 +21,17 @@ class Gem::Commands::ListCommand < Gem::Commands::QueryCommand "--local --no-details" end + def description # :nodoc: + <<-EOF +The list command is used to view the gems you have installed locally. + +The --details option displays additional details including the summary, the +homepage, the author, the locations of different versions of the gem. + +To search for remote gems use the search command. + EOF + end + def usage # :nodoc: "#{program_name} [STRING]" end diff --git a/lib/rubygems/commands/mirror_command.rb b/lib/rubygems/commands/mirror_command.rb index 0f98077cbd..75419c857a 100644 --- a/lib/rubygems/commands/mirror_command.rb +++ b/lib/rubygems/commands/mirror_command.rb @@ -10,6 +10,12 @@ class Gem::Commands::MirrorCommand < Gem::Command end end + def description # :nodoc: + <<-EOF +The mirror command has been moved to the rubygems-mirror gem. + EOF + end + def execute alert_error "Install the rubygems-mirror gem for the mirror command" end diff --git a/lib/rubygems/commands/outdated_command.rb b/lib/rubygems/commands/outdated_command.rb index 196d0d67e6..f51bc5e93f 100644 --- a/lib/rubygems/commands/outdated_command.rb +++ b/lib/rubygems/commands/outdated_command.rb @@ -15,6 +15,15 @@ class Gem::Commands::OutdatedCommand < Gem::Command add_platform_option end + def description # :nodoc: + <<-EOF +The outdated command lists gems you way wish to upgrade to a newer version. + +You can check for dependency mismatches using the dependency command and +update the gems with the update or install commands. + EOF + end + def execute Gem::Specification.outdated_and_latest_version.each do |spec, remote_version| say "#{spec.name} (#{spec.version} < #{remote_version})" diff --git a/lib/rubygems/commands/owner_command.rb b/lib/rubygems/commands/owner_command.rb index c1c0a570d6..13b8793021 100644 --- a/lib/rubygems/commands/owner_command.rb +++ b/lib/rubygems/commands/owner_command.rb @@ -7,7 +7,14 @@ class Gem::Commands::OwnerCommand < Gem::Command include Gem::GemcutterUtilities def description # :nodoc: - 'Manage gem owners on RubyGems.org.' + <<-EOF +The owner command lets you add and remove owners of a gem on a push +server (the default is https://rubygems.org). + +The owner of a gem has the permission to push new versions, yank existing +versions or edit the HTML page of the gem. Be careful of who you give push +permission to. + EOF end def arguments # :nodoc: @@ -19,7 +26,7 @@ class Gem::Commands::OwnerCommand < Gem::Command end def initialize - super 'owner', description + super 'owner', 'Manage gem owners of a gem on the push server' add_proxy_option add_key_option defaults.merge! :add => [], :remove => [] diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb index 257e6df1cc..3f3bca45be 100644 --- a/lib/rubygems/commands/pristine_command.rb +++ b/lib/rubygems/commands/pristine_command.rb @@ -21,7 +21,8 @@ class Gem::Commands::PristineCommand < Gem::Command end add_option('--[no-]extensions', - 'Restore gems with extensions') do |value, options| + 'Restore gems with extensions', + 'in addition to regular gems') do |value, options| options[:extensions] = value end @@ -49,23 +50,23 @@ class Gem::Commands::PristineCommand < Gem::Command def description # :nodoc: <<-EOF -The pristine command compares the installed gems with the contents of the -cached gem and restores any files that don't match the cached gem's copy. +The pristine command compares an installed gem with the contents of its +cached .gem file and restores any files that don't match the cached .gem's +copy. -If you have made modifications to your installed gems, the pristine command -will revert them. After all the gem's files have been checked all bin stubs -for the gem are regenerated. +If you have made modifications to an installed gem, the pristine command +will revert them. All extensions are rebuilt and all bin stubs for the gem +are regenerated after checking for modifications. -If the cached gem cannot be found, you will need to use `gem install` to -revert the gem. +If the cached gem cannot be found it will be downloaded. -If --no-extensions is provided pristine will not attempt to restore gems -with extensions. +If --no-extensions is provided pristine will not attempt to restore a gem +with an extension. EOF end def usage # :nodoc: - "#{program_name} [args]" + "#{program_name} [GEMNAME ...]" end def execute diff --git a/lib/rubygems/commands/push_command.rb b/lib/rubygems/commands/push_command.rb index fccad206fa..b90be7bd10 100644 --- a/lib/rubygems/commands/push_command.rb +++ b/lib/rubygems/commands/push_command.rb @@ -8,7 +8,13 @@ class Gem::Commands::PushCommand < Gem::Command include Gem::GemcutterUtilities def description # :nodoc: - 'Push a gem up to RubyGems.org' + <<-EOF +The push command uploads a gem to the push server (the default is +https://rubygems.org) and adds it to the index. + +The gem can be removed from the index (but only the index) using the yank +command. For further discussion see the help for the yank command. + EOF end def arguments # :nodoc: @@ -20,7 +26,7 @@ class Gem::Commands::PushCommand < Gem::Command end def initialize - super 'push', description, :host => self.host + super 'push', 'Push a gem up to the gem server', :host => self.host add_proxy_option add_key_option diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb index 05b214bb63..c9c3014975 100644 --- a/lib/rubygems/commands/query_command.rb +++ b/lib/rubygems/commands/query_command.rb @@ -61,6 +61,15 @@ class Gem::Commands::QueryCommand < Gem::Command "--local --name-matches // --no-details --versions --no-installed" end + def description # :nodoc: + <<-EOF +The query command is the basis for the list and search commands. + +You should really use the list and search commands instead. This command +is too hard to use. + EOF + end + def execute exit_code = 0 diff --git a/lib/rubygems/commands/rdoc_command.rb b/lib/rubygems/commands/rdoc_command.rb index df00f3a5df..86597f99a6 100644 --- a/lib/rubygems/commands/rdoc_command.rb +++ b/lib/rubygems/commands/rdoc_command.rb @@ -45,8 +45,12 @@ class Gem::Commands::RdocCommand < Gem::Command def description # :nodoc: <<-DESC -The rdoc command builds RDoc and RI documentation for installed gems. Use ---overwrite to force rebuilding of documentation. +The rdoc command builds documentation for installed gems. By default +only documentation is built using rdoc, but additional types of +documentation may be built through rubygems plugins and the +Gem.post_installs hook. + +Use --overwrite to force rebuilding of documentation. DESC end diff --git a/lib/rubygems/commands/search_command.rb b/lib/rubygems/commands/search_command.rb index c125715fe2..5bc9650672 100644 --- a/lib/rubygems/commands/search_command.rb +++ b/lib/rubygems/commands/search_command.rb @@ -4,7 +4,7 @@ require 'rubygems/commands/query_command' class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand def initialize - super 'search', 'Display all gems whose name contains STRING' + super 'search', 'Display remote gems whose name contains STRING' remove_option '--name-matches' @@ -19,6 +19,19 @@ class Gem::Commands::SearchCommand < Gem::Commands::QueryCommand "--remote --no-details" end + 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 +individually from the index. + +To list local gems use the list command. + EOF + end + def usage # :nodoc: "#{program_name} [STRING]" end diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb index 810b45d7c0..60d96c5828 100644 --- a/lib/rubygems/commands/sources_command.rb +++ b/lib/rubygems/commands/sources_command.rb @@ -97,6 +97,53 @@ Do you want to add this insecure source? '--list' end + def description # :nodoc: + <<-EOF +RubyGems fetches gems from the sources you have configured (stored in your +~/.gemrc). + +The default source is https://rubygems.org, but you may have older sources +configured. This guide will help you update your sources or configure +yourself to use your own gem server. + +Without any arguments the sources lists your currently configured sources: + + $ gem sources + *** CURRENT SOURCES *** + + https://rubygems.org + +This may list multiple sources or non-rubygems sources. You probably +configured them before or have an old `~/.gemrc`. If you have sources you +do not recognize you should remove them. + +RubyGems has been configured to serve gems via the following URLs through +its history: + +* http://gems.rubyforge.org (RubyGems 1.3.6 and earlier) +* http://rubygems.org (RubyGems 1.3.7 through 1.8.25) +* https://rubygems.org (RubyGems 2.0.1 and newer) + +Since all of these sources point to the same set of gems you only need one +of them in your list. https://rubygems.org is recommended as it brings the +protections of an SSL connection to gem downloads. + +To add a source use the --add argument: + + $ gem sources --add https://rubygems.org + https://rubygems.org added to sources + +RubyGems will check to see if gems can be installed from the source given +before it is added. + +To remove a source use the --remove argument: + + $ gem sources --remove http://rubygems.org + http://rubygems.org removed from sources + + EOF + end + def list # :nodoc: say "*** CURRENT SOURCES ***" say diff --git a/lib/rubygems/commands/specification_command.rb b/lib/rubygems/commands/specification_command.rb index b40dfd5f3c..d96c8b8627 100644 --- a/lib/rubygems/commands/specification_command.rb +++ b/lib/rubygems/commands/specification_command.rb @@ -50,6 +50,22 @@ FIELD name of gemspec field to show "--local --version '#{Gem::Requirement.default}' --yaml" end + def description # :nodoc: + <<-EOF +The specification command allows you to extract the specification from +a gem for examination. + +The specification can be output in YAML, ruby or Marshal formats. + +Specific fields in the specification can be extracted in YAML format: + + $ gem spec rake summary + --- Ruby based make-like utility. + ... + + EOF + end + def usage # :nodoc: "#{program_name} [GEMFILE] [FIELD]" end diff --git a/lib/rubygems/commands/stale_command.rb b/lib/rubygems/commands/stale_command.rb index 36c517e27c..0ef0755960 100644 --- a/lib/rubygems/commands/stale_command.rb +++ b/lib/rubygems/commands/stale_command.rb @@ -5,6 +5,16 @@ class Gem::Commands::StaleCommand < Gem::Command super('stale', 'List gems along with access times') end + def description # :nodoc: + <<-EOF +The stale command lists the latest access time for all the files in your +installed gems. + +You can use this command to discover gems and gem versions you are no +longer using. + EOF + end + def usage # :nodoc: "#{program_name}" end diff --git a/lib/rubygems/commands/uninstall_command.rb b/lib/rubygems/commands/uninstall_command.rb index 5db8a1ff22..8e6af2ba65 100644 --- a/lib/rubygems/commands/uninstall_command.rb +++ b/lib/rubygems/commands/uninstall_command.rb @@ -88,6 +88,16 @@ class Gem::Commands::UninstallCommand < Gem::Command "--user-install" end + def description # :nodoc: + <<-EOF +The uninstall command removes a previously installed gem. + +RubyGems will ask for confirmation if you are attempting to uninstall a gem +that is a dependency of an existing gem. You can use the +--ignore-dependencies option to skip this check. + EOF + end + def usage # :nodoc: "#{program_name} GEMNAME [GEMNAME ...]" end @@ -104,15 +114,18 @@ class Gem::Commands::UninstallCommand < Gem::Command end def uninstall_all - install_dir = options[:install_dir] + _, specs = Gem::Specification.partition { |spec| spec.default_gem? } - dirs_to_be_emptied = Dir[File.join(install_dir, '*')] - dirs_to_be_emptied.delete_if { |dir| dir.end_with? 'build_info' } + specs.each do |spec| + options[:version] = spec.version - dirs_to_be_emptied.each do |dir| - FileUtils.rm_rf Dir[File.join(dir, '*')] + begin + Gem::Uninstaller.new(spec.name, options).uninstall + rescue Gem::InstallError + end end - alert("Successfully uninstalled all gems in #{install_dir}") + + alert "Uninstalled all gems in #{options[:install_dir]}" end def uninstall_specific diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb index 7eefd32a6e..e60e7d90fd 100644 --- a/lib/rubygems/commands/unpack_command.rb +++ b/lib/rubygems/commands/unpack_command.rb @@ -34,6 +34,24 @@ class Gem::Commands::UnpackCommand < Gem::Command "--version '#{Gem::Requirement.default}'" end + def description + <<-EOF +The unpack command allows you to examine the contents of a gem or modify +them to help diagnose a bug. + +You can add the contents of the unpacked gem to the load path using the +RUBYLIB environment variable or -I: + + $ gem unpack my_gem + Unpacked gem: '.../my_gem-1.0' + [edit my_gem-1.0/lib/my_gem.rb] + $ ruby -Imy_gem-1.0/lib -S other_program + +You can repackage an unpacked gem using the build command. See the build +command help for an example. + EOF + end + def usage # :nodoc: "#{program_name} GEMNAME" end diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index 3a167361cf..77bf5edb45 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -52,6 +52,15 @@ class Gem::Commands::UpdateCommand < Gem::Command "--document --no-force --install-dir #{Gem.dir}" end + def description # :nodoc: + <<-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 diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb index 6495278a87..99b9085b2b 100644 --- a/lib/rubygems/commands/which_command.rb +++ b/lib/rubygems/commands/which_command.rb @@ -23,6 +23,17 @@ class Gem::Commands::WhichCommand < Gem::Command "--no-gems-first --no-all" end + def description # :nodoc: + <<-EOF +The which command is like the shell which command and shows you where +the file you wish to require lives. + +You can use the which command to help determine why you are requiring a +version you did not expect or to look at the content of a file you are +requiring to see why it does not behave as you expect. + EOF + end + def execute found = false diff --git a/lib/rubygems/commands/yank_command.rb b/lib/rubygems/commands/yank_command.rb index df4142d395..2285bb4017 100644 --- a/lib/rubygems/commands/yank_command.rb +++ b/lib/rubygems/commands/yank_command.rb @@ -9,7 +9,21 @@ class Gem::Commands::YankCommand < Gem::Command include Gem::GemcutterUtilities def description # :nodoc: - 'Remove a specific gem version release from RubyGems.org' + <<-EOF +The yank command removes a gem you pushed to a server from the server's +index. + +Note that if you push a gem to rubygems.org the yank command does not +prevent other people from downloading the gem via the download link. + +Once you have pushed a gem several downloads will happen automatically +via the webhooks. If you accidentally pushed passwords or other sensitive +data you will need to change them immediately and yank your gem. + +If you are yanking a gem due to intellectual property reasons contact +http://help.rubygems.org for permanant removal. Be sure to mention this +as the reason for the removal request. + EOF end def arguments # :nodoc: @@ -21,7 +35,7 @@ class Gem::Commands::YankCommand < Gem::Command end def initialize - super 'yank', description + super 'yank', 'Remove a pushed gem from the index' add_version_option("remove") add_platform_option("remove") diff --git a/lib/rubygems/core_ext/kernel_require.rb b/lib/rubygems/core_ext/kernel_require.rb index b9172e26c0..3619f3f559 100755 --- a/lib/rubygems/core_ext/kernel_require.rb +++ b/lib/rubygems/core_ext/kernel_require.rb @@ -8,6 +8,8 @@ require 'monitor' module Kernel + RUBYGEMS_ACTIVATION_MONITOR = Monitor.new # :nodoc: + if defined?(gem_original_require) then # Ruby ships with a custom_require, override its require remove_method :require @@ -33,10 +35,8 @@ module Kernel # The normal require functionality of returning false if # that file has already been loaded is preserved. - ACTIVATION_MONITOR = Monitor.new - def require path - ACTIVATION_MONITOR.enter + RUBYGEMS_ACTIVATION_MONITOR.enter spec = Gem.find_unresolved_default_spec(path) if spec @@ -118,7 +118,7 @@ module Kernel raise load_error ensure - ACTIVATION_MONITOR.exit + RUBYGEMS_ACTIVATION_MONITOR.exit end private :require diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 9b5bea21da..591580b7da 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -134,4 +134,11 @@ module Gem def self.default_cert_path File.join Gem.user_home, ".gem", "gem-public_cert.pem" end + + ## + # Whether to expect full paths in default gems - true for non-MRI + # ruby implementations + def self.default_gems_use_full_paths? + ruby_engine != 'ruby' + end end diff --git a/lib/rubygems/dependency_installer.rb b/lib/rubygems/dependency_installer.rb index 2523d1b2ae..e7c489a759 100644 --- a/lib/rubygems/dependency_installer.rb +++ b/lib/rubygems/dependency_installer.rb @@ -5,8 +5,7 @@ require 'rubygems/package' require 'rubygems/installer' require 'rubygems/spec_fetcher' require 'rubygems/user_interaction' -require 'rubygems/source/local' -require 'rubygems/source/specific_file' +require 'rubygems/source' require 'rubygems/available_set' ## @@ -251,7 +250,6 @@ class Gem::DependencyInstaller def find_spec_by_name_and_version gem_name, version = Gem::Requirement.default, prerelease = false - set = Gem::AvailableSet.new if consider_local? @@ -269,7 +267,6 @@ class Gem::DependencyInstaller if set.empty? dep = Gem::Dependency.new gem_name, version - # HACK Dependency objects should be immutable dep.prerelease = true if prerelease set = find_gems_with_sources(dep) diff --git a/lib/rubygems/package_task.rb b/lib/rubygems/package_task.rb index 463f8d32cc..09384cc0e7 100644 --- a/lib/rubygems/package_task.rb +++ b/lib/rubygems/package_task.rb @@ -96,12 +96,15 @@ class Gem::PackageTask < Rake::PackageTask def define super - task :package => [:gem] - gem_file = File.basename gem_spec.cache_file gem_path = File.join package_dir, gem_file gem_dir = File.join package_dir, gem_spec.full_name + task :package => [:gem] + + directory package_dir + directory gem_dir + desc "Build the gem file #{gem_file}" task :gem => [gem_path] diff --git a/lib/rubygems/security/policy.rb b/lib/rubygems/security/policy.rb index 98e41b812c..7238b2e477 100644 --- a/lib/rubygems/security/policy.rb +++ b/lib/rubygems/security/policy.rb @@ -213,6 +213,9 @@ class Gem::Security::Policy if @only_signed then raise Gem::Security::Exception, "unsigned gems are not allowed by the #{name} policy" + elsif digests.empty? then + # lack of signatures is irrelevant if there is nothing to check + # against else alert_warning "#{full_name} is not signed" end @@ -246,6 +249,8 @@ class Gem::Security::Policy if @only_trusted then check_trust chain, digester, trust_dir + elsif signatures.empty? and digests.empty? then + # trust is irrelevant if there's no signatures to verify else alert_warning "#{subject signer} is not trusted for #{full_name}" end diff --git a/lib/rubygems/security/signer.rb b/lib/rubygems/security/signer.rb index 231f2fe604..bb1eae7cf2 100644 --- a/lib/rubygems/security/signer.rb +++ b/lib/rubygems/security/signer.rb @@ -62,6 +62,22 @@ class Gem::Security::Signer end end + ## + # Extracts the full name of +cert+. If the certificate has a subjectAltName + # this value is preferred, otherwise the subject is used. + + def extract_name cert # :nodoc: + subject_alt_name = cert.extensions.find { |e| 'subjectAltName' == e.oid } + + if subject_alt_name then + /\Aemail:/ =~ subject_alt_name.value + + $' || subject_alt_name.value + else + cert.subject + end + end + ## # Loads any missing issuers in the cert chain from the trusted certificates. # @@ -89,7 +105,9 @@ class Gem::Security::Signer re_sign_key end - Gem::Security::SigningPolicy.verify @cert_chain, @key + full_name = extract_name @cert_chain.last + + Gem::Security::SigningPolicy.verify @cert_chain, @key, {}, {}, full_name @key.sign @digest_algorithm.new, data end diff --git a/lib/rubygems/source.rb b/lib/rubygems/source.rb index 8322ac33d4..f0e2a597b9 100644 --- a/lib/rubygems/source.rb +++ b/lib/rubygems/source.rb @@ -26,15 +26,17 @@ class Gem::Source def <=>(other) case other - when Gem::Source::Installed, Gem::Source::Local then + when Gem::Source::Installed, + Gem::Source::Local, + Gem::Source::SpecificFile then -1 when Gem::Source then if !@uri return 0 unless other.uri - return -1 + return 1 end - return 1 if !other.uri + return -1 if !other.uri @uri.to_s <=> other.uri.to_s else @@ -158,3 +160,5 @@ class Gem::Source end require 'rubygems/source/installed' +require 'rubygems/source/specific_file' +require 'rubygems/source/local' diff --git a/lib/rubygems/source/local.rb b/lib/rubygems/source/local.rb index 7392ff0e8e..642dda1e44 100644 --- a/lib/rubygems/source/local.rb +++ b/lib/rubygems/source/local.rb @@ -1,8 +1,8 @@ -require 'rubygems/source' - class Gem::Source::Local < Gem::Source def initialize - @uri = nil + @specs = nil + @api_uri = nil + @uri = nil end ## @@ -22,7 +22,8 @@ class Gem::Source::Local < Gem::Source end def inspect # :nodoc: - "#<%s specs: %p>" % [self.class, @specs.keys] + keys = @specs ? @specs.keys.sort : 'NOT LOADED' + "#<%s specs: %p>" % [self.class, keys] end def load_specs(type) diff --git a/lib/rubygems/source/specific_file.rb b/lib/rubygems/source/specific_file.rb index d296e617cc..8d328b38c2 100644 --- a/lib/rubygems/source/specific_file.rb +++ b/lib/rubygems/source/specific_file.rb @@ -25,4 +25,32 @@ class Gem::Source::SpecificFile < Gem::Source raise Gem::Exception, "Unable to download '#{spec.full_name}'" end + def pretty_print q # :nodoc: + q.group 2, '[Local:', ']' do + q.breakable + q.text @path + end + end + + ## + # Orders this source against +other+. + # + # If +other+ is a SpecificFile from a different gem name +nil+ is returned. + # + # If +other+ is a SpecificFile from the same gem name the versions are + # compared using Gem::Version#<=> + # + # Otherwise Gem::Source#<=> is used. + + def <=> other + case other + when Gem::Source::SpecificFile then + return nil if @spec.name != other.spec.name + + @spec.version <=> other.spec.version + else + super + end + end + end diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb index d2d48c8501..49cf25d772 100644 --- a/lib/rubygems/specification.rb +++ b/lib/rubygems/specification.rb @@ -206,15 +206,19 @@ class Gem::Specification < Gem::BasicSpecification attr_reader :version ## - # Paths in the gem to add to $LOAD_PATH when this gem is activated. + # Paths in the gem to add to $LOAD_PATH when this gem is + # activated. + # + # If you have an extension you do not need to add "ext" to the + # require path, the extension build process will copy the extension files + # into "lib" for you. + # + # The default value is "lib" # # Usage: # # # If all library files are in the root directory... # spec.require_path = '.' - # - # # If you have 'lib' and 'ext' directories... - # spec.require_paths << 'ext' attr_accessor :require_paths @@ -228,7 +232,7 @@ class Gem::Specification < Gem::BasicSpecification ## # A short summary of this gem's description. Displayed in `gem list -d`. # - # The description should be more detailed than the summary. + # The #description should be more detailed than the summary. # # Usage: # @@ -241,21 +245,23 @@ class Gem::Specification < Gem::BasicSpecification # # This is usually Gem::Platform::RUBY or Gem::Platform::CURRENT. # - # Most gems contain pure Ruby code; they should simply leave the default value - # in place. Some gems contain C (or other) code to be compiled into a Ruby - # “extension”. The should leave the default value in place unless their code - # will only compile on a certain type of system. Some gems consist of - # pre-compiled code (“binary gems”). It’s especially important that they set - # the platform attribute appropriately. A shortcut is to set the platform to - # Gem::Platform::CURRENT, which will cause the gem builder to set the platform - # to the appropriate value for the system on which the build is being performed. + # Most gems contain pure Ruby code; they should simply leave the default + # value in place. Some gems contain C (or other) code to be compiled into a + # Ruby "extension". The should leave the default value in place unless + # their code will only compile on a certain type of system. Some gems + # consist of pre-compiled code ("binary gems"). It's especially important + # that they set the platform attribute appropriately. A shortcut is to set + # the platform to Gem::Platform::CURRENT, which will cause the gem builder + # to set the platform to the appropriate value for the system on which the + # build is being performed. # - # If this attribute is set to a non-default value, it will be included in the - # filename of the gem when it is built, e.g. fxruby-1.2.0-win32.gem. + # If this attribute is set to a non-default value, it will be included in + # the filename of the gem when it is built such as: + # nokogiri-1.6.0-x86-mingw32.gem # # Usage: # - # spec.platform = Gem::Platform::Win32 + # spec.platform = Gem::Platform.local def platform= platform if @original_platform.nil? or @@ -357,7 +363,7 @@ class Gem::Specification < Gem::BasicSpecification attr_reader :description ## - # A contact email for this gem + # A contact email address (or addresses) for this gem # # Usage: # @@ -473,6 +479,8 @@ class Gem::Specification < Gem::BasicSpecification # Usage: # # spec.extensions << 'ext/rmagic/extconf.rb' + # + # See Gem::Ext::Builder for information about writing extensions for gems. def extensions @extensions ||= [] @@ -502,6 +510,8 @@ class Gem::Specification < Gem::BasicSpecification # 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. # + # You can set multiple licenses with #licenses= + # # Usage: # spec.license = 'MIT' @@ -538,15 +548,20 @@ class Gem::Specification < Gem::BasicSpecification end ## - # The version of Ruby required by this gem + # The version of Ruby required by this gem. The ruby version can be + # specified to the patch-level: + # + # $ ruby -v -e 'p Gem.ruby_version' + # ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0] + # # # # Usage: # - # # If it will work with 1.8.6 or greater... + # # This gem will work with 1.8.6 or greater... # spec.required_ruby_version = '>= 1.8.6' # - # # Hopefully by now: - # spec.required_ruby_version = '>= 1.9.2' + # # Only with ruby 2.0.x + # spec.required_ruby_version = '~> 2.0' def required_ruby_version= req @required_ruby_version = Gem::Requirement.create req @@ -554,7 +569,7 @@ class Gem::Specification < Gem::BasicSpecification ## # Lists the external (to RubyGems) requirements that must be met for this gem - # to work. It’s simply information for the user. + # to work. It's simply information for the user. # # Usage: # @@ -566,7 +581,7 @@ class Gem::Specification < Gem::BasicSpecification end ## - # A collection of unit test files. They will be loaded as unit tests when + # A collection of unit test files. They will be loaded as unit tests when # the user requests a gem to be unit tested. # # Usage: @@ -592,7 +607,7 @@ class Gem::Specification < Gem::BasicSpecification # # Deprecated: It is neither supported nor functional. - attr_accessor :autorequire + attr_accessor :autorequire # :nodoc: ## # Sets the default executable for this gem. @@ -615,9 +630,12 @@ class Gem::Specification < Gem::BasicSpecification # 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". + # + # This option is deprecated. attr_accessor :rubyforge_project @@ -768,7 +786,7 @@ class Gem::Specification < Gem::BasicSpecification # -- wilsonb def self.all= specs - @@all = specs + @@all = @@stubs = specs end ## @@ -1320,7 +1338,7 @@ class Gem::Specification < Gem::BasicSpecification end ## - # Singular reader for #authors + # Singular reader for #authors. Returns the first author in the list def author val = authors and val.first @@ -1328,6 +1346,8 @@ class Gem::Specification < Gem::BasicSpecification ## # The list of author names who wrote this gem. + # + # spec.authors = ['Chad Fowler', 'Jim Weirich', 'Rich Kilmer'] def authors @authors ||= [] @@ -1407,7 +1427,9 @@ class Gem::Specification < Gem::BasicSpecification end ## - # The date this gem was created. Lazily defaults to TODAY. + # The date this gem was created. Lazily defaults to the current UTC date. + # + # There is no need to set this in your gem specification. def date @date ||= TODAY @@ -1454,7 +1476,7 @@ class Gem::Specification < Gem::BasicSpecification # Deprecated: The name of the gem is assumed to be the name of the # executable now. See Gem.bin_path. - def default_executable + def default_executable # :nodoc: if defined?(@default_executable) and @default_executable result = @default_executable elsif @executables and @executables.size == 1 @@ -1513,7 +1535,7 @@ class Gem::Specification < Gem::BasicSpecification end ## - # A long description of this gem + # A detailed description of this gem. See also #summary def description= str @description = str.to_s @@ -1672,7 +1694,7 @@ class Gem::Specification < Gem::BasicSpecification # # Formerly used to indicate this gem was RDoc-capable. - def has_rdoc + def has_rdoc # :nodoc: true end @@ -1681,11 +1703,11 @@ class Gem::Specification < Gem::BasicSpecification # # Formerly used to indicate this gem was RDoc-capable. - def has_rdoc= ignored + def has_rdoc= ignored # :nodoc: @has_rdoc = true end - alias :has_rdoc? :has_rdoc + alias :has_rdoc? :has_rdoc # :nodoc: ## # True if this gem has files in test_files @@ -1818,7 +1840,7 @@ class Gem::Specification < Gem::BasicSpecification @licenses ||= [] end - def filename= path + def loaded_from= path # :nodoc: super @bin_dir = nil @@ -1831,17 +1853,6 @@ class Gem::Specification < Gem::BasicSpecification @spec_file = nil end - ## - # Path this gemspec was loaded from. This attribute is not persisted. - - alias loaded_from filename - - ## - # Set the location a Specification was loaded from. +obj+ is converted - # to a String. - - alias loaded_from= filename= - ## # Sets the rubygems_version to the current RubyGems version. diff --git a/lib/rubygems/stub_specification.rb b/lib/rubygems/stub_specification.rb index c2910c1bba..08102b48ef 100644 --- a/lib/rubygems/stub_specification.rb +++ b/lib/rubygems/stub_specification.rb @@ -1,119 +1,120 @@ -module Gem - # Gem::StubSpecification reads the stub: line from the gemspec - # This prevents us having to eval the entire gemspec in order to - # find out certain information. - class StubSpecification < BasicSpecification - # :nodoc: - PREFIX = "# stub: " - - OPEN_MODE = # :nodoc: - if Object.const_defined? :Encoding then - 'r:UTF-8:-' - else - 'r' - end - - # :nodoc: - class StubLine - attr_reader :parts +## +# Gem::StubSpecification reads the stub: line from the gemspec. This prevents +# us having to eval the entire gemspec in order to find out certain +# information. + +class Gem::StubSpecification < Gem::BasicSpecification + # :nodoc: + PREFIX = "# stub: " + + OPEN_MODE = # :nodoc: + if Object.const_defined? :Encoding then + 'r:UTF-8:-' + else + 'r' + end - def initialize(data) - @parts = data[PREFIX.length..-1].split(" ") - end + class StubLine # :nodoc: all + attr_reader :parts - def name - @parts[0] - end + def initialize(data) + @parts = data[PREFIX.length..-1].split(" ") + end - def version - Gem::Version.new @parts[1] - end + def name + @parts[0] + end - def platform - Gem::Platform.new @parts[2] - end + def version + Gem::Version.new @parts[1] + end - def require_paths - @parts[3..-1].join(" ").split("\0") - end + def platform + Gem::Platform.new @parts[2] end - def initialize(filename) - self.filename = filename - @data = nil - @spec = nil + def require_paths + @parts[3..-1].join(" ").split("\0") end + end - ## - # Name of the gem + def initialize(filename) + self.loaded_from = filename + @data = nil + @spec = nil + end - def name - @name ||= data.name - end + ## + # True when this gem has been activated - ## - # Version of the gem + def activated? + loaded = Gem.loaded_specs[name] + loaded && loaded.version == version + end - def version - @version ||= data.version + ## + # If the gemspec contains a stubline, returns a StubLine instance. Otherwise + # returns the full Gem::Specification. + + def data + unless @data + open loaded_from, OPEN_MODE do |file| + begin + file.readline # discard encoding line + stubline = file.readline.chomp + @data = StubLine.new(stubline) if stubline.start_with?(PREFIX) + rescue EOFError + end + end end - ## - # Platform of the gem + @data ||= to_spec + end - def platform - @platform ||= data.platform - end + private :data - ## - # Require paths of the gem + ## + # Name of the gem - def require_paths - @require_paths ||= data.require_paths - end + def name + @name ||= data.name + end - ## - # The full Gem::Specification for this gem, loaded from evalling its gemspec + ## + # Platform of the gem - def to_spec - @spec ||= Gem::Specification.load(filename) - end + def platform + @platform ||= data.platform + end - ## - # True when this gem has been activated + ## + # Require paths of the gem - def activated? - loaded = Gem.loaded_specs[name] - loaded && loaded.version == version - end + def require_paths + @require_paths ||= data.require_paths + end - ## - # Is this StubSpecification valid? i.e. have we found a stub line, OR does - # the filename contain a valid gemspec? + ## + # The full Gem::Specification for this gem, loaded from evalling its gemspec - def valid? - data - end + def to_spec + @spec ||= Gem::Specification.load(loaded_from) + end - private - - ## - # If the gemspec contains a stubline, returns a StubLine instance. Otherwise - # returns the full Gem::Specification. - - def data - unless @data - open filename, OPEN_MODE do |file| - begin - file.readline # discard encoding line - stubline = file.readline.chomp - @data = StubLine.new(stubline) if stubline.start_with?(PREFIX) - rescue EOFError - end - end - end + ## + # Is this StubSpecification valid? i.e. have we found a stub line, OR does + # the filename contain a valid gemspec? - @data ||= to_spec - end + def valid? + data end + + ## + # Version of the gem + + def version + @version ||= data.version + end + end + diff --git a/lib/rubygems/test_case.rb b/lib/rubygems/test_case.rb index 2ae8ec9a2c..5d59e35403 100644 --- a/lib/rubygems/test_case.rb +++ b/lib/rubygems/test_case.rb @@ -785,7 +785,7 @@ Also, a list: @a_evil9 = quick_gem('a_evil', '9', &init) @b2 = quick_gem('b', '2', &init) @c1_2 = quick_gem('c', '1.2', &init) - @x = quick_gem('x', '1', &init) + @x = quick_gem('x', '1', &init) @dep_x = quick_gem('dep_x', '1') do |s| s.files = %w[lib/code.rb] s.require_paths = %w[lib] @@ -805,14 +805,15 @@ Also, a list: util_build_gem @a2_pre end - write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@x.original_name} lib code.rb]) - write_file File.join(*%W[gems #{@dep_x.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a_evil9.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@x.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@dep_x.original_name} lib code.rb]) [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1, @x, @dep_x].each do |spec| util_build_gem spec diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 0ee8d36f8e..38a63c3b2c 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -1181,6 +1181,28 @@ class TestGem < Gem::TestCase assert_equal nil, Gem.find_unresolved_default_spec("README") end + def test_default_gems_use_full_paths + begin + engine = RUBY_ENGINE + Object.send :remove_const, :RUBY_ENGINE + Object.const_set :RUBY_ENGINE, 'ruby' + refute Gem.default_gems_use_full_paths? + ensure + Object.send :remove_const, :RUBY_ENGINE + Object.const_set :RUBY_ENGINE, engine + end + + begin + engine = RUBY_ENGINE + Object.send :remove_const, :RUBY_ENGINE + Object.const_set :RUBY_ENGINE, 'jruby' + assert Gem.default_gems_use_full_paths? + ensure + Object.send :remove_const, :RUBY_ENGINE + Object.const_set :RUBY_ENGINE, engine + end + end + def with_plugin(path) test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}", @@project_dir) diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index 5a11948ee6..9ba1371b79 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -191,21 +191,30 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase end def test_execute_all - ui = Gem::MockGemUi.new "y\n" - util_make_gems - util_setup_gem ui - assert Gem::Specification.find_all_by_name('a').length > 1 + default = new_default_spec 'default', '1' + install_default_gems default + + gemhome2 = "#{@gemhome}2" + + a_4 = quick_spec 'a', 4 + install_gem a_4, :install_dir => gemhome2 + + Gem::Specification.dirs = [@gemhome, gemhome2] + + assert_includes Gem::Specification.all_names, 'a-1' + assert_includes Gem::Specification.all_names, 'a-4' + assert_includes Gem::Specification.all_names, 'default-1' @cmd.options[:all] = true @cmd.options[:args] = [] - use_ui ui do + use_ui @ui do @cmd.execute end - refute_includes Gem::Specification.all_names, 'a' + assert_equal %w[a-4 default-1], Gem::Specification.all_names.sort end end diff --git a/test/rubygems/test_gem_package_task.rb b/test/rubygems/test_gem_package_task.rb index 35b38cdbc7..1526e825fe 100644 --- a/test/rubygems/test_gem_package_task.rb +++ b/test/rubygems/test_gem_package_task.rb @@ -4,16 +4,37 @@ require 'rubygems/package_task' class TestGemPackageTask < Gem::TestCase + def setup + super + + Rake.application = Rake::Application.new + RakeFileUtils.verbose_flag = false + end + def test_gem_package gem = Gem::Specification.new do |g| g.name = "pkgr" g.version = "1.2.3" - g.files = Rake::FileList["x"].resolve + + g.authors = %w[author] + g.files = %w[x] + g.summary = 'summary' end + pkg = Gem::PackageTask.new(gem) do |p| p.package_files << "y" end - assert_equal ["x", "y"], pkg.package_files + + assert_equal %w[x y], pkg.package_files + + Dir.chdir @tempdir do + FileUtils.touch 'x' + FileUtils.touch 'y' + + Rake.application['package'].invoke + + assert_path_exists 'pkg/pkgr-1.2.3.gem' + end end def test_gem_package_with_current_platform diff --git a/test/rubygems/test_gem_security_policy.rb b/test/rubygems/test_gem_security_policy.rb index 5b960c4d48..a2115e709a 100644 --- a/test/rubygems/test_gem_security_policy.rb +++ b/test/rubygems/test_gem_security_policy.rb @@ -351,6 +351,17 @@ class TestGemSecurityPolicy < Gem::TestCase end end + def test_verify_no_signatures_no_digests + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + use_ui @ui do + @no.verify [PUBLIC_CERT], nil, {}, {}, 'some_gem' + end + + assert_empty @ui.output + assert_empty @ui.error + end + def test_verify_not_enough_signatures Gem::Security.trust_dir.trust_cert PUBLIC_CERT diff --git a/test/rubygems/test_gem_security_signer.rb b/test/rubygems/test_gem_security_signer.rb index c984382947..f077a46413 100644 --- a/test/rubygems/test_gem_security_signer.rb +++ b/test/rubygems/test_gem_security_signer.rb @@ -84,6 +84,12 @@ class TestGemSecuritySigner < Gem::TestCase assert_equal ENCRYPTED_PRIVATE_KEY.to_s, signer.key.to_s end + def test_extract_name + signer = Gem::Security::Signer.new nil, nil + + assert_equal 'child@example', signer.extract_name(CHILD_CERT) + end + def test_load_cert_chain Gem::Security.trust_dir.trust_cert PUBLIC_CERT diff --git a/test/rubygems/test_gem_source.rb b/test/rubygems/test_gem_source.rb index 1303978a8e..cb43121ddd 100644 --- a/test/rubygems/test_gem_source.rb +++ b/test/rubygems/test_gem_source.rb @@ -184,5 +184,28 @@ class TestGemSource < Gem::TestCase end end + def test_spaceship + remote = @source + specific = Gem::Source::SpecificFile.new(@a1.cache_file) + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + + assert_equal( 0, remote. <=>(remote), 'remote <=> remote') + + assert_equal(-1, remote. <=>(specific), 'remote <=> specific') + assert_equal( 1, specific. <=>(remote), 'specific <=> remote') + + assert_equal(-1, remote. <=>(local), 'remote <=> local') + assert_equal( 1, local. <=>(remote), 'local <=> remote') + + assert_equal(-1, remote. <=>(installed), 'remote <=> installed') + assert_equal( 1, installed.<=>(remote), 'installed <=> remote') + + no_uri = @source.dup + no_uri.instance_variable_set :@uri, nil + + assert_equal(-1, remote. <=>(no_uri), 'remote <=> no_uri') + end + end diff --git a/test/rubygems/test_gem_source_installed.rb b/test/rubygems/test_gem_source_installed.rb new file mode 100644 index 0000000000..1119ad0c2b --- /dev/null +++ b/test/rubygems/test_gem_source_installed.rb @@ -0,0 +1,28 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +class TestGemSourceInstalled < Gem::TestCase + + def test_spaceship + a1 = quick_gem 'a', '1' + util_build_gem a1 + + remote = Gem::Source.new @gem_repo + 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') + + assert_equal(-1, remote. <=>(installed), 'remote <=> installed') + assert_equal( 1, installed.<=>(remote), 'installed <=> remote') + + assert_equal( 1, installed.<=>(local), 'installed <=> local') + assert_equal(-1, local. <=>(installed), 'local <=> installed') + + assert_equal(-1, specific. <=>(installed), 'specific <=> installed') + assert_equal( 1, installed.<=>(specific), 'installed <=> specific') + end + +end + diff --git a/test/rubygems/test_gem_source_local.rb b/test/rubygems/test_gem_source_local.rb index 8e901cfd21..b3b444ccde 100644 --- a/test/rubygems/test_gem_source_local.rb +++ b/test/rubygems/test_gem_source_local.rb @@ -66,18 +66,41 @@ class TestGemSourceLocal < Gem::TestCase assert_equal s, @a end + def test_inspect + assert_equal '#', @sl.inspect + + @sl.load_specs :released + + inner = [@a, @ap, @b].map { |t| t.name_tuple }.inspect + + assert_equal "#", @sl.inspect + end + def test_download path = @sl.download @a assert_equal File.expand_path(@a.file_name), path end - def test_compare - uri = URI.parse "http://gems.example/foo" - s = Gem::Source.new uri + def test_spaceship + a1 = quick_gem 'a', '1' + util_build_gem a1 - assert_equal(-1, s <=> @sl) - assert_equal 0, @sl <=> @sl - assert_equal 1, @sl <=> s + remote = Gem::Source.new @gem_repo + specific = Gem::Source::SpecificFile.new a1.cache_file + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + + assert_equal( 0, local. <=>(local), 'local <=> local') + + assert_equal(-1, remote. <=>(local), 'remote <=> local') + assert_equal( 1, local. <=>(remote), 'local <=> remote') + + assert_equal( 1, installed.<=>(local), 'installed <=> local') + assert_equal(-1, local. <=>(installed), 'local <=> installed') + + assert_equal(-1, specific. <=>(local), 'specific <=> local') + assert_equal( 1, local. <=>(specific), 'local <=> specific') end + end diff --git a/test/rubygems/test_gem_source_specific_file.rb b/test/rubygems/test_gem_source_specific_file.rb index 1d8351781f..8ccbe50c91 100644 --- a/test/rubygems/test_gem_source_specific_file.rb +++ b/test/rubygems/test_gem_source_specific_file.rb @@ -30,4 +30,42 @@ class TestGemSourceSpecificFile < Gem::TestCase def test_download assert_equal @a_gem, @sf.download(@a) end + + def test_spaceship + a1 = quick_gem 'a', '1' + util_build_gem a1 + + remote = Gem::Source.new @gem_repo + specific = Gem::Source::SpecificFile.new a1.cache_file + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + + assert_equal( 0, specific. <=>(specific), 'specific <=> specific') + + assert_equal(-1, remote. <=>(specific), 'remote <=> specific') + assert_equal( 1, specific. <=>(remote), 'specific <=> remote') + + assert_equal(-1, specific. <=>(local), 'specific <=> local') + assert_equal( 1, local. <=>(specific), 'local <=> specific') + + assert_equal(-1, specific. <=>(installed), 'specific <=> installed') + assert_equal( 1, installed.<=>(specific), 'installed <=> specific') + + a2 = quick_gem 'a', '2' + util_build_gem a2 + + b1 = quick_gem 'b', '1' + util_build_gem b1 + + a1_source = specific + a2_source = Gem::Source::SpecificFile.new a2.cache_file + b1_source = Gem::Source::SpecificFile.new b1.cache_file + + assert_nil a1_source.<=>(b1_source), 'a1_source <=> b1_source' + + assert_equal(-1, a1_source.<=>(a2_source), 'a1_source <=> a2_source') + assert_equal( 0, a1_source.<=>(a1_source), 'a1_source <=> a1_source') + assert_equal( 1, a2_source.<=>(a1_source), 'a2_source <=> a1_source') + end + end diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index dce7ad260b..efda6f6f19 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -445,6 +445,14 @@ end end end + def test_self_all_equals + a = new_spec "foo", "1", nil, "lib/foo.rb" + + Gem::Specification.all = [a] + + assert_equal a, Gem::Specification.find_inactive_by_path('foo') + end + def test_self_attribute_names expected_value = %w[ authors @@ -1313,7 +1321,7 @@ dependencies: [] end def test_base_dir_not_loaded - @a1.instance_variable_set :@filename, nil + @a1.instance_variable_set :@loaded_from, nil assert_equal Gem.dir, @a1.base_dir end @@ -1322,7 +1330,7 @@ dependencies: [] default_dir = File.join Gem::Specification.default_specifications_dir, @a1.spec_name - @a1.instance_variable_set :@filename, default_dir + @a1.instance_variable_set :@loaded_from, default_dir assert_equal Gem.default_dir, @a1.base_dir end -- cgit v1.2.3