1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/rubygems: update to 1.3.6.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26728 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2010-02-22 02:52:35 +00:00
parent 65544f575b
commit b551e8c8b3
119 changed files with 2735 additions and 2613 deletions

View file

@ -1,3 +1,7 @@
Mon Feb 22 11:52:30 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/rubygems: update to 1.3.6.
Mon Feb 22 11:21:18 2010 Nobuyoshi Nakada <nobu@ruby-lang.org> Mon Feb 22 11:21:18 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/digest/sha2: Use OpenSSL's SHA1 engine if available. * ext/digest/sha2: Use OpenSSL's SHA1 engine if available.

View file

@ -1,5 +1,149 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
2010-02-20 Eric Hodel <drbrain@segment7.net>
* lib/rubygems.rb: 1.3.6.
* test/*: Windows test fixes
* lib/rubygems/remote_fetcher.rb: Fix same file detection on windows.
2010-02-15 Eric Hodel <drbrain@segment7.net>
* lib/rubygems/config_file.rb: Fix use of ConfigFile#api_key= vs
#rubygems_api_key=. Patch by Nick Quaranto.
2010-02-12 Eric Hodel <drbrain@segment7.net>
* Rakefile: RubyGems doesn't depend on previous RubyGems.
2010-02-11 Eric Hodel <drbrain@segment7.net>
* lib/rubygems.rb: http://rubygems.org is now the default source.
* lib/rubygems/dependency.rb: Only warn once about
#version_requirement
2010-02-09 Eric Hodel <drbrain@segment7.net>
* bin/update_rubygems: Use system, exec more correctly, remove
useless puts.
* lib/rubygems/commands/query_command.rb: List every version when
--prerelease --all is given.
2010-02-08 Eric Hodel <drbrain@segment7.net>
* lib/rubygems/commands/dependency_command.rb: Support --prerelease.
* lib/rubygems/commands/fetch_command.rb: Support --prerelease.
* lib/rubygems/format.rb: Don't crash on empty files. Bug #27292 by
Ian Ragsdale.
* lib/rubygems/server.rb: Fix markup. Bug #27045 by Eric Young.
* History.txt: RubyGems 1.3.6 release notes.
2010-02-07 Eric Hodel <drbrain@segment7.net>
* lib/rubygems/dependency_installer.rb: Allow prerelease gems to
depend on non-prerelease gems.
2010-02-06 Eric Hodel <drbrain@segment7.net>
* test/test_gem_commands_specification_command.rb: Don't enforce YAML
format. Patch #27791 by Aaron Patterson.
* lib/rubygems/version.rb: Allow captial letters in prerelease
versions.
* lib/rubygems/config_file.rb: Explain format of ~/.gemrc. Bug
#27698 by J Smith.
* lib/rubygems/gem_path_searcher.rb: Handle nil require_paths.
Patch #27334 by Roger Pack.
* lib/rubygems/server.rb: Handle --bind option. Patch #27357 by
Bruno Michel.
* lib/rubygems/doc_manager: gem rdoc --overwrite to preserve built
rdoc. Patch #25982 by Akinori MUSHA.
* lib/rubygems/commands/which_command.rb: Fail if no paths were
found. Adapted patch #27681 by Caio Chassot.
* lib/rubygems/remote_fetcher.rb: Don't copy if the file is where we
want it. Patch #27409 by Jakub Šťastný.
2010-02-01 John Barnette <jbarnette@rubygems.org>
* lib/rubygems/command*: Add 'gem push' and 'gem owner' for
interacting with modern/Gemcutter sources [Nick Quaranto]
2010-01-18 Eric Hodel <drbrain@segment7.net>
* lib/rubygems/dependency_list.rb: Ignore development dependencies
unless explicitly needed. Bug #27608 by Roger Pack.
2010-01-12 John Barnette <jbarnette@rubygems.org>
* Rakefile: Don't add development deps when building the
rubygems-update gem, it borks older versions when they're updating
from a stub index.
2009-12-22 Evan Phoenix <evan@fallingsnow.net>
* lib/rubygems/spec_fetcher.rb: Don't bother re-Marshaling the spec
YAML list.
2009-11-04 John Barnette <jbarnette@rubygems.org>
* lib/rubygems/timer.rb: Removed. The deprecation sun set in July.
2009-10-14 John Barnette <jbarnette@rubygems.org>
* lib/rubygems/dependency.rb: Burndown/cleanup. Refactored code
and tests. Gem::Dependency.version_requirement(s) is deprecated in
favor of Gem::Dependency.requirement.
* lib/rubygems/requirement.rb: Burndown/cleanup. Refactored code
and tests. See test/support/shortcuts.rb for some new test helpers.
2009-10-13 John Barnette <jbarnette@rubygems.org>
* lib/rubygems/local_remote_options.rb: Make --source additive,
not exclusive. If exclusive sources are desired, use
--clear-sources first.
2009-09-29 John Barnette <jbarnette@rubyforge.org>
* lib/rubygems/spec_fetcher.rb: Be slightly more robust when faced
with corrupted indexes.
2009-09-03 John Barnette <jbarnette@rubyforge.org>
* LOTS: Use "raise" consistently, not "fail".
2009-09-01 John Barnette <jbarnette@rubyforge.org>
* lib/rubygems/version.rb: Gem::Version immutability
burndown. Changed canonical internal representation to an
Array. Refactored significant amounts of the internals for
clarity. Breaking change: Gem::Version::Requirement is no longer
available, use Gem::Requirement instead. Breaking change: custom
YAML marshaling is gone. Credit to Yehuda Katz for certain bits of
a related patch.
* test/test_gem_dependency.rb: Moved a bunch of tests over from
test_gem_version.rb. Work in progress.
* test/test_gem_specification.rb: Removed a failing YAML
test. Many more will be going away shortly.
* test/test_gem_version.rb: Significant refactoring for
maintainability and clarity. Moved a ton of poorly-placed tests to
test_gem_dependency.rb for future refactoring.
2009-08-19 Ryan Davis <ryand-ruby@zenspider.com>
* lib/rubygems.rb: Cleanup of rdoc and file layout.
* lib/rubygems/versions.rb: Added Version#spermy_recommendation
and fixed bug in Version::Part#inspect. General cleanup.
2009-07-29 John Barnette <jbarnette@rubyforge.org>
* lib/rubygems/package/tar_input.rb: Add Maglev to the list of
implementations with working Zlib. Bug #26790 by Peter McLain.
2009-07-21 Eric Hodel <drbrain@segment7.net>
* lib/rubygems.rb: 1.3.5.
* lib/rubygems/package.rb: Remove dangling digest require. Reported
by Jeremy Kemper.
2009-06-25 Eric Hodel <drbrain@segment7.net> 2009-06-25 Eric Hodel <drbrain@segment7.net>
* release_notes/: Merged into History.txt for Hoe. * release_notes/: Merged into History.txt for Hoe.
@ -8,6 +152,8 @@
2009-06-23 Eric Hodel <drbrain@segment7.net> 2009-06-23 Eric Hodel <drbrain@segment7.net>
* release_notes/rel_1_3_5.rdoc: RubyGems 1.3.5 release notes. * release_notes/rel_1_3_5.rdoc: RubyGems 1.3.5 release notes.
* lib/rubygems/builder.rb: Only print out with verbose.
* lib/rubygems/package_task.rb: Only print out with -t.
2009-06-12 Ryan Davis <ryand@zenspider.com> 2009-06-12 Ryan Davis <ryand@zenspider.com>
@ -15,8 +161,26 @@
2009-06-10 Phil Hagelberg <technomancy@gmail.com> 2009-06-10 Phil Hagelberg <technomancy@gmail.com>
* lib/rubygems/installer.rb: --user-install is no longer enabled by
default.
* lib/rubygems/source_index.rb: Fix use of prerelease gems. * lib/rubygems/source_index.rb: Fix use of prerelease gems.
2009-06-04 Eric Hodel <drbrain@segment7.net>
* util/gem_prelude.rb.template: Backports from 1.9.
2009-06-03 Eric Hodel <drbrain@segment7.net>
* bin/gem: Support 1.8.6+
* lib/rubygems/digest*: Removed, support dropped for Ruby < 1.8.6
* lib/rubygems/installer.rb: Support env(1) in wrong path, use
/bin/sh if shebang has options. By Nobu, ruby trunk r22853.
* lib/rubygems/config_file.rb: Switch to stdcall for appdata folder.
[ruby-core:22601].
* lib/rubygems.rb: Use only File::expand_path on 1.9 for home dir.
Don't recklessly create directories. Simplify RbConfig::datadir
definition.
2009-05-30 Eric Hodel <drbrain@segment7.net> 2009-05-30 Eric Hodel <drbrain@segment7.net>
* lib/rubygems/commands/which_command.rb: Only print out directory * lib/rubygems/commands/which_command.rb: Only print out directory

View file

@ -1,4 +1,57 @@
=== 1.3.5 / 2009-07-21 # -*- coding: utf-8 -*-
=== 1.3.6 / 2010-02-17
NOTE:
http://rubygems.org is now the default source for downloading gems.
You may have sources set via ~/.gemrc, so you should replace
http://gems.rubyforge.org with http://rubygems.org
http://gems.rubyforge.org will continue to work for the forseeable future.
New features:
* `gem` commands
* Added `gem push` and `gem owner` for interacting with modern/Gemcutter
sources
* `gem dep` now supports --prerelease.
* `gem fetch` now supports --prerelease.
* `gem server` now supports --bind. Patch #27357 by Bruno Michel.
* `gem rdoc` no longer overwrites built documentation. Use --overwrite
force rebuilding. Patch #25982 by Akinori MUSHA.
* Captial letters are now allowed in prerelease versions.
Bug fixes:
* Development deps are no longer added to rubygems-update gem so older
versions can update sucessfully.
* Installer bugs:
* Prerelease gems can now depend on non-prerelease gems.
* Development dependencies are ignored unless explicitly needed. Bug #27608
by Roger Pack.
* `gem` commands
* `gem which` now fails if no paths were found. Adapted patch #27681 by
Caio Chassot.
* `gem server` no longer has invalid markup. Bug #27045 by Eric Young.
* `gem list` and friends show both prerelease and regular gems when
--prerelease --all is given
* Gem::Format no longer crashes on empty files. Bug #27292 by Ian Ragsdale.
* Gem::GemPathSearcher handles nil require_paths. Patch #27334 by Roger Pack.
* Gem::RemoteFetcher no longer copies the file if it is where we want it.
Patch #27409 by Jakub Šťastný.
Deprecation Notices:
* lib/rubygems/timer.rb has been removed.
* Gem::Dependency#version_requirements is deprecated and will be removed on or
after August 2010.
* Bulk index update is no longer supported.
* Gem::manage_gems was removed in 1.3.3.
* Time::today was removed in 1.3.3.
=== 1.3.5 / 2009-07-21
Bug fixes: Bug fixes:

View file

@ -1,8 +1,9 @@
= RubyGems = RubyGems
* http://rubygems.org/
* http://docs.rubygems.org/
* http://rubygems.rubyforge.org/ * http://rubygems.rubyforge.org/
* http://rubyforge.org/projects/rubygems * http://rubyforge.org/projects/rubygems
* http://rubygems.org/
== DESCRIPTION == DESCRIPTION
@ -15,7 +16,7 @@ See Gem for information on RubyGems (or `ri Gem`)
To upgrade to the latest RubyGems, run: To upgrade to the latest RubyGems, run:
$ gem install --system # you might need to be an administrator or root $ gem update --system # you might need to be an administrator or root
NOTE: RubyGems 1.1 and 1.2 have problems upgrading when there is no NOTE: RubyGems 1.1 and 1.2 have problems upgrading when there is no
rubygems-update installed. You will need to use the following instructions rubygems-update installed. You will need to use the following instructions

View file

@ -9,71 +9,6 @@ require 'rubygems/defaults'
require 'thread' require 'thread'
require 'etc' require 'etc'
module Gem
RubyGemsVersion = VERSION = '1.3.5'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
# name and version requirements of the gem that either conflicts with
# already activated gems or that RubyGems is otherwise unable to activate.
class LoadError < ::LoadError
##
# Name of gem
attr_accessor :name
##
# Version requirement of gem
attr_accessor :version_requirement
end
end
module Kernel
# defined in gem_prelude.rb
undef gem
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
# +version_requirements+ is a list of version requirements that the
# specified gem must match, most commonly "= example.version.number". See
# Gem::Requirement for how to specify a version requirement.
#
# If you will be activating the latest version of a gem, there is no need to
# call Kernel#gem, Kernel#require will do the right thing for you.
#
# Kernel#gem returns true if the gem was activated, otherwise false. If the
# gem could not be found, didn't match the version requirements, or a
# different version was already activated, an exception will be raised.
#
# 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
# RUBYLIB environment variable to skip activation of a gem.
#
# Example:
#
# GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
def gem(gem_name, *version_requirements) # :doc:
skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
Gem.activate(gem_name, *version_requirements)
end
private :gem
end
## ##
# RubyGems is the Ruby standard for publishing and managing third party # RubyGems is the Ruby standard for publishing and managing third party
# libraries. # libraries.
@ -88,6 +23,7 @@ end
# #
# * {Creating Gems}[http://docs.rubygems.org/read/chapter/5] # * {Creating Gems}[http://docs.rubygems.org/read/chapter/5]
# * Gem::Specification # * Gem::Specification
# * Gem::Version for version dependency notes
# #
# Further RubyGems documentation can be found at: # Further RubyGems documentation can be found at:
# #
@ -98,7 +34,8 @@ end
# == RubyGems Plugins # == RubyGems Plugins
# #
# As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or # As of RubyGems 1.3.2, RubyGems will load plugins installed in gems or
# $LOAD_PATH. Plugins must be named 'rubygems_plugin' are discovered via # $LOAD_PATH. Plugins must be named 'rubygems_plugin' (.rb, .so, etc) and
# placed at the root of your gem's #require_path. Plugins are discovered via
# Gem::find_files then loaded. Take care when implementing a plugin as your # Gem::find_files then loaded. Take care when implementing a plugin as your
# plugin file may be loaded multiple times if multiple versions of your gem # plugin file may be loaded multiple times if multiple versions of your gem
# are installed. # are installed.
@ -124,7 +61,7 @@ end
# == Bugs # == Bugs
# #
# You can submit bugs to the # You can submit bugs to the
# {RubyGems bug tracker}[http://rubyforge.org/tracker/?atid=575&group_id=126&func=browse] # {RubyGems bug tracker}[http://rubyforge.org/tracker/?atid=575&group_id=126]
# on RubyForge # on RubyForge
# #
# == Credits # == Credits
@ -133,26 +70,26 @@ end
# #
# RubyGems was originally developed at RubyConf 2003 by: # RubyGems was originally developed at RubyConf 2003 by:
# #
# * Rich Kilmer -- rich(at)infoether.com # * Rich Kilmer -- rich(at)infoether.com
# * Chad Fowler -- chad(at)chadfowler.com # * Chad Fowler -- chad(at)chadfowler.com
# * David Black -- dblack(at)wobblini.net # * David Black -- dblack(at)wobblini.net
# * Paul Brannan -- paul(at)atdesk.com # * Paul Brannan -- paul(at)atdesk.com
# * Jim Weirch -- {jim(at)weirichhouse.org}[mailto:jim@weirichhouse.org] # * Jim Weirch -- jim(at)weirichhouse.org
# #
# Contributors: # Contributors:
# #
# * Gavin Sinclair -- gsinclair(at)soyabean.com.au # * Gavin Sinclair -- gsinclair(at)soyabean.com.au
# * George Marrows -- george.marrows(at)ntlworld.com # * George Marrows -- george.marrows(at)ntlworld.com
# * Dick Davies -- rasputnik(at)hellooperator.net # * Dick Davies -- rasputnik(at)hellooperator.net
# * Mauricio Fernandez -- batsman.geo(at)yahoo.com # * Mauricio Fernandez -- batsman.geo(at)yahoo.com
# * Simon Strandgaard -- neoneye(at)adslhome.dk # * Simon Strandgaard -- neoneye(at)adslhome.dk
# * Dave Glasser -- glasser(at)mit.edu # * Dave Glasser -- glasser(at)mit.edu
# * Paul Duncan -- pabs(at)pablotron.org # * Paul Duncan -- pabs(at)pablotron.org
# * Ville Aine -- vaine(at)cs.helsinki.fi # * Ville Aine -- vaine(at)cs.helsinki.fi
# * Eric Hodel -- drbrain(at)segment7.net # * Eric Hodel -- drbrain(at)segment7.net
# * Daniel Berger -- djberg96(at)gmail.com # * Daniel Berger -- djberg96(at)gmail.com
# * Phil Hagelberg -- technomancy(at)gmail.com # * Phil Hagelberg -- technomancy(at)gmail.com
# * Ryan Davis # * Ryan Davis -- ryand-ruby(at)zenspider.com
# #
# (If your name is missing, PLEASE let us know!) # (If your name is missing, PLEASE let us know!)
# #
@ -161,6 +98,20 @@ end
# -The RubyGems Team # -The RubyGems Team
module Gem module Gem
RubyGemsVersion = VERSION = '1.3.6'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
# name and version requirements of the gem that either conflicts with
# already activated gems or that RubyGems is otherwise unable to activate.
class LoadError < ::LoadError
# Name of gem
attr_accessor :name
# Version requirement of gem
attr_accessor :version_requirement
end
## ##
# Configuration settings from ::RbConfig # Configuration settings from ::RbConfig
@ -170,19 +121,19 @@ module Gem
require 'rbconfig' require 'rbconfig'
ConfigMap.merge!( ConfigMap.merge!(
:EXEEXT => RbConfig::CONFIG["EXEEXT"], :EXEEXT => RbConfig::CONFIG["EXEEXT"],
:RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"], :RUBY_SO_NAME => RbConfig::CONFIG["RUBY_SO_NAME"],
:arch => RbConfig::CONFIG["arch"], :arch => RbConfig::CONFIG["arch"],
:bindir => RbConfig::CONFIG["bindir"], :bindir => RbConfig::CONFIG["bindir"],
:datadir => RbConfig::CONFIG["datadir"], :datadir => RbConfig::CONFIG["datadir"],
:libdir => RbConfig::CONFIG["libdir"], :libdir => RbConfig::CONFIG["libdir"],
:rubylibprefix => RbConfig::CONFIG["rubylibprefix"], :rubylibprefix => RbConfig::CONFIG["rubylibprefix"],
:ruby_install_name => RbConfig::CONFIG["ruby_install_name"], :ruby_install_name => RbConfig::CONFIG["ruby_install_name"],
:ruby_version => RbConfig::CONFIG["ruby_version"], :ruby_version => RbConfig::CONFIG["ruby_version"],
:sitedir => RbConfig::CONFIG["sitedir"], :sitedir => RbConfig::CONFIG["sitedir"],
:sitelibdir => RbConfig::CONFIG["sitelibdir"], :sitelibdir => RbConfig::CONFIG["sitelibdir"],
:vendordir => RbConfig::CONFIG["vendordir"] , :vendordir => RbConfig::CONFIG["vendordir"] ,
:vendorlibdir => RbConfig::CONFIG["vendorlibdir"] :vendorlibdir => RbConfig::CONFIG["vendorlibdir"]
) )
## ##
@ -253,11 +204,11 @@ module Gem
end end
unless gem.respond_to?(:name) and unless gem.respond_to?(:name) and
gem.respond_to?(:version_requirements) then gem.respond_to?(:requirement) then
gem = Gem::Dependency.new(gem, version_requirements) gem = Gem::Dependency.new(gem, version_requirements)
end end
matches = Gem.source_index.find_name(gem.name, gem.version_requirements) matches = Gem.source_index.find_name(gem.name, gem.requirement)
report_activate_error(gem) if matches.empty? report_activate_error(gem) if matches.empty?
if @loaded_specs[gem.name] then if @loaded_specs[gem.name] then
@ -275,7 +226,7 @@ module Gem
e = Gem::LoadError.new msg e = Gem::LoadError.new msg
e.name = gem.name e.name = gem.name
e.version_requirement = gem.version_requirements e.version_requirement = gem.requirement
raise e raise e
end end
@ -351,7 +302,7 @@ module Gem
requirements = Gem::Requirement.default if requirements.empty? requirements = Gem::Requirement.default if requirements.empty?
unless gem.respond_to?(:name) and unless gem.respond_to?(:name) and
gem.respond_to?(:version_requirements) then gem.respond_to?(:requirement) then
gem = Gem::Dependency.new gem, requirements gem = Gem::Dependency.new gem, requirements
end end
@ -731,14 +682,15 @@ module Gem
# The directory prefix this RubyGems was installed at. # The directory prefix this RubyGems was installed at.
def self.prefix def self.prefix
prefix = File.dirname File.expand_path(__FILE__) dir = File.dirname File.expand_path(__FILE__)
prefix = File.dirname(dir)
if File.dirname(prefix) == File.expand_path(ConfigMap[:sitelibdir]) or if prefix == File.expand_path(ConfigMap[:sitelibdir]) or
File.dirname(prefix) == File.expand_path(ConfigMap[:libdir]) or prefix == File.expand_path(ConfigMap[:libdir]) or
'lib' != File.basename(prefix) then 'lib' != File.basename(dir) then
nil nil
else else
File.dirname prefix prefix
end end
end end
@ -797,15 +749,15 @@ module Gem
if matches.empty? then if matches.empty? then
error = Gem::LoadError.new( error = Gem::LoadError.new(
"Could not find RubyGem #{gem.name} (#{gem.version_requirements})\n") "Could not find RubyGem #{gem.name} (#{gem.requirement})\n")
else else
error = Gem::LoadError.new( error = Gem::LoadError.new(
"RubyGem version error: " + "RubyGem version error: " +
"#{gem.name}(#{matches.first.version} not #{gem.version_requirements})\n") "#{gem.name}(#{matches.first.version} not #{gem.requirement})\n")
end end
error.name = gem.name error.name = gem.name
error.version_requirement = gem.version_requirements error.version_requirement = gem.requirement
raise error raise error
end end
@ -1054,6 +1006,46 @@ module Gem
end end
module Kernel
# defined in gem_prelude.rb
undef gem
##
# Use Kernel#gem to activate a specific version of +gem_name+.
#
# +version_requirements+ is a list of version requirements that the
# specified gem must match, most commonly "= example.version.number". See
# Gem::Requirement for how to specify a version requirement.
#
# If you will be activating the latest version of a gem, there is no need to
# call Kernel#gem, Kernel#require will do the right thing for you.
#
# Kernel#gem returns true if the gem was activated, otherwise false. If the
# gem could not be found, didn't match the version requirements, or a
# different version was already activated, an exception will be raised.
#
# 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
# RUBYLIB environment variable to skip activation of a gem.
#
# Example:
#
# GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
def gem(gem_name, *version_requirements) # :doc:
skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name
Gem.activate(gem_name, *version_requirements)
end
private :gem
end
## ##
# Return the path to the data directory associated with the named package. If # Return the path to the data directory associated with the named package. If
# the package is loaded as a gem, return the gem specific data directory. # the package is loaded as a gem, return the gem specific data directory.
@ -1093,6 +1085,12 @@ Gem.clear_paths
plugins = Gem.find_files 'rubygems_plugin' plugins = Gem.find_files 'rubygems_plugin'
plugins.each do |plugin| plugins.each do |plugin|
# Skip older versions of the GemCutter plugin: Its commands are in
# RubyGems proper now.
next if plugin =~ /gemcutter-0\.[0-3]/
begin begin
load plugin load plugin
rescue => e rescue => e

View file

@ -11,6 +11,7 @@
class Gem::Builder class Gem::Builder
include Gem::UserInteraction include Gem::UserInteraction
## ##
# Constructs a builder instance for the provided specification # Constructs a builder instance for the provided specification
# #
@ -33,7 +34,7 @@ class Gem::Builder
@spec.validate @spec.validate
@signer = sign @signer = sign
write_package write_package
say success say success if Gem.configuration.verbose
@spec.file_name @spec.file_name
end end
@ -42,7 +43,7 @@ class Gem::Builder
Successfully built RubyGem Successfully built RubyGem
Name: #{@spec.name} Name: #{@spec.name}
Version: #{@spec.version} Version: #{@spec.version}
File: #{@spec.full_name+'.gem'} File: #{@spec.file_name}
EOM EOM
end end
@ -86,5 +87,6 @@ EOM
end end
end end
end end
end end

View file

@ -160,8 +160,8 @@ class Gem::Command
end end
## ##
# Get the single gem name from the command line. Fail if there is no gem # Get a single gem name from the command line. Fail if there is no gem name
# name or if there is more than one gem name given. # or if there is more than one gem name given.
def get_one_gem_name def get_one_gem_name
args = options[:args] args = options[:args]
@ -248,11 +248,12 @@ class Gem::Command
# Invoke the command with the given list of arguments. # Invoke the command with the given list of arguments.
def invoke(*args) def invoke(*args)
handle_options(args) handle_options args
if options[:help]
if options[:help] then
show_help show_help
elsif @when_invoked elsif @when_invoked then
@when_invoked.call(options) @when_invoked.call options
else else
execute execute
end end
@ -362,37 +363,39 @@ class Gem::Command
def create_option_parser def create_option_parser
@parser = OptionParser.new @parser = OptionParser.new
@parser.separator("") @parser.separator nil
regular_options = @option_groups.delete :options regular_options = @option_groups.delete :options
configure_options "", regular_options configure_options "", regular_options
@option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list| @option_groups.sort_by { |n,_| n.to_s }.each do |group_name, option_list|
@parser.separator nil
configure_options group_name, option_list configure_options group_name, option_list
end end
@parser.separator nil
configure_options "Common", Gem::Command.common_options configure_options "Common", Gem::Command.common_options
@parser.separator("")
unless arguments.empty? unless arguments.empty?
@parser.separator(" Arguments:") @parser.separator nil
@parser.separator " Arguments:"
arguments.split(/\n/).each do |arg_desc| arguments.split(/\n/).each do |arg_desc|
@parser.separator(" #{arg_desc}") @parser.separator " #{arg_desc}"
end end
@parser.separator("")
end end
@parser.separator(" Summary:") @parser.separator nil
@parser.separator " Summary:"
wrap(@summary, 80 - 4).split("\n").each do |line| wrap(@summary, 80 - 4).split("\n").each do |line|
@parser.separator(" #{line.strip}") @parser.separator " #{line.strip}"
end end
if description then if description then
formatted = description.split("\n\n").map do |chunk| formatted = description.split("\n\n").map do |chunk|
wrap(chunk, 80 - 4) wrap chunk, 80 - 4
end.join("\n") end.join "\n"
@parser.separator "" @parser.separator nil
@parser.separator " Description:" @parser.separator " Description:"
formatted.split("\n").each do |line| formatted.split("\n").each do |line|
@parser.separator " #{line.rstrip}" @parser.separator " #{line.rstrip}"
@ -400,10 +403,10 @@ class Gem::Command
end end
unless defaults_str.empty? unless defaults_str.empty?
@parser.separator("") @parser.separator nil
@parser.separator(" Defaults:") @parser.separator " Defaults:"
defaults_str.split(/\n/).each do |line| defaults_str.split(/\n/).each do |line|
@parser.separator(" #{line}") @parser.separator " #{line}"
end end
end end
end end
@ -471,33 +474,33 @@ class Gem::Command
# :stopdoc: # :stopdoc:
HELP = %{ HELP = <<-HELP
RubyGems is a sophisticated package manager for Ruby. This is a RubyGems is a sophisticated package manager for Ruby. This is a
basic help message containing pointers to more information. basic help message containing pointers to more information.
Usage: Usage:
gem -h/--help gem -h/--help
gem -v/--version gem -v/--version
gem command [arguments...] [options...] gem command [arguments...] [options...]
Examples: Examples:
gem install rake gem install rake
gem list --local gem list --local
gem build package.gemspec gem build package.gemspec
gem help install gem help install
Further help: Further help:
gem help commands list all 'gem' commands gem help commands list all 'gem' commands
gem help examples show some examples of usage gem help examples show some examples of usage
gem help platforms show information about platforms gem help platforms show information about platforms
gem help <COMMAND> show help on COMMAND gem help <COMMAND> show help on COMMAND
(e.g. 'gem help install') (e.g. 'gem help install')
gem server present a web page at gem server present a web page at
http://localhost:8808/ http://localhost:8808/
with info about installed gems with info about installed gems
Further information: Further information:
http://rubygems.rubyforge.org http://rubygems.rubyforge.org
}.gsub(/^ /, '') HELP
# :startdoc: # :startdoc:

View file

@ -58,7 +58,9 @@ class Gem::CommandManager
register_command :lock register_command :lock
register_command :mirror register_command :mirror
register_command :outdated register_command :outdated
register_command :owner
register_command :pristine register_command :pristine
register_command :push
register_command :query register_command :query
register_command :rdoc register_command :rdoc
register_command :search register_command :search

View file

@ -15,6 +15,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
add_version_option add_version_option
add_platform_option add_platform_option
add_prerelease_option
add_option('-R', '--[no-]reverse-dependencies', add_option('-R', '--[no-]reverse-dependencies',
'Include reverse dependencies in the output') do 'Include reverse dependencies in the output') do
@ -59,6 +60,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
end end
dependency = Gem::Dependency.new pattern, options[:version] dependency = Gem::Dependency.new pattern, options[:version]
dependency.prerelease = options[:prerelease]
if options[:reverse_dependencies] and remote? and not local? then if options[:reverse_dependencies] and remote? and not local? then
alert_error 'Only reverse dependencies for local gems are supported.' alert_error 'Only reverse dependencies for local gems are supported.'
@ -75,7 +77,10 @@ class Gem::Commands::DependencyCommand < Gem::Command
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
begin begin
fetcher.find_matching(dependency).each do |spec_tuple, source_uri| specs_and_sources = fetcher.find_matching(dependency, false, true,
dependency.prerelease?)
specs_and_sources.each do |spec_tuple, source_uri|
spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri) spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri)
source_indexes[source_uri].add_spec spec source_indexes[source_uri].add_spec spec
@ -120,8 +125,8 @@ class Gem::Commands::DependencyCommand < Gem::Command
if options[:pipe_format] then if options[:pipe_format] then
specs.values.sort_by { |_, spec| spec }.each do |_, spec| specs.values.sort_by { |_, spec| spec }.each do |_, spec|
unless spec.dependencies.empty? unless spec.dependencies.empty?
spec.dependencies.each do |dep| spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
say "#{dep.name} --version '#{dep.version_requirements}'" say "#{dep.name} --version '#{dep.requirement}'"
end end
end end
end end
@ -147,7 +152,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
response = '' response = ''
response << ' ' * level + "Gem #{spec.full_name}\n" response << ' ' * level + "Gem #{spec.full_name}\n"
unless spec.dependencies.empty? then unless spec.dependencies.empty? then
spec.dependencies.each do |dep| spec.dependencies.sort_by { |dep| dep.name }.each do |dep|
response << ' ' * level + " #{dep}\n" response << ' ' * level + " #{dep}\n"
end end
end end
@ -163,7 +168,7 @@ class Gem::Commands::DependencyCommand < Gem::Command
dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep
if spec.name == dep.name and if spec.name == dep.name and
dep.version_requirements.satisfied_by?(spec.version) then dep.requirement.satisfied_by?(spec.version) then
result << [sp.full_name, dep] result << [sp.full_name, dep]
end end
end end

View file

@ -118,7 +118,7 @@ lib/rubygems/defaults/operating_system.rb
end end
else else
fail Gem::CommandLineError, "Unknown enviroment option [#{arg}]" raise Gem::CommandLineError, "Unknown enviroment option [#{arg}]"
end end
say out say out
true true

View file

@ -17,6 +17,7 @@ class Gem::Commands::FetchCommand < Gem::Command
add_version_option add_version_option
add_platform_option add_platform_option
add_prerelease_option
end end
def arguments # :nodoc: def arguments # :nodoc:
@ -39,12 +40,12 @@ class Gem::Commands::FetchCommand < Gem::Command
gem_names.each do |gem_name| gem_names.each do |gem_name|
dep = Gem::Dependency.new gem_name, version dep = Gem::Dependency.new gem_name, version
dep.prerelease = options[:prerelease]
specs_and_sources = Gem::SpecFetcher.fetcher.fetch dep, all specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, false, true,
dep.prerelease?)
specs_and_sources.sort_by { |spec,| spec.version } spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last
spec, source_uri = specs_and_sources.last
if spec.nil? then if spec.nil? then
alert_error "Could not find #{gem_name} in any repository" alert_error "Could not find #{gem_name} in any repository"
@ -52,7 +53,7 @@ class Gem::Commands::FetchCommand < Gem::Command
end end
path = Gem::RemoteFetcher.fetcher.download spec, source_uri path = Gem::RemoteFetcher.fetcher.download spec, source_uri
FileUtils.mv path, "#{spec.full_name}.gem" FileUtils.mv path, spec.file_name
say "Downloaded #{spec.full_name}" say "Downloaded #{spec.full_name}"
end end

View file

@ -32,6 +32,7 @@ class Gem::Commands::InstallCommand < Gem::Command
add_local_remote_options add_local_remote_options
add_platform_option add_platform_option
add_version_option add_version_option
add_prerelease_option "to be installed. (Only for listed gems)"
end end
def arguments # :nodoc: def arguments # :nodoc:

View file

@ -51,7 +51,7 @@ Multiple sources and destinations may be specified.
Dir.mkdir gems_dir Dir.mkdir gems_dir
end end
sourceindex_data = '' source_index_data = ''
say "fetching: #{get_from}/Marshal.#{Gem.marshal_version}.Z" say "fetching: #{get_from}/Marshal.#{Gem.marshal_version}.Z"
@ -70,18 +70,18 @@ Multiple sources and destinations may be specified.
end end
open File.join(get_from.to_s, "Marshal.#{Gem.marshal_version}.Z"), "rb" do |y| open File.join(get_from.to_s, "Marshal.#{Gem.marshal_version}.Z"), "rb" do |y|
sourceindex_data = Zlib::Inflate.inflate y.read source_index_data = Zlib::Inflate.inflate y.read
open File.join(save_to, "Marshal.#{Gem.marshal_version}"), "wb" do |out| open File.join(save_to, "Marshal.#{Gem.marshal_version}"), "wb" do |out|
out.write sourceindex_data out.write source_index_data
end end
end end
sourceindex = Marshal.load(sourceindex_data) source_index = Marshal.load source_index_data
progress = ui.progress_reporter sourceindex.size, progress = ui.progress_reporter source_index.size,
"Fetching #{sourceindex.size} gems" "Fetching #{source_index.size} gems"
sourceindex.each do |fullname, gem| source_index.each do |fullname, gem|
gem_file = "#{fullname}.gem" gem_file = gem.file_name
gem_dest = File.join gems_dir, gem_file gem_dest = File.join gems_dir, gem_file
unless File.exist? gem_dest then unless File.exist? gem_dest then

View file

@ -0,0 +1,75 @@
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities'
class Gem::Commands::OwnerCommand < Gem::Command
include Gem::LocalRemoteOptions
include Gem::GemcutterUtilities
def description # :nodoc:
'Manage gem owners on RubyGems.org.'
end
def arguments # :nodoc:
"GEM gem to manage owners for"
end
def initialize
super 'owner', description
add_proxy_option
defaults.merge! :add => [], :remove => []
add_option '-a', '--add EMAIL', 'Add an owner' do |value, options|
options[:add] << value
end
add_option '-r', '--remove EMAIL', 'Remove an owner' do |value, options|
options[:remove] << value
end
end
def execute
sign_in
name = get_one_gem_name
add_owners name, options[:add]
remove_owners name, options[:remove]
show_owners name
end
def show_owners name
response = rubygems_api_request :get, "api/v1/gems/#{name}/owners.yaml" do |request|
request.add_field "Authorization", Gem.configuration.rubygems_api_key
end
with_response response do |resp|
owners = YAML.load resp.body
say "Owners for gem: #{name}"
owners.each do |owner|
say "- #{owner['email']}"
end
end
end
def add_owners name, owners
manage_owners :post, name, owners
end
def remove_owners name, owners
manage_owners :delete, name, owners
end
def manage_owners method, name, owners
owners.each do |owner|
response = rubygems_api_request method, "api/v1/gems/#{name}/owners" do |request|
request.set_form_data 'email' => owner
request.add_field "Authorization", Gem.configuration.rubygems_api_key
end
with_response response
end
end
end

View file

@ -74,7 +74,7 @@ revert the gem.
say "Restoring gem(s) to pristine condition..." say "Restoring gem(s) to pristine condition..."
specs.each do |spec| specs.each do |spec|
gem = Dir[File.join(Gem.dir, 'cache', "#{spec.full_name}.gem")].first gem = Dir[File.join(Gem.dir, 'cache', spec.file_name)].first
if gem.nil? then if gem.nil? then
alert_error "Cached gem for #{spec.full_name} not found, use `gem install` to restore" alert_error "Cached gem for #{spec.full_name} not found, use `gem install` to restore"

View file

@ -0,0 +1,45 @@
require 'rubygems/command'
require 'rubygems/local_remote_options'
require 'rubygems/gemcutter_utilities'
class Gem::Commands::PushCommand < Gem::Command
include Gem::LocalRemoteOptions
include Gem::GemcutterUtilities
def description # :nodoc:
'Push a gem up to RubyGems.org'
end
def arguments # :nodoc:
"GEM built gem to push up"
end
def usage # :nodoc:
"#{program_name} GEM"
end
def initialize
super 'push', description
add_proxy_option
end
def execute
sign_in
send_gem get_one_gem_name
end
def send_gem name
say "Pushing gem to RubyGems.org..."
response = rubygems_api_request :post, "api/v1/gems" do |request|
request.body = Gem.read_binary name
request.add_field "Content-Length", request.body.size
request.add_field "Content-Type", "application/octet-stream"
request.add_field "Authorization", Gem.configuration.rubygems_api_key
end
with_response response
end
end

View file

@ -45,7 +45,7 @@ class Gem::Commands::QueryCommand < Gem::Command
options[:all] = value options[:all] = value
end end
add_option( '--prerelease', add_option( '--[no-]prerelease',
'Display prerelease versions') do |value, options| 'Display prerelease versions') do |value, options|
options[:prerelease] = value options[:prerelease] = value
end end
@ -111,6 +111,9 @@ class Gem::Commands::QueryCommand < Gem::Command
begin begin
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
spec_tuples = fetcher.find_matching dep, all, false, prerelease spec_tuples = fetcher.find_matching dep, all, false, prerelease
spec_tuples += fetcher.find_matching dep, false, false, true if
prerelease and all
rescue Gem::RemoteFetcher::FetchError => e rescue Gem::RemoteFetcher::FetchError => e
if prerelease then if prerelease then
raise Gem::OperationNotSupportedError, raise Gem::OperationNotSupportedError,

View file

@ -8,7 +8,7 @@ class Gem::Commands::RdocCommand < Gem::Command
def initialize def initialize
super 'rdoc', 'Generates RDoc for pre-installed gems', super 'rdoc', 'Generates RDoc for pre-installed gems',
:version => Gem::Requirement.default, :version => Gem::Requirement.default,
:include_rdoc => true, :include_ri => true :include_rdoc => true, :include_ri => true, :overwrite => false
add_option('--all', add_option('--all',
'Generate RDoc/RI documentation for all', 'Generate RDoc/RI documentation for all',
@ -17,15 +17,20 @@ class Gem::Commands::RdocCommand < Gem::Command
end end
add_option('--[no-]rdoc', add_option('--[no-]rdoc',
'Include RDoc generated documents') do |value, options| 'Generate RDoc HTML') do |value, options|
options[:include_rdoc] = value options[:include_rdoc] = value
end end
add_option('--[no-]ri', add_option('--[no-]ri',
'Include RI generated documents') do |value, options| 'Generate RI data') do |value, options|
options[:include_ri] = value options[:include_ri] = value
end end
add_option('--[no-]overwrite',
'Overwrite installed documents') do |value, options|
options[:overwrite] = value
end
add_version_option add_version_option
end end
@ -34,7 +39,14 @@ class Gem::Commands::RdocCommand < Gem::Command
end end
def defaults_str # :nodoc: def defaults_str # :nodoc:
"--version '#{Gem::Requirement.default}' --rdoc --ri" "--version '#{Gem::Requirement.default}' --rdoc --ri --no-overwrite"
end
def description # :nodoc:
<<-DESC
The rdoc command builds RDoc and RI documentation for installed gems. Use
--overwrite to force rebuilding of documentation.
DESC
end end
def usage # :nodoc: def usage # :nodoc:
@ -53,24 +65,27 @@ class Gem::Commands::RdocCommand < Gem::Command
end end
if specs.empty? if specs.empty?
fail "Failed to find gem #{gem_name} to generate RDoc for #{options[:version]}" raise "Failed to find gem #{gem_name} to generate RDoc for #{options[:version]}"
end end
if options[:include_ri] if options[:include_ri]
specs.each do |spec| specs.sort.each do |spec|
Gem::DocManager.new(spec).generate_ri doc = Gem::DocManager.new(spec)
doc.generate_ri if options[:overwrite] || !doc.ri_installed?
end end
Gem::DocManager.update_ri_cache Gem::DocManager.update_ri_cache
end end
if options[:include_rdoc] if options[:include_rdoc]
specs.each do |spec| specs.sort.each do |spec|
Gem::DocManager.new(spec).generate_rdoc doc = Gem::DocManager.new(spec)
doc.generate_rdoc if options[:overwrite] || !doc.rdoc_installed?
end end
end end
true true
end end
end end

View file

@ -36,6 +36,12 @@ class Gem::Commands::ServerCommand < Gem::Command
add_option '--[no-]daemon', 'run as a daemon' do |daemon, options| add_option '--[no-]daemon', 'run as a daemon' do |daemon, options|
options[:daemon] = daemon options[:daemon] = daemon
end end
add_option '-b', '--bind=HOST,HOST',
'addresses to bind', Array do |address, options|
options[:addresses] ||= []
options[:addresses].push(*address)
end
end end
def defaults_str # :nodoc: def defaults_str # :nodoc:

View file

@ -2,7 +2,6 @@ require 'rubygems/command'
require 'fileutils' require 'fileutils'
require 'rbconfig' require 'rbconfig'
require 'tmpdir' require 'tmpdir'
require 'pathname'
## ##
# Installs RubyGems itself. This command is ordinarily only available from a # Installs RubyGems itself. This command is ordinarily only available from a
@ -117,6 +116,8 @@ By default, this RubyGems will install gem as:
say "RubyGems #{Gem::VERSION} installed" say "RubyGems #{Gem::VERSION} installed"
uninstall_old_gemcutter
install_rdoc install_rdoc
say say
@ -359,5 +360,14 @@ abort "#{deprecation_message}"
r.document args r.document args
end end
def uninstall_old_gemcutter
require 'rubygems/uninstaller'
ui = Gem::Uninstaller.new('gemcutter', :all => true, :ignore => true,
:version => '< 0.4')
ui.uninstall
rescue Gem::InstallError
end
end end

View file

@ -41,7 +41,7 @@ class Gem::Commands::UnpackCommand < Gem::Command
path = get_path name, options[:version] path = get_path name, options[:version]
if path then if path then
basename = File.basename(path).sub(/\.gem$/, '') basename = File.basename(path, '.gem')
target_dir = File.expand_path File.join(options[:target], basename) target_dir = File.expand_path File.join(options[:target], basename)
FileUtils.mkdir_p target_dir FileUtils.mkdir_p target_dir
Gem::Installer.new(path, :unpack => true).unpack target_dir Gem::Installer.new(path, :unpack => true).unpack target_dir
@ -79,7 +79,7 @@ class Gem::Commands::UnpackCommand < Gem::Command
# We expect to find (basename).gem in the 'cache' directory. # We expect to find (basename).gem in the 'cache' directory.
# Furthermore, the name match must be exact (ignoring case). # Furthermore, the name match must be exact (ignoring case).
if gemname =~ /^#{selected.name}$/i if gemname =~ /^#{selected.name}$/i
filename = selected.full_name + '.gem' filename = selected.file_name
path = nil path = nil
Gem.path.find do |gem_dir| Gem.path.find do |gem_dir|

View file

@ -28,8 +28,8 @@ class Gem::Commands::UpdateCommand < Gem::Command
end end
add_local_remote_options add_local_remote_options
add_platform_option add_platform_option
add_prerelease_option "as update targets"
end end
def arguments # :nodoc: def arguments # :nodoc:
@ -51,7 +51,7 @@ class Gem::Commands::UpdateCommand < Gem::Command
say "Updating RubyGems" say "Updating RubyGems"
unless options[:args].empty? then unless options[:args].empty? then
fail "No gem names are allowed with the --system option" raise "No gem names are allowed with the --system option"
end end
rubygems_update = Gem::Specification.new rubygems_update = Gem::Specification.new

View file

@ -27,13 +27,11 @@ class Gem::Commands::WhichCommand < Gem::Command
"--no-gems-first --no-all" "--no-gems-first --no-all"
end end
def usage # :nodoc:
"#{program_name} FILE [FILE ...]"
end
def execute def execute
searcher = Gem::GemPathSearcher.new searcher = Gem::GemPathSearcher.new
found = false
options[:args].each do |arg| options[:args].each do |arg|
dirs = $LOAD_PATH dirs = $LOAD_PATH
spec = searcher.find arg spec = searcher.find arg
@ -44,19 +42,19 @@ class Gem::Commands::WhichCommand < Gem::Command
else else
dirs = $LOAD_PATH + gem_paths(spec) dirs = $LOAD_PATH + gem_paths(spec)
end end
say "(checking gem #{spec.full_name} for #{arg})" if
Gem.configuration.verbose and $stdout.tty?
end end
paths = find_paths arg, dirs paths = find_paths arg, dirs
if paths.empty? then if paths.empty? then
say "Can't find ruby library file or shared library #{arg}" alert_error "Can't find ruby library file or shared library #{arg}"
else else
say paths say paths
found = true
end end
end end
terminate_interaction 1 unless found
end end
def find_paths(package_name, dirs) def find_paths(package_name, dirs)
@ -80,7 +78,7 @@ class Gem::Commands::WhichCommand < Gem::Command
end end
def usage # :nodoc: def usage # :nodoc:
"#{program_name} FILE [...]" "#{program_name} FILE [FILE ...]"
end end
end end

View file

@ -4,10 +4,26 @@
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
require 'yaml' ##
# Gem::ConfigFile RubyGems options and gem command options from ~/.gemrc.
# Store the gem command options specified in the configuration file. The #
# config file object acts much like a hash. # ~/.gemrc is a YAML file that uses strings to match gem command arguments and
# symbols to match RubyGems options.
#
# Gem command arguments use a String key that matches the command name and
# allow you to specify default arguments:
#
# install: --no-rdoc --no-ri
# update: --no-rdoc --no-ri
#
# You can use <tt>gem:</tt> to set default arguments for all commands.
#
# RubyGems options use symbol keys. Valid options are:
#
# +:backtrace+:: See #backtrace
# +:benchmark+:: See #benchmark
# +:sources+:: Sets Gem::sources
# +:verbose+:: See #verbose
class Gem::ConfigFile class Gem::ConfigFile
@ -46,49 +62,74 @@ class Gem::ConfigFile
SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc' SYSTEM_WIDE_CONFIG_FILE = File.join system_config_path, 'gemrc'
##
# List of arguments supplied to the config file object. # List of arguments supplied to the config file object.
attr_reader :args attr_reader :args
# Where to look for gems ##
# Where to look for gems (deprecated)
attr_accessor :path attr_accessor :path
##
# Where to install gems (deprecated)
attr_accessor :home attr_accessor :home
##
# True if we print backtraces on errors. # True if we print backtraces on errors.
attr_writer :backtrace attr_writer :backtrace
##
# True if we are benchmarking this run. # True if we are benchmarking this run.
attr_accessor :benchmark attr_accessor :benchmark
# Bulk threshold value. If the number of missing gems are above ##
# this threshold value, then a bulk download technique is used. # Bulk threshold value. If the number of missing gems are above this
# threshold value, then a bulk download technique is used. (deprecated)
attr_accessor :bulk_threshold attr_accessor :bulk_threshold
##
# Verbose level of output: # Verbose level of output:
# * false -- No output # * false -- No output
# * true -- Normal output # * true -- Normal output
# * :loud -- Extra output # * :loud -- Extra output
attr_accessor :verbose attr_accessor :verbose
##
# True if we want to update the SourceInfoCache every time, false otherwise # True if we want to update the SourceInfoCache every time, false otherwise
attr_accessor :update_sources attr_accessor :update_sources
##
# API key for RubyGems.org
attr_reader :rubygems_api_key
##
# Create the config file object. +args+ is the list of arguments # Create the config file object. +args+ is the list of arguments
# from the command line. # from the command line.
# #
# The following command line options are handled early here rather # The following command line options are handled early here rather
# than later at the time most command options are processed. # than later at the time most command options are processed.
# #
# * --config-file and --config-file==NAME -- Obviously these need # <tt>--config-file</tt>, <tt>--config-file==NAME</tt>::
# to be handled by the ConfigFile object to ensure we get the # Obviously these need to be handled by the ConfigFile object to ensure we
# right config file. # get the right config file.
# #
# * --backtrace -- Backtrace needs to be turned on early so that # <tt>--backtrace</tt>::
# errors before normal option parsing can be properly handled. # Backtrace needs to be turned on early so that errors before normal
# # option parsing can be properly handled.
# * --debug -- Enable Ruby level debug messages. Handled early
# for the same reason as --backtrace.
# #
# <tt>--debug</tt>::
# Enable Ruby level debug messages. Handled early for the same reason as
# --backtrace.
def initialize(arg_list) def initialize(arg_list)
@config_file_name = nil @config_file_name = nil
need_config_file_name = false need_config_file_name = false
@ -125,21 +166,53 @@ class Gem::ConfigFile
@hash = @hash.merge user_config @hash = @hash.merge user_config
# HACK these override command-line args, which is bad # HACK these override command-line args, which is bad
@backtrace = @hash[:backtrace] if @hash.key? :backtrace @backtrace = @hash[:backtrace] if @hash.key? :backtrace
@benchmark = @hash[:benchmark] if @hash.key? :benchmark @benchmark = @hash[:benchmark] if @hash.key? :benchmark
@bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold @bulk_threshold = @hash[:bulk_threshold] if @hash.key? :bulk_threshold
Gem.sources = @hash[:sources] if @hash.key? :sources @home = @hash[:gemhome] if @hash.key? :gemhome
@verbose = @hash[:verbose] if @hash.key? :verbose @path = @hash[:gempath] if @hash.key? :gempath
@update_sources = @hash[:update_sources] if @hash.key? :update_sources @update_sources = @hash[:update_sources] if @hash.key? :update_sources
@path = @hash[:gempath] if @hash.key? :gempath @verbose = @hash[:verbose] if @hash.key? :verbose
@home = @hash[:gemhome] if @hash.key? :gemhome
load_rubygems_api_key
Gem.sources = @hash[:sources] if @hash.key? :sources
handle_arguments arg_list handle_arguments arg_list
end end
##
# Location of RubyGems.org credentials
def credentials_path
File.join(Gem.user_home, '.gem', 'credentials')
end
def load_rubygems_api_key
api_key_hash = File.exists?(credentials_path) ? load_file(credentials_path) : @hash
@rubygems_api_key = api_key_hash[:rubygems_api_key] if api_key_hash.key? :rubygems_api_key
end
def rubygems_api_key=(api_key)
config = load_file(credentials_path).merge(:rubygems_api_key => api_key)
dirname = File.dirname(credentials_path)
Dir.mkdir(dirname) unless File.exists?(dirname)
require 'yaml'
File.open(credentials_path, 'w') do |f|
f.write config.to_yaml
end
@rubygems_api_key = api_key
end
def load_file(filename) def load_file(filename)
return {} unless filename and File.exists?(filename)
begin begin
YAML.load(File.read(filename)) if filename and File.exist?(filename) require 'yaml'
YAML.load(File.read(filename))
rescue ArgumentError rescue ArgumentError
warn "Failed to load #{config_file_name}" warn "Failed to load #{config_file_name}"
rescue Errno::EACCES rescue Errno::EACCES
@ -233,8 +306,9 @@ class Gem::ConfigFile
# Writes out this config file, replacing its source. # Writes out this config file, replacing its source.
def write def write
File.open config_file_name, 'w' do |fp| require 'yaml'
fp.write self.to_yaml open config_file_name, 'w' do |io|
io.write to_yaml
end end
end end

View file

@ -9,7 +9,7 @@ module Gem
# An Array of the default sources that come with RubyGems # An Array of the default sources that come with RubyGems
def self.default_sources def self.default_sources
%w[http://gems.rubyforge.org/] %w[http://rubygems.org/]
end end
## ##

View file

@ -1,14 +1,22 @@
#-- require "rubygems/requirement"
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
## ##
# The Dependency class holds a Gem name and a Gem::Requirement # The Dependency class holds a Gem name and a Gem::Requirement.
class Gem::Dependency class Gem::Dependency
# :stopdoc:
@warned_version_requirement = false
def self.warned_version_requirement
@warned_version_requirement
end
def self.warned_version_requirement= value
@warned_version_requirement = value
end
# :startdoc:
## ##
# Valid dependency types. # Valid dependency types.
#-- #--
@ -16,132 +24,182 @@ class Gem::Dependency
# Gem::Specification::CURRENT_SPECIFICATION_VERSION as well. # Gem::Specification::CURRENT_SPECIFICATION_VERSION as well.
TYPES = [ TYPES = [
:development, :development,
:runtime, :runtime,
] ]
## ##
# Dependency name or regular expression. # Dependency name or regular expression.
attr_accessor :name attr_accessor :name
##
# Allows you to force this dependency to be a prerelease.
attr_writer :prerelease
## ##
# Dependency type. # Dependency type.
attr_reader :type attr_reader :type
## ##
# Dependent versions. # Constructs a dependency with +name+ and +requirements+. The last
# argument can optionally be the dependency type, which defaults to
# <tt>:runtime</tt>.
attr_writer :version_requirements def initialize name, *requirements
type = Symbol === requirements.last ? requirements.pop : :runtime
## requirements = requirements.first if 1 == requirements.length # unpack
# Orders dependencies by name only.
def <=>(other)
[@name] <=> [other.name]
end
##
# Constructs a dependency with +name+ and +requirements+.
def initialize(name, version_requirements, type=:runtime)
@name = name
unless TYPES.include? type unless TYPES.include? type
raise ArgumentError, "Valid types are #{TYPES.inspect}, not #{@type.inspect}" raise ArgumentError, "Valid types are #{TYPES.inspect}, "
+ "not #{@type.inspect}"
end end
@type = type @name = name
@requirement = Gem::Requirement.create requirements
@type = type
@prerelease = false
@version_requirements = Gem::Requirement.create version_requirements # This is for Marshal backwards compatability. See the comments in
@version_requirement = nil # Avoid warnings. # +requirement+ for the dirty details.
@version_requirements = @requirement
end end
def version_requirements ##
normalize if defined? @version_requirement and @version_requirement # What does this dependency require?
@version_requirements
##
# A dependency's hash is the XOR of the hashes of +name+, +type+,
# and +requirement+.
def hash # :nodoc:
name.hash ^ type.hash ^ requirement.hash
end end
def requirement_list def inspect # :nodoc:
version_requirements.as_list "<%s type=%p name=%p requirements=%p>" %
[self.class, @type, @name, requirement.to_s]
end end
alias requirements_list requirement_list ##
# Does this dependency require a prerelease?
def normalize def prerelease?
ver = @version_requirement.instance_variable_get :@version @prerelease || requirement.prerelease?
@version_requirements = Gem::Requirement.new([ver])
@version_requirement = nil
end
def to_s # :nodoc:
"#{name} (#{version_requirements}, #{@type || :runtime})"
end end
def pretty_print(q) # :nodoc: def pretty_print(q) # :nodoc:
q.group 1, 'Gem::Dependency.new(', ')' do q.group 1, 'Gem::Dependency.new(', ')' do
q.pp @name q.pp name
q.text ',' q.text ','
q.breakable q.breakable
q.pp @version_requirements q.pp requirement
q.text ',' q.text ','
q.breakable q.breakable
q.pp @type q.pp type
end end
end end
def ==(other) # :nodoc: def requirement
self.class === other && return @requirement if defined?(@requirement) and @requirement
self.name == other.name &&
self.type == other.type && # @version_requirements and @version_requirement are legacy ivar
self.version_requirements == other.version_requirements # names, and supported here because older gems need to keep
# working and Dependency doesn't implement marshal_dump and
# marshal_load. In a happier world, this would be an
# attr_accessor. The horrifying instance_variable_get you see
# below is also the legacy of some old restructurings.
#
# Note also that because of backwards compatibility (loading new
# gems in an old RubyGems installation), we can't add explicit
# marshaling to this class until we want to make a big
# break. Maybe 2.0.
#
# Children, define explicit marshal and unmarshal behavior for
# public classes. Marshal formats are part of your public API.
if defined?(@version_requirement) && @version_requirement
version = @version_requirement.instance_variable_get :@version
@version_requirement = nil
@version_requirements = Gem::Requirement.new version
end
@requirement = @version_requirements if defined?(@version_requirements)
end end
## ##
# Uses this dependency as a pattern to compare to +other+. This dependency # Rails subclasses Gem::Dependency and uses this method, so we'll hack
# will match if the name matches the other's name, and other has only an # around it.
# equal version requirement that satisfies this dependency.
def =~(other) alias __requirement requirement # :nodoc:
other = if self.class === other then
other
else
return false unless other.respond_to? :name and
other.respond_to? :version
Gem::Dependency.new other.name, other.version def requirements_list
end requirement.as_list
end
pattern = @name def to_s # :nodoc:
pattern = /\A#{Regexp.escape @name}\Z/ unless Regexp === pattern "#{name} (#{requirement}, #{type})"
end
def version_requirements # :nodoc:
unless Gem::Dependency.warned_version_requirement then
warn "#{Gem.location_of_caller.join ':'}:Warning: " \
"Gem::Dependency#version_requirements is deprecated " \
"and will be removed on or after August 2010. " \
"Use #requirement"
Gem::Dependency.warned_version_requirement = true
end
__requirement
end
alias_method :version_requirement, :version_requirements
def == other # :nodoc:
Gem::Dependency === other &&
self.name == other.name &&
self.type == other.type &&
self.requirement == other.requirement
end
##
# Dependencies are ordered by name.
def <=> other
[@name] <=> [other.name]
end
##
# Uses this dependency as a pattern to compare to +other+. This
# dependency will match if the name matches the other's name, and
# other has only an equal version requirement that satisfies this
# dependency.
def =~ other
unless Gem::Dependency === other
other = Gem::Dependency.new other.name, other.version rescue return false
end
pattern = name
pattern = /\A#{Regexp.escape pattern}\Z/ unless Regexp === pattern
return false unless pattern =~ other.name return false unless pattern =~ other.name
reqs = other.version_requirements.requirements reqs = other.requirement.requirements
return false unless reqs.length == 1 return false unless reqs.length == 1
return false unless reqs.first.first == '=' return false unless reqs.first.first == '='
version = reqs.first.last version = reqs.first.last
version_requirements.satisfied_by? version requirement.satisfied_by? version
end
##
# A dependency's hash is the sum of the hash of the #name, #type and
# #version_requirements
def hash
name.hash + type.hash + version_requirements.hash
end
def inspect # :nodoc:
"<%s type=%p name=%p requirements=%p>" % [self.class, @type, @name,
version_requirements.to_s]
end end
end end

View file

@ -38,7 +38,7 @@ class Gem::DependencyInstaller
# :format_executable:: See Gem::Installer#initialize. # :format_executable:: See Gem::Installer#initialize.
# :ignore_dependencies:: Don't install any dependencies. # :ignore_dependencies:: Don't install any dependencies.
# :install_dir:: See Gem::Installer#install. # :install_dir:: See Gem::Installer#install.
# :prerelease:: Allow prerelease versions # :prerelease:: Allow prerelease versions. See #install.
# :security_policy:: See Gem::Installer::new and Gem::Security. # :security_policy:: See Gem::Installer::new and Gem::Security.
# :user_install:: See Gem::Installer.new # :user_install:: See Gem::Installer.new
# :wrappers:: See Gem::Installer::new # :wrappers:: See Gem::Installer::new
@ -89,14 +89,18 @@ class Gem::DependencyInstaller
if @domain == :both or @domain == :remote then if @domain == :both or @domain == :remote then
begin begin
requirements = dep.version_requirements.requirements.map do |req, ver| requirements = dep.requirement.requirements.map do |req, ver|
req req
end end
all = !@prerelease && (requirements.length > 1 || all = !dep.prerelease? &&
# we only need latest if there's one requirement and it is
# guaranteed to match the newest specs
(requirements.length > 1 or
(requirements.first != ">=" and requirements.first != ">")) (requirements.first != ">=" and requirements.first != ">"))
found = Gem::SpecFetcher.fetcher.fetch dep, all, true, @prerelease found = Gem::SpecFetcher.fetcher.fetch dep, all, true, dep.prerelease?
gems_and_sources.push(*found) gems_and_sources.push(*found)
rescue Gem::RemoteFetcher::FetchError => e rescue Gem::RemoteFetcher::FetchError => e
@ -120,7 +124,7 @@ class Gem::DependencyInstaller
def gather_dependencies def gather_dependencies
specs = @specs_and_sources.map { |spec,_| spec } specs = @specs_and_sources.map { |spec,_| spec }
dependency_list = Gem::DependencyList.new dependency_list = Gem::DependencyList.new @development
dependency_list.add(*specs) dependency_list.add(*specs)
unless @ignore_dependencies then unless @ignore_dependencies then
@ -143,7 +147,7 @@ class Gem::DependencyInstaller
@source_index.any? do |_, installed_spec| @source_index.any? do |_, installed_spec|
dep.name == installed_spec.name and dep.name == installed_spec.name and
dep.version_requirements.satisfied_by? installed_spec.version dep.requirement.satisfied_by? installed_spec.version
end end
end end
@ -164,7 +168,9 @@ class Gem::DependencyInstaller
# +version+. Returns an Array of specs and sources required for # +version+. Returns an Array of specs and sources required for
# installation of the gem. # installation of the gem.
def find_spec_by_name_and_version gem_name, version = Gem::Requirement.default def find_spec_by_name_and_version(gem_name,
version = Gem::Requirement.default,
prerelease = false)
spec_and_source = nil spec_and_source = nil
glob = if File::ALT_SEPARATOR then glob = if File::ALT_SEPARATOR then
@ -189,6 +195,7 @@ class Gem::DependencyInstaller
if spec_and_source.nil? then if spec_and_source.nil? then
dep = Gem::Dependency.new gem_name, version dep = Gem::Dependency.new gem_name, version
dep.prerelease = true if prerelease
spec_and_sources = find_gems_with_sources(dep).reverse spec_and_sources = find_gems_with_sources(dep).reverse
spec_and_source = spec_and_sources.find { |spec, source| spec_and_source = spec_and_sources.find { |spec, source|
@ -205,13 +212,24 @@ class Gem::DependencyInstaller
end end
## ##
# Installs the gem and all its dependencies. Returns an Array of installed # Installs the gem +dep_or_name+ and all its dependencies. Returns an Array
# gems specifications. # of installed gem specifications.
#
# If the +:prerelease+ option is set and there is a prerelease for
# +dep_or_name+ the prerelease version will be installed.
#
# Unless explicitly specified as a prerelease dependency, prerelease gems
# that +dep_or_name+ depend on will not be installed.
#
# If c-1.a depends on b-1 and a-1.a and there is a gem b-1.a available then
# c-1.a, b-1 and a-1.a will be installed. b-1.a will need to be installed
# separately.
def install dep_or_name, version = Gem::Requirement.default def install dep_or_name, version = Gem::Requirement.default
if String === dep_or_name then if String === dep_or_name then
find_spec_by_name_and_version dep_or_name, version find_spec_by_name_and_version dep_or_name, version, @prerelease
else else
dep_or_name.prerelease = @prerelease
@specs_and_sources = [find_gems_with_sources(dep_or_name).last] @specs_and_sources = [find_gems_with_sources(dep_or_name).last]
end end

View file

@ -6,23 +6,41 @@
require 'tsort' require 'tsort'
##
# Gem::DependencyList is used for installing and uninstalling gems in the
# correct order to avoid conflicts.
class Gem::DependencyList class Gem::DependencyList
include Enumerable include Enumerable
include TSort include TSort
def self.from_source_index(src_index) ##
deps = new # Allows enabling/disabling use of development dependencies
src_index.each do |full_name, spec| attr_accessor :development
deps.add spec
##
# Creates a DependencyList from a Gem::SourceIndex +source_index+
def self.from_source_index(source_index)
list = new
source_index.each do |full_name, spec|
list.add spec
end end
deps list
end end
def initialize ##
# Creates a new DependencyList. If +development+ is true, development
# dependencies will be included.
def initialize development = false
@specs = [] @specs = []
@development = development
end end
## ##
@ -33,8 +51,9 @@ class Gem::DependencyList
end end
## ##
# Return a list of the specifications in the dependency list, sorted in # Return a list of the gem specifications in the dependency list, sorted in
# order so that no spec in the list depends on a gem earlier in the list. # order so that no gemspec in the list depends on a gemspec earlier in the
# list.
# #
# This is useful when removing gems from a set of installed gems. By # This is useful when removing gems from a set of installed gems. By
# removing them in the returned order, you don't get into as many dependency # removing them in the returned order, you don't get into as many dependency
@ -77,6 +96,10 @@ class Gem::DependencyList
@specs.find { |spec| spec.full_name == full_name } @specs.find { |spec| spec.full_name == full_name }
end end
def inspect # :nodoc:
"#<%s:0x%x %p>" % [self.class, object_id, map { |s| s.full_name }]
end
## ##
# Are all the dependencies in the list satisfied? # Are all the dependencies in the list satisfied?
@ -89,10 +112,10 @@ class Gem::DependencyList
end end
## ##
# Is is ok to remove a gem from the dependency list? # Is is ok to remove a gemspec from the dependency list?
# #
# If removing the gemspec creates breaks a currently ok dependency, then it # If removing the gemspec creates breaks a currently ok dependency, then it
# is NOT ok to remove the gem. # is NOT ok to remove the gemspec.
def ok_to_remove?(full_name) def ok_to_remove?(full_name)
gem_to_remove = find_name full_name gem_to_remove = find_name full_name
@ -117,13 +140,16 @@ class Gem::DependencyList
} }
end end
##
# Removes the gemspec matching +full_name+ from the dependency list
def remove_by_name(full_name) def remove_by_name(full_name)
@specs.delete_if { |spec| spec.full_name == full_name } @specs.delete_if { |spec| spec.full_name == full_name }
end end
## ##
# Return a hash of predecessors. <tt>result[spec]</tt> is an Array of # Return a hash of predecessors. <tt>result[spec]</tt> is an Array of
# gemspecs that have a dependency satisfied by the named spec. # gemspecs that have a dependency satisfied by the named gemspec.
def spec_predecessors def spec_predecessors
result = Hash.new { |h,k| h[k] = [] } result = Hash.new { |h,k| h[k] = [] }
@ -152,7 +178,10 @@ class Gem::DependencyList
def tsort_each_child(node, &block) def tsort_each_child(node, &block)
specs = @specs.sort.reverse specs = @specs.sort.reverse
node.dependencies.each do |dep| dependencies = node.runtime_dependencies
dependencies.push(*node.development_dependencies) if @development
dependencies.each do |dep|
specs.each do |spec| specs.each do |spec|
if spec.satisfies_requirement? dep then if spec.satisfies_requirement? dep then
begin begin

View file

@ -1,13 +0,0 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'digest/md5'
# :stopdoc:
module Gem
MD5 = Digest::MD5
end
# :startdoc:

View file

@ -1,11 +0,0 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'digest/sha1'
module Gem
SHA1 = Digest::SHA1
end

View file

@ -1,11 +0,0 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'digest/sha2'
module Gem
SHA256 = Digest::SHA256
end

View file

@ -97,6 +97,13 @@ class Gem::DocManager
File.exist?(File.join(@doc_dir, "rdoc")) File.exist?(File.join(@doc_dir, "rdoc"))
end end
##
# Is the RI documentation installed?
def ri_installed?
File.exist?(File.join(@doc_dir, "ri"))
end
## ##
# Generate the RI documents for this gem spec. # Generate the RI documents for this gem spec.
# #

View file

@ -14,25 +14,22 @@ require 'rubygems/package'
class Gem::Format class Gem::Format
attr_accessor :spec, :file_entries, :gem_path attr_accessor :spec
attr_accessor :file_entries
attr_accessor :gem_path
extend Gem::UserInteraction extend Gem::UserInteraction
## ##
# Constructs an instance of a Format object, representing the gem's # Constructs a Format representing the gem's data which came from +gem_path+
# data structure.
#
# gem:: [String] The file name of the gem
#
def initialize(gem_path) def initialize(gem_path)
@gem_path = gem_path @gem_path = gem_path
end end
## ##
# Reads the named gem file and returns a Format object, representing # Reads the gem +file_path+ using +security_policy+ and returns a Format
# the data from the gem file # representing the data in the gem
#
# file_path:: [String] Path to the gem file
def self.from_file_by_path(file_path, security_policy = nil) def self.from_file_by_path(file_path, security_policy = nil)
format = nil format = nil
@ -41,25 +38,24 @@ class Gem::Format
raise Gem::Exception, "Cannot load gem at [#{file_path}] in #{Dir.pwd}" raise Gem::Exception, "Cannot load gem at [#{file_path}] in #{Dir.pwd}"
end end
# check for old version gem start = File.read file_path, 20
if File.read(file_path, 20).include?("MD5SUM =")
if start.nil? or start.length < 20 then
nil
elsif start.include?("MD5SUM =") # old version gems
require 'rubygems/old_format' require 'rubygems/old_format'
format = Gem::OldFormat.from_file_by_path(file_path) Gem::OldFormat.from_file_by_path file_path
else else
open file_path, Gem.binary_mode do |io| open file_path, Gem.binary_mode do |io|
format = from_io io, file_path, security_policy from_io io, file_path, security_policy
end end
end end
return format
end end
## ##
# Reads a gem from an io stream and returns a Format object, representing # Reads a gem from +io+ at +gem_path+ using +security_policy+ and returns a
# the data from the gem file # Format representing the data from the gem
#
# io:: [IO] Stream from which to read the gem
def self.from_io(io, gem_path="(io)", security_policy = nil) def self.from_io(io, gem_path="(io)", security_policy = nil)
format = new gem_path format = new gem_path

View file

@ -30,7 +30,7 @@ module Gem
def ensure_ssl_available def ensure_ssl_available
unless ssl_available? unless ssl_available?
fail Gem::Exception, "SSL is not installed on this system" raise Gem::Exception, "SSL is not installed on this system"
end end
end end
end end

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
## ##
# GemPathSearcher has the capability to find loadable files inside # GemPathSearcher has the capability to find loadable files inside
# gems. It generates data up front to speed up searches later. # gems. It generates data up front to speed up searches later.
@ -14,14 +8,16 @@ class Gem::GemPathSearcher
# Initialise the data we need to make searches later. # Initialise the data we need to make searches later.
def initialize def initialize
# We want a record of all the installed gemspecs, in the order # We want a record of all the installed gemspecs, in the order we wish to
# we wish to examine them. # examine them.
@gemspecs = init_gemspecs @gemspecs = init_gemspecs
# Map gem spec to glob of full require_path directories.
# Preparing this information may speed up searches later. # Map gem spec to glob of full require_path directories. Preparing this
# information may speed up searches later.
@lib_dirs = {} @lib_dirs = {}
@gemspecs.each do |spec| @gemspecs.each do |spec|
@lib_dirs[spec.object_id] = lib_dirs_for(spec) @lib_dirs[spec.object_id] = lib_dirs_for spec
end end
end end
@ -72,6 +68,7 @@ class Gem::GemPathSearcher
# Some of the intermediate results are cached in @lib_dirs for speed. # Some of the intermediate results are cached in @lib_dirs for speed.
def matching_files(spec, path) def matching_files(spec, path)
return [] unless @lib_dirs[spec.object_id] # case no paths
glob = File.join @lib_dirs[spec.object_id], "#{path}#{Gem.suffix_pattern}" glob = File.join @lib_dirs[spec.object_id], "#{path}#{Gem.suffix_pattern}"
Dir[glob].select { |f| File.file? f.untaint } Dir[glob].select { |f| File.file? f.untaint }
end end
@ -95,7 +92,8 @@ class Gem::GemPathSearcher
# '/usr/local/lib/ruby/gems/1.8/gems/foobar-1.0/{lib,ext}' # '/usr/local/lib/ruby/gems/1.8/gems/foobar-1.0/{lib,ext}'
def lib_dirs_for(spec) def lib_dirs_for(spec)
"#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}" "#{spec.full_gem_path}/{#{spec.require_paths.join(',')}}" if
spec.require_paths
end end
end end

View file

@ -0,0 +1,49 @@
require 'net/http'
require 'rubygems/remote_fetcher'
module Gem::GemcutterUtilities
def sign_in
return if Gem.configuration.rubygems_api_key
say "Enter your RubyGems.org credentials."
say "Don't have an account yet? Create one at http://rubygems.org/sign_up"
email = ask " Email: "
password = ask_for_password "Password: "
say "\n"
response = rubygems_api_request :get, "api/v1/api_key" do |request|
request.basic_auth email, password
end
with_response response do |resp|
say "Signed in."
Gem.configuration.rubygems_api_key = resp.body
end
end
def rubygems_api_request(method, path, &block)
host = ENV['RUBYGEMS_HOST'] || 'https://rubygems.org'
uri = URI.parse "#{host}/#{path}"
request_method = Net::HTTP.const_get method.to_s.capitalize
Gem::RemoteFetcher.fetcher.request(uri, request_method, &block)
end
def with_response(resp)
case resp
when Net::HTTPSuccess then
if block_given? then
yield resp
else
say resp.body
end
else
say resp.body
terminate_interaction 1
end
end
end

View file

@ -58,7 +58,7 @@ class Gem::Indexer
def initialize(directory, options = {}) def initialize(directory, options = {})
unless ''.respond_to? :to_xs then unless ''.respond_to? :to_xs then
fail "Gem::Indexer requires that the XML Builder library be installed:" \ raise "Gem::Indexer requires that the XML Builder library be installed:" \
"\n\tgem install builder" "\n\tgem install builder"
end end
@ -350,7 +350,7 @@ class Gem::Indexer
end end
index.sort_by { |_, spec| [-spec.date.to_i, spec] }.each do |_, spec| index.sort_by { |_, spec| [-spec.date.to_i, spec] }.each do |_, spec|
gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{spec.full_name}.gem" gem_path = CGI.escapeHTML "http://#{@rss_gems_host}/gems/#{spec.file_name}"
size = File.stat(spec.loaded_from).size rescue next size = File.stat(spec.loaded_from).size rescue next
description = spec.description || spec.summary || '' description = spec.description || spec.summary || ''

View file

@ -95,8 +95,7 @@ module Gem::InstallUpdateOptions
add_option(:"Install/Update", '--[no-]user-install', add_option(:"Install/Update", '--[no-]user-install',
'Install in user\'s home directory instead', 'Install in user\'s home directory instead',
'of GEM_HOME. Defaults to using home', 'of GEM_HOME.') do |value, options|
'only if GEM_HOME is not writable.') do |value, options|
options[:user_install] = value options[:user_install] = value
end end
@ -105,13 +104,6 @@ module Gem::InstallUpdateOptions
"dependencies") do |value, options| "dependencies") do |value, options|
options[:development] = true options[:development] = true
end end
add_option(:"Install/Update", "--prerelease",
"Install prerelease versions of a gem if",
"available. Defaults to skipping",
"prereleases.") do |value, options|
options[:prerelease] = true
end
end end
## ##

View file

@ -5,7 +5,6 @@
#++ #++
require 'fileutils' require 'fileutils'
require 'pathname'
require 'rbconfig' require 'rbconfig'
require 'rubygems/format' require 'rubygems/format'
@ -58,16 +57,10 @@ class Gem::Installer
attr_reader :spec attr_reader :spec
@home_install_warning = false
@path_warning = false @path_warning = false
class << self class << self
##
# True if we've warned about ~/.gems install
attr_accessor :home_install_warning
## ##
# True if we've warned about PATH not including Gem.bindir # True if we've warned about PATH not including Gem.bindir
@ -112,7 +105,7 @@ class Gem::Installer
@env_shebang = options[:env_shebang] @env_shebang = options[:env_shebang]
@force = options[:force] @force = options[:force]
gem_home = options[:install_dir] gem_home = options[:install_dir]
@gem_home = Pathname.new(gem_home).expand_path @gem_home = File.expand_path(gem_home)
@ignore_dependencies = options[:ignore_dependencies] @ignore_dependencies = options[:ignore_dependencies]
@format_executable = options[:format_executable] @format_executable = options[:format_executable]
@security_policy = options[:security_policy] @security_policy = options[:security_policy]
@ -127,27 +120,6 @@ class Gem::Installer
raise Gem::InstallError, "invalid gem format for #{@gem}" raise Gem::InstallError, "invalid gem format for #{@gem}"
end end
begin
FileUtils.mkdir_p @gem_home
rescue Errno::EACCES, Errno::ENOTDIR
# We'll divert to ~/.gems below
end
if not File.writable? @gem_home or
# TODO: Shouldn't have to test for existence of bindir; tests need it.
(@gem_home.to_s == Gem.dir and File.exist? Gem.bindir and
not File.writable? Gem.bindir) then
if options[:user_install] == false then # You don't want to use ~
raise Gem::FilePermissionError, @gem_home
elsif options[:user_install].nil? then
unless self.class.home_install_warning or options[:unpack] then
alert_warning "Installing to ~/.gem since #{@gem_home} and\n\t #{Gem.bindir} aren't both writable."
self.class.home_install_warning = true
end
end
options[:user_install] = true
end
if options[:user_install] and not options[:unpack] then if options[:user_install] and not options[:unpack] then
@gem_home = Gem.user_dir @gem_home = Gem.user_dir
@ -158,12 +130,11 @@ class Gem::Installer
self.class.path_warning = true self.class.path_warning = true
end end
end end
FileUtils.mkdir_p @gem_home unless File.directory? @gem_home
# If it's still not writable, you've got issues.
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
end end
FileUtils.mkdir_p @gem_home
raise Gem::FilePermissionError, @gem_home unless File.writable? @gem_home
@spec = @format.spec @spec = @format.spec
@gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint @gem_dir = File.join(@gem_home, "gems", @spec.full_name).untaint
@ -189,14 +160,15 @@ class Gem::Installer
unless @force then unless @force then
if rrv = @spec.required_ruby_version then if rrv = @spec.required_ruby_version then
unless rrv.satisfied_by? Gem.ruby_version then unless rrv.satisfied_by? Gem.ruby_version then
raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}" raise Gem::InstallError, "#{@spec.name} requires Ruby version #{rrv}."
end end
end end
if rrgv = @spec.required_rubygems_version then if rrgv = @spec.required_rubygems_version then
unless rrgv.satisfied_by? Gem::Version.new(Gem::RubyGemsVersion) then unless rrgv.satisfied_by? Gem::Version.new(Gem::RubyGemsVersion) then
raise Gem::InstallError, raise Gem::InstallError,
"#{@spec.name} requires RubyGems version #{rrgv}" "#{@spec.name} requires RubyGems version #{rrgv}. " +
"Try 'gem update --system' to update RubyGems itself."
end end
end end
@ -235,8 +207,7 @@ class Gem::Installer
say @spec.post_install_message unless @spec.post_install_message.nil? say @spec.post_install_message unless @spec.post_install_message.nil?
@spec.loaded_from = File.join(@gem_home, 'specifications', @spec.loaded_from = File.join(@gem_home, 'specifications', @spec.spec_name)
"#{@spec.full_name}.gemspec")
@source_index.add_spec @spec @source_index.add_spec @spec
@ -268,7 +239,7 @@ class Gem::Installer
# True if the gems in the source_index satisfy +dependency+. # True if the gems in the source_index satisfy +dependency+.
def installation_satisfies_dependency?(dependency) def installation_satisfies_dependency?(dependency)
@source_index.find_name(dependency.name, dependency.version_requirements).size > 0 @source_index.find_name(dependency.name, dependency.requirement).size > 0
end end
## ##
@ -287,8 +258,7 @@ class Gem::Installer
def write_spec def write_spec
rubycode = @spec.to_ruby rubycode = @spec.to_ruby
file_name = File.join @gem_home, 'specifications', file_name = File.join @gem_home, 'specifications', @spec.spec_name
"#{@spec.full_name}.gemspec"
file_name.untaint file_name.untaint
@ -522,7 +492,7 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
# Ensures that files can't be installed outside the gem directory. # Ensures that files can't be installed outside the gem directory.
def extract_files def extract_files
expand_and_validate_gem_dir @gem_dir = File.expand_path @gem_dir
raise ArgumentError, "format required to extract from" if @format.nil? raise ArgumentError, "format required to extract from" if @format.nil?
@ -566,24 +536,5 @@ Results logged to #{File.join(Dir.pwd, 'gem_make.out')}
end end
end end
private
##
# HACK Pathname is broken on windows.
def absolute_path? pathname
pathname.absolute? or (Gem.win_platform? and pathname.to_s =~ /\A[a-z]:/i)
end
def expand_and_validate_gem_dir
@gem_dir = Pathname.new(@gem_dir).expand_path
unless absolute_path?(@gem_dir) then # HACK is this possible after #expand_path?
raise ArgumentError, "install directory %p not absolute" % @gem_dir
end
@gem_dir = @gem_dir.to_s
end
end end

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.
@ -9,7 +10,6 @@ require 'stringio'
require 'yaml' require 'yaml'
require 'zlib' require 'zlib'
require 'rubygems/digest/md5'
require 'rubygems/security' require 'rubygems/security'
require 'rubygems/specification' require 'rubygems/specification'

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.
@ -199,7 +200,8 @@ class Gem::Package::TarInput
# times. And that's the way it is. # times. And that's the way it is.
def zipped_stream(entry) def zipped_stream(entry)
if defined? Rubinius then if defined? Rubinius or defined? Maglev then
# these implementations have working Zlib
zis = Zlib::GzipReader.new entry zis = Zlib::GzipReader.new entry
dis = zis.read dis = zis.read
is = StringIO.new(dis) is = StringIO.new(dis)

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.

View file

@ -1,3 +1,4 @@
# -*- coding: iso-8859-1 -*-
#++ #++
# Copyright (C) 2004 Mauricio Julio Fernández Pradier # Copyright (C) 2004 Mauricio Julio Fernández Pradier
# See LICENSE.txt for additional licensing information. # See LICENSE.txt for additional licensing information.

View file

@ -97,21 +97,26 @@ class Gem::PackageTask < Rake::PackageTask
def define def define
super super
task :package => [:gem]
desc "Build the gem file #{gem_file}"
task :gem => ["#{package_dir}/#{gem_file}"]
file "#{package_dir}/#{gem_file}" => [package_dir] + @gem_spec.files do
when_writing("Creating #{gem_spec.full_name}.gem") {
Gem::Builder.new(gem_spec).build
verbose(true) {
mv gem_file, "#{package_dir}/#{gem_file}"
}
}
end
end
def gem_file task :package => [:gem]
"#{@gem_spec.full_name}.gem"
gem_file = gem_spec.file_name
gem_path = File.join package_dir, gem_file
desc "Build the gem file #{gem_file}"
task :gem => [gem_path]
trace = Rake.application.options.trace
Gem.configuration.verbose = trace
file gem_path => [package_dir] + @gem_spec.files do
when_writing "Creating #{gem_spec.file_name}" do
Gem::Builder.new(gem_spec).build
verbose trace do
mv gem_file, gem_path
end
end
end
end end
end end

View file

@ -81,7 +81,7 @@ class Gem::RemoteFetcher
cache_dir = File.join(Gem.user_dir, 'cache') cache_dir = File.join(Gem.user_dir, 'cache')
end end
gem_file_name = "#{spec.full_name}.gem" gem_file_name = spec.file_name
local_gem_path = File.join cache_dir, gem_file_name local_gem_path = File.join cache_dir, gem_file_name
FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir FileUtils.mkdir_p cache_dir rescue nil unless File.exist? cache_dir
@ -138,12 +138,18 @@ class Gem::RemoteFetcher
say "Using local gem #{local_gem_path}" if say "Using local gem #{local_gem_path}" if
Gem.configuration.really_verbose Gem.configuration.really_verbose
when nil then # TODO test for local overriding cache when nil then # TODO test for local overriding cache
source_path = if Gem.win_platform? && source_uri.scheme &&
!source_uri.path.include?(':') then
"#{source_uri.scheme}:#{source_uri.path}"
else
source_uri.path
end
source_path = URI.unescape source_path
begin begin
if Gem.win_platform? && source_uri.scheme && !source_uri.path.include?(':') FileUtils.cp source_path, local_gem_path unless
FileUtils.cp URI.unescape(source_uri.scheme + ':' + source_uri.path), local_gem_path File.expand_path(source_path) == File.expand_path(local_gem_path)
else
FileUtils.cp URI.unescape(source_uri.path), local_gem_path
end
rescue Errno::EACCES rescue Errno::EACCES
local_gem_path = source_uri.to_s local_gem_path = source_uri.to_s
end end
@ -317,6 +323,8 @@ class Gem::RemoteFetcher
request.add_field 'If-Modified-Since', last_modified.rfc2822 request.add_field 'If-Modified-Since', last_modified.rfc2822
end end
yield request if block_given?
connection = connection_for uri connection = connection_for uri
retried = false retried = false
@ -324,10 +332,16 @@ class Gem::RemoteFetcher
begin begin
@requests[connection.object_id] += 1 @requests[connection.object_id] += 1
response = connection.request request
say "#{request.method} #{response.code} #{response.message}: #{uri}" if say "#{request.method} #{uri}" if
Gem.configuration.really_verbose Gem.configuration.really_verbose
response = connection.request request
say "#{response.code} #{response.message}" if
Gem.configuration.really_verbose
rescue Net::HTTPBadResponse rescue Net::HTTPBadResponse
say "bad response" if Gem.configuration.really_verbose
reset connection reset connection
raise FetchError.new('too many bad responses', uri) if bad_response raise FetchError.new('too many bad responses', uri) if bad_response
@ -337,7 +351,7 @@ class Gem::RemoteFetcher
# HACK work around EOFError bug in Net::HTTP # HACK work around EOFError bug in Net::HTTP
# NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible # NOTE Errno::ECONNABORTED raised a lot on Windows, and make impossible
# to install gems. # to install gems.
rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET rescue EOFError, Errno::ECONNABORTED, Errno::ECONNRESET, Errno::EPIPE
requests = @requests[connection.object_id] requests = @requests[connection.object_id]
say "connection reset after #{requests} requests, retrying" if say "connection reset after #{requests} requests, retrying" if
Gem.configuration.really_verbose Gem.configuration.really_verbose

View file

@ -1,41 +1,33 @@
#-- require "rubygems/version"
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
## ##
# Requirement version includes a prefaced comparator in addition # A Requirement is a set of one or more version restrictions. It supports a
# to a version number. # few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
#
# A Requirement object can actually contain multiple, er,
# requirements, as in (> 1.2, < 2.0).
class Gem::Requirement class Gem::Requirement
include Comparable include Comparable
attr_reader :requirements OPS = { #:nodoc:
OPS = {
"=" => lambda { |v, r| v == r }, "=" => lambda { |v, r| v == r },
"!=" => lambda { |v, r| v != r }, "!=" => lambda { |v, r| v != r },
">" => lambda { |v, r| v > r }, ">" => lambda { |v, r| v > r },
"<" => lambda { |v, r| v < r }, "<" => lambda { |v, r| v < r },
">=" => lambda { |v, r| v >= r }, ">=" => lambda { |v, r| v >= r },
"<=" => lambda { |v, r| v <= r }, "<=" => lambda { |v, r| v <= r },
"~>" => lambda { |v, r| v = v.release; v >= r && v < r.bump } "~>" => lambda { |v, r| v = v.release; v >= r && v < r.bump }
} }
OP_RE = OPS.keys.map{ |k| Regexp.quote k }.join '|' quoted = OPS.keys.map { |k| Regexp.quote k }.join "|"
PATTERN = /\A\s*(#{quoted})?\s*(#{Gem::Version::VERSION_PATTERN})\s*\z/
## ##
# Factory method to create a Gem::Requirement object. Input may be a # Factory method to create a Gem::Requirement object. Input may be
# Version, a String, or nil. Intended to simplify client code. # a Version, a String, or nil. Intended to simplify client code.
# #
# If the input is "weird", the default version requirement is returned. # If the input is "weird", the default version requirement is
# returned.
def self.create(input) def self.create input
case input case input
when Gem::Requirement then when Gem::Requirement then
input input
@ -43,9 +35,9 @@ class Gem::Requirement
new input new input
else else
if input.respond_to? :to_str then if input.respond_to? :to_str then
self.new [input.to_str] new [input.to_str]
else else
self.default default
end end
end end
end end
@ -58,113 +50,99 @@ class Gem::Requirement
# "A default "version requirement" can surely _only_ be '> 0'." # "A default "version requirement" can surely _only_ be '> 0'."
def self.default def self.default
self.new ['>= 0'] new '>= 0'
end end
## ##
# Constructs a Requirement from +requirements+ which can be a String, a # Parse +obj+, returning an <tt>[op, version]</tt> pair. +obj+ can
# Gem::Version, or an Array of those. See #parse for details on the # be a String or a Gem::Version.
# formatting of requirement strings. #
# If +obj+ is a String, it can be either a full requirement
# specification, like <tt>">= 1.2"</tt>, or a simple version number,
# like <tt>"1.2"</tt>.
#
# parse("> 1.0") # => [">", "1.0"]
# parse("1.0") # => ["=", "1.0"]
# parse(Gem::Version.new("1.0")) # => ["=, "1.0"]
def initialize(requirements) def self.parse obj
@requirements = case requirements return ["=", obj] if Gem::Version === obj
when Array then
requirements.map do |requirement| unless PATTERN =~ obj.to_s
parse(requirement) raise ArgumentError, "Illformed requirement [#{obj.inspect}]"
end end
else
[parse(requirements)] [$1 || "=", Gem::Version.new($2)]
end
@version = nil # Avoid warnings.
end end
## ##
# Marshal raw requirements, rather than the full object # An array of requirement pairs. The first element of the pair is
# the op, and the second is the Gem::Version.
attr_reader :requirements #:nodoc:
##
# Constructs a requirement from +requirements+. Requirements can be
# Strings, Gem::Versions, or Arrays of those. +nil+ and duplicate
# requirements are ignored. An empty set of +requirements+ is the
# same as <tt>">= 0"</tt>.
def initialize *requirements
requirements = requirements.flatten
requirements.compact!
requirements.uniq!
requirements << ">= 0" if requirements.empty?
@requirements = requirements.map! { |r| self.class.parse r }
end
def as_list # :nodoc:
requirements.map { |op, version| "#{op} #{version}" }
end
def hash # :nodoc:
requirements.hash
end
def marshal_dump # :nodoc: def marshal_dump # :nodoc:
[@requirements] [@requirements]
end end
## def marshal_load array # :nodoc:
# Load custom marshal format
def marshal_load(array) # :nodoc:
@requirements = array[0] @requirements = array[0]
@version = nil
end end
def to_s # :nodoc: def prerelease?
as_list.join(", ") requirements.any? { |r| r.last.prerelease? }
end end
def pretty_print(q) # :nodoc: def pretty_print q # :nodoc:
q.group 1, 'Gem::Requirement.new(', ')' do q.group 1, 'Gem::Requirement.new(', ')' do
q.pp as_list q.pp as_list
end end
end end
def as_list
normalize
@requirements.map do |op, version| "#{op} #{version}" end
end
def normalize
return if not defined? @version or @version.nil?
@requirements = [parse(@version)]
@nums = nil
@version = nil
@op = nil
end
## ##
# True if this requirement satisfied by the Gem::Version +version+. # True if +version+ satisfies this Requirement.
def satisfied_by?(version) def satisfied_by? version
normalize requirements.all? { |op, rv| OPS[op].call version, rv }
@requirements.all? { |op, rv| satisfy?(op, version, rv) }
end end
## def to_s # :nodoc:
# Is "+version+ +op+ +required_version+" satisfied? as_list.join ", "
def satisfy?(op, version, required_version)
OPS[op].call(version, required_version)
end end
def prerelease? def <=> other # :nodoc:
# TODO: why is @requirements a nested array?
@requirements.any?{ |r| r[1].prerelease? }
end
##
# Parse the version requirement obj returning the operator and version.
#
# The requirement can be a String or a Gem::Version. A String can be an
# operator (<, <=, =, >=, >, !=, ~>), a version number, or both, operator
# first.
def parse(obj)
case obj
when /^\s*(#{OP_RE})\s*(#{Gem::Version::VERSION_PATTERN})\s*$/o then
[$1, Gem::Version.new($2)]
when /^\s*(#{Gem::Version::VERSION_PATTERN})\s*$/o then
['=', Gem::Version.new($1)]
when /^\s*(#{OP_RE})\s*$/o then
[$1, Gem::Version.new('0')]
when Gem::Version then
['=', obj]
else
fail ArgumentError, "Illformed requirement [#{obj.inspect}]"
end
end
def <=>(other) # :nodoc:
to_s <=> other.to_s to_s <=> other.to_s
end end
def hash # :nodoc:
to_s.hash
end
end end
# :stopdoc:
# Gem::Version::Requirement is used in a lot of old YAML specs. It's aliased
# here for backwards compatibility. I'd like to remove this, maybe in RubyGems
# 2.0.
::Gem::Version::Requirement = ::Gem::Requirement
# :startdoc:

View file

@ -39,9 +39,9 @@ class Gem::Server
SEARCH = <<-SEARCH SEARCH = <<-SEARCH
<form class="headerSearch" name="headerSearchForm" method="get" action="/rdoc"> <form class="headerSearch" name="headerSearchForm" method="get" action="/rdoc">
<div id="search" style="float:right"> <div id="search" style="float:right">
<span>Filter/Search</span> <label for="q">Filter/Search</label>
<input id="q" type="text" style="width:10em" name="q"/> <input id="q" type="text" style="width:10em" name="q">
<button type="submit" style="display:none" /> <button type="submit" style="display:none"></button>
</div> </div>
</form> </form>
SEARCH SEARCH
@ -426,15 +426,17 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
RDOC_SEARCH RDOC_SEARCH
def self.run(options) def self.run(options)
new(options[:gemdir], options[:port], options[:daemon]).run new(options[:gemdir], options[:port], options[:daemon],
options[:addresses]).run
end end
def initialize(gem_dir, port, daemon) def initialize(gem_dir, port, daemon, addresses = nil)
Socket.do_not_reverse_lookup = true Socket.do_not_reverse_lookup = true
@gem_dir = gem_dir @gem_dir = gem_dir
@port = port @port = port
@daemon = daemon @daemon = daemon
@addresses = addresses
logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL logger = WEBrick::Log.new nil, WEBrick::BasicLog::FATAL
@server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger @server = WEBrick::HTTPServer.new :DoNotListen => true, :Logger => logger
@ -498,6 +500,37 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
end end
##
# Creates server sockets based on the addresses option. If no addresses
# were given a server socket for all interfaces is created.
def listen addresses = @addresses
addresses = [nil] unless addresses
listeners = 0
addresses.each do |address|
begin
@server.listen address, @port
@server.listeners[listeners..-1].each do |listener|
host, port = listener.addr.values_at 2, 1
host = "[#{host}]" if host =~ /:/ # we don't reverse lookup
say "Server started at http://#{host}:#{port}"
end
listeners = @server.listeners.length
rescue SystemCallError
next
end
end
if @server.listeners.empty? then
say "Unable to start a server."
say "Check for running servers or your --bind and --port arguments"
terminate_interaction 1
end
end
def quick(req, res) def quick(req, res)
@source_index.refresh! @source_index.refresh!
@ -566,7 +599,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
deps = spec.dependencies.map do |dep| deps = spec.dependencies.map do |dep|
{ "name" => dep.name, { "name" => dep.name,
"type" => dep.type, "type" => dep.type,
"version" => dep.version_requirements.to_s, } "version" => dep.requirement.to_s, }
end end
deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] } deps = deps.sort_by { |dep| [dep["name"].downcase, dep["version"]] }
@ -602,7 +635,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
"only_one_executable" => true, "only_one_executable" => true,
"full_name" => "rubygems-#{Gem::RubyGemsVersion}", "full_name" => "rubygems-#{Gem::RubyGemsVersion}",
"has_deps" => false, "has_deps" => false,
"homepage" => "http://rubygems.org/", "homepage" => "http://docs.rubygems.org/",
"name" => 'rubygems', "name" => 'rubygems',
"rdoc_installed" => true, "rdoc_installed" => true,
"summary" => "RubyGems itself", "summary" => "RubyGems itself",
@ -716,9 +749,7 @@ div.method-source-code pre { color: #ffdead; overflow: hidden; }
end end
def run def run
@server.listen nil, @port listen
say "Starting gem server on http://localhost:#{@port}/"
WEBrick::Daemon.start if @daemon WEBrick::Daemon.start if @daemon

View file

@ -303,7 +303,7 @@ class Gem::SourceIndex
version_requirement = platform_only || Gem::Requirement.default version_requirement = platform_only || Gem::Requirement.default
when Gem::Dependency then when Gem::Dependency then
only_platform = platform_only only_platform = platform_only
version_requirement = gem_pattern.version_requirements version_requirement = gem_pattern.requirement
gem_pattern = if Regexp === gem_pattern.name then gem_pattern = if Regexp === gem_pattern.name then
gem_pattern.name gem_pattern.name
elsif gem_pattern.name.empty? then elsif gem_pattern.name.empty? then

View file

@ -197,7 +197,7 @@ class Gem::SpecFetcher
if type == :all if type == :all
list.values.map do |gems| list.values.map do |gems|
gems.reject! { |g| g[1].prerelease? } gems.reject! { |g| !g[1] || g[1].prerelease? }
end end
end end
@ -242,7 +242,7 @@ class Gem::SpecFetcher
FileUtils.mkdir_p cache_dir FileUtils.mkdir_p cache_dir
open local_file, 'wb' do |io| open local_file, 'wb' do |io|
Marshal.dump specs, io io << spec_dump
end end
rescue rescue
end end

View file

@ -17,7 +17,7 @@ class Date; end # for ruby_code if date.rb wasn't required
# defined in a .gemspec file or a Rakefile, and looks like this: # defined in a .gemspec file or a Rakefile, and looks like this:
# #
# spec = Gem::Specification.new do |s| # spec = Gem::Specification.new do |s|
# s.name = 'rfoo' # s.name = 'example'
# s.version = '1.0' # s.version = '1.0'
# s.summary = 'Example gem specification' # s.summary = 'Example gem specification'
# ... # ...
@ -409,15 +409,19 @@ class Gem::Specification
# :startdoc: # :startdoc:
## ##
# Specification constructor. Assigns the default values to the attributes # Specification constructor. Assigns the default values to the
# and yields itself for further initialization. # attributes and yields itself for further
# initialization. Optionally takes +name+ and +version+.
def initialize def initialize name = nil, version = nil
@new_platform = nil @new_platform = nil
assign_defaults assign_defaults
@loaded = false @loaded = false
@loaded_from = nil @loaded_from = nil
self.name = name if name
self.version = version if version
yield self if block_given? yield self if block_given?
@@gather.call(self) if @@gather @@gather.call(self) if @@gather
@ -498,7 +502,7 @@ class Gem::Specification
def self.load(filename) def self.load(filename)
gemspec = nil gemspec = nil
fail "NESTED Specification.load calls not allowed!" if @@gather raise "NESTED Specification.load calls not allowed!" if @@gather
@@gather = proc { |gs| gemspec = gs } @@gather = proc { |gs| gemspec = gs }
data = File.read(filename) data = File.read(filename)
eval(data) eval(data)
@ -598,10 +602,12 @@ class Gem::Specification
end end
## ##
# The default (generated) file name of the gem. # The default (generated) file name of the gem. See also #spec_name.
#
# spec.file_name # => "example-1.0.gem"
def file_name def file_name
full_name + ".gem" full_name + '.gem'
end end
## ##
@ -620,7 +626,7 @@ class Gem::Specification
def satisfies_requirement?(dependency) def satisfies_requirement?(dependency)
return @name == dependency.name && return @name == dependency.name &&
dependency.version_requirements.satisfied_by?(@version) dependency.requirement.satisfied_by?(@version)
end end
## ##
@ -630,6 +636,15 @@ class Gem::Specification
[@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1] [@name, @version, @new_platform == Gem::Platform::RUBY ? -1 : 1]
end end
##
# The default name of the gemspec. See also #file_name
#
# spec.spec_name # => "example-1.0.gemspec"
def spec_name
full_name + '.gemspec'
end
def <=>(other) # :nodoc: def <=>(other) # :nodoc:
sort_obj <=> other.sort_obj sort_obj <=> other.sort_obj
end end
@ -1033,14 +1048,18 @@ class Gem::Specification
## ##
# :attr_accessor: rubygems_version # :attr_accessor: rubygems_version
# #
# The version of RubyGems used to create this gem # The version of RubyGems used to create this gem.
#
# Do not set this, it is set automatically when the gem is packaged.
required_attribute :rubygems_version, Gem::RubyGemsVersion required_attribute :rubygems_version, Gem::RubyGemsVersion
## ##
# :attr_accessor: specification_version # :attr_accessor: specification_version
# #
# The Gem::Specification version of this gemspec # The Gem::Specification version of this gemspec.
#
# Do not set this, it is set automatically when the gem is packaged.
required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION required_attribute :specification_version, CURRENT_SPECIFICATION_VERSION
@ -1062,6 +1081,8 @@ class Gem::Specification
# :attr_accessor: date # :attr_accessor: date
# #
# The date this gem was created # The date this gem was created
#
# Do not set this, it is set automatically when the gem is packaged.
required_attribute :date, TODAY required_attribute :date, TODAY
@ -1069,13 +1090,20 @@ class Gem::Specification
# :attr_accessor: summary # :attr_accessor: summary
# #
# A short summary of this gem's description. Displayed in `gem list -d`. # A short summary of this gem's description. Displayed in `gem list -d`.
#
# The description should be more detailed than the summary. For example,
# you might wish to copy the entire README into the description.
#
# As of RubyGems 1.3.2 newlines are no longer stripped.
required_attribute :summary required_attribute :summary
## ##
# :attr_accessor: require_paths # :attr_accessor: require_paths
# #
# 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.
#
# The default 'lib' is typically sufficient.
required_attribute :require_paths, ['lib'] required_attribute :require_paths, ['lib']
@ -1085,6 +1113,13 @@ class Gem::Specification
# :attr_accessor: email # :attr_accessor: email
# #
# A contact email for this gem # A contact email for this gem
#
# If you are providing multiple authors and multiple emails they should be
# in the same order such that:
#
# Hash[*spec.authors.zip(spec.emails).flatten]
#
# Gives a hash of author name to email address.
attribute :email attribute :email
@ -1122,6 +1157,8 @@ class Gem::Specification
# :attr_accessor: default_executable # :attr_accessor: default_executable
# #
# The default executable for this gem. # The default executable for this gem.
#
# This is not used.
attribute :default_executable attribute :default_executable
@ -1149,7 +1186,7 @@ class Gem::Specification
## ##
# :attr_accessor: required_ruby_version # :attr_accessor: required_ruby_version
# #
# The ruby of version required by this gem # The version of ruby required by this gem
attribute :required_ruby_version, Gem::Requirement.default attribute :required_ruby_version, Gem::Requirement.default
@ -1164,6 +1201,9 @@ class Gem::Specification
# :attr_accessor: platform # :attr_accessor: platform
# #
# The platform this gem runs on. See Gem::Platform for details. # The platform this gem runs on. See Gem::Platform for details.
#
# Setting this to any value other than Gem::Platform::RUBY or
# Gem::Platform::CURRENT is probably wrong.
attribute :platform, Gem::Platform::RUBY attribute :platform, Gem::Platform::RUBY
@ -1192,7 +1232,14 @@ class Gem::Specification
## ##
# :attr_accessor: authors # :attr_accessor: authors
# #
# The list of authors who wrote this gem # The list of author names who wrote this gem.
#
# If you are providing multiple authors and multiple emails they should be
# in the same order such that:
#
# Hash[*spec.authors.zip(spec.emails).flatten]
#
# Gives a hash of author name to email address.
array_attribute :authors array_attribute :authors
@ -1228,21 +1275,21 @@ class Gem::Specification
## ##
# :attr_accessor: rdoc_options # :attr_accessor: rdoc_options
# #
# An ARGV-style array of options to RDoc # An ARGV style array of options to RDoc
array_attribute :rdoc_options array_attribute :rdoc_options
## ##
# :attr_accessor: extra_rdoc_files # :attr_accessor: extra_rdoc_files
# #
# Extra files to add to RDoc # Extra files to add to RDoc such as README or doc/examples.txt
array_attribute :extra_rdoc_files array_attribute :extra_rdoc_files
## ##
# :attr_accessor: executables # :attr_accessor: executables
# #
# Executables included in the gem # Executables included in the gem.
array_attribute :executables array_attribute :executables
@ -1266,6 +1313,9 @@ class Gem::Specification
# :attr_reader: dependencies # :attr_reader: dependencies
# #
# A list of Gem::Dependency objects this gem depends on. # A list of Gem::Dependency objects this gem depends on.
#
# Use #add_dependency or #add_development_dependency to add dependencies to
# a gem.
array_attribute :dependencies array_attribute :dependencies

View file

@ -23,6 +23,7 @@ require 'rubygems/remote_fetcher'
class Gem::FakeFetcher class Gem::FakeFetcher
attr_reader :data attr_reader :data
attr_reader :last_request
attr_accessor :paths attr_accessor :paths
def initialize def initialize
@ -30,16 +31,20 @@ class Gem::FakeFetcher
@paths = [] @paths = []
end end
def fetch_path path, mtime = nil def find_data(path)
path = path.to_s path = path.to_s
@paths << path @paths << path
raise ArgumentError, 'need full URI' unless path =~ %r'^http://' raise ArgumentError, 'need full URI' unless path =~ %r'^https?://'
unless @data.key? path then unless @data.key? path then
raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path) raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path)
end end
data = @data[path] @data[path]
end
def fetch_path path, mtime = nil
data = find_data(path)
if data.respond_to?(:call) then if data.respond_to?(:call) then
data.call data.call
@ -52,6 +57,30 @@ class Gem::FakeFetcher
end end
end end
# Thanks, FakeWeb!
def open_uri_or_path(path)
data = find_data(path)
body, code, msg = data
response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
response.instance_variable_set(:@body, body)
response.instance_variable_set(:@read, true)
response
end
def request(uri, request_class, last_modified = nil)
data = find_data(uri)
body, code, msg = data
@last_request = request_class.new uri.request_uri
yield @last_request if block_given?
response = Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg)
response.instance_variable_set(:@body, body)
response.instance_variable_set(:@read, true)
response
end
def fetch_size(path) def fetch_size(path)
path = path.to_s path = path.to_s
@paths << path @paths << path
@ -68,7 +97,7 @@ class Gem::FakeFetcher
end end
def download spec, source_uri, install_dir = Gem.dir def download spec, source_uri, install_dir = Gem.dir
name = "#{spec.full_name}.gem" name = spec.file_name
path = File.join(install_dir, 'cache', name) path = File.join(install_dir, 'cache', name)
Gem.ensure_gem_subdirectories install_dir Gem.ensure_gem_subdirectories install_dir

View file

@ -1,28 +0,0 @@
#
# This file defines a $log variable for logging, and a time() method for
# recording timing information.
#
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'rubygems'
file, lineno = Gem.location_of_caller
warn "#{file}:#{lineno}:Warning: RubyGems' lib/rubygems/timer.rb deprecated and will be removed on or after June 2009."
$log = Object.new
# :stopdoc:
def $log.debug(message)
Gem.debug message
end
def time(msg, width=25, &block)
Gem.time(msg, width, &block)
end
# :startdoc:

View file

@ -202,7 +202,7 @@ class Gem::Uninstaller
spec.name, spec.version, spec.original_platform].join '-' spec.name, spec.version, spec.original_platform].join '-'
spec_dir = File.join spec.installation_path, 'specifications' spec_dir = File.join spec.installation_path, 'specifications'
gemspec = File.join spec_dir, "#{spec.full_name}.gemspec" gemspec = File.join spec_dir, spec.spec_name
unless File.exist? gemspec then unless File.exist? gemspec then
gemspec = File.join spec_dir, "#{original_platform_name}.gemspec" gemspec = File.join spec_dir, "#{original_platform_name}.gemspec"
@ -211,7 +211,7 @@ class Gem::Uninstaller
FileUtils.rm_rf gemspec FileUtils.rm_rf gemspec
cache_dir = File.join spec.installation_path, 'cache' cache_dir = File.join spec.installation_path, 'cache'
gem = File.join cache_dir, "#{spec.full_name}.gem" gem = File.join cache_dir, spec.file_name
unless File.exist? gem then unless File.exist? gem then
gem = File.join cache_dir, "#{original_platform_name}.gem" gem = File.join cache_dir, "#{original_platform_name}.gem"
@ -251,7 +251,7 @@ class Gem::Uninstaller
spec.dependent_gems.each do |gem,dep,satlist| spec.dependent_gems.each do |gem,dep,satlist|
msg << msg <<
("#{gem.name}-#{gem.version} depends on " + ("#{gem.name}-#{gem.version} depends on " +
"[#{dep.name} (#{dep.version_requirements})]") "[#{dep.name} (#{dep.requirement})]")
end end
msg << 'If you remove this gems, one or more dependencies will not be met.' msg << 'If you remove this gems, one or more dependencies will not be met.'
msg << 'Continue with Uninstall?' msg << 'Continue with Uninstall?'

View file

@ -112,6 +112,7 @@ module Gem::UserInteraction
:alert_error, :alert_error,
:alert_warning, :alert_warning,
:ask, :ask,
:ask_for_password,
:ask_yes_no, :ask_yes_no,
:choose_from_list, :choose_from_list,
:say, :say,
@ -217,6 +218,50 @@ class Gem::StreamUI
result result
end end
##
# Ask for a password. Does not echo response to terminal.
def ask_for_password(question)
return nil if not @ins.tty?
@outs.print(question + " ")
@outs.flush
Gem.win_platform? ? ask_for_password_on_windows : ask_for_password_on_unix
end
##
# Asks for a password that works on windows. Ripped from the Heroku gem.
def ask_for_password_on_windows
require "Win32API"
char = nil
password = ''
while char = Win32API.new("crtdll", "_getch", [ ], "L").Call do
break if char == 10 || char == 13 # received carriage return or newline
if char == 127 || char == 8 # backspace and delete
password.slice!(-1, 1)
else
password << char.chr
end
end
puts
password
end
##
# Asks for a password that works on unix
def ask_for_password_on_unix
system "stty -echo"
password = @ins.gets
password.chomp! if password
system "stty echo"
password
end
## ##
# Display a statement. # Display a statement.

View file

@ -93,9 +93,8 @@ class Gem::Validator
next unless gems.include? gem_spec.name unless gems.empty? next unless gems.include? gem_spec.name unless gems.empty?
install_dir = gem_spec.installation_path install_dir = gem_spec.installation_path
gem_path = File.join(install_dir, "cache", gem_spec.full_name) + ".gem" gem_path = File.join install_dir, "cache", gem_spec.file_name
spec_path = File.join(install_dir, "specifications", spec_path = File.join install_dir, "specifications", gem_spec.spec_name
gem_spec.full_name) + ".gemspec"
gem_directory = gem_spec.full_gem_path gem_directory = gem_spec.full_gem_path
unless File.directory? gem_directory then unless File.directory? gem_directory then

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
## ##
# The Version class processes string versions into comparable # The Version class processes string versions into comparable
# values. A version string should normally be a series of numbers # values. A version string should normally be a series of numbers
@ -24,72 +18,153 @@
# 2. 1.0.b # 2. 1.0.b
# 3. 1.0.a # 3. 1.0.a
# 4. 0.9 # 4. 0.9
#
# == How Software Changes
#
# Users expect to be able to specify a version constraint that gives them
# some reasonable expectation that new versions of a library will work with
# their software if the version constraint is true, and not work with their
# software if the version constraint is false. In other words, the perfect
# system will accept all compatible versions of the library and reject all
# incompatible versions.
#
# Libraries change in 3 ways (well, more than 3, but stay focused here!).
#
# 1. The change may be an implementation detail only and have no effect on
# the client software.
# 2. The change may add new features, but do so in a way that client software
# written to an earlier version is still compatible.
# 3. The change may change the public interface of the library in such a way
# that old software is no longer compatible.
#
# Some examples are appropriate at this point. Suppose I have a Stack class
# that supports a <tt>push</tt> and a <tt>pop</tt> method.
#
# === Examples of Category 1 changes:
#
# * Switch from an array based implementation to a linked-list based
# implementation.
# * Provide an automatic (and transparent) backing store for large stacks.
#
# === Examples of Category 2 changes might be:
#
# * Add a <tt>depth</tt> method to return the current depth of the stack.
# * Add a <tt>top</tt> method that returns the current top of stack (without
# changing the stack).
# * Change <tt>push</tt> so that it returns the item pushed (previously it
# had no usable return value).
#
# === Examples of Category 3 changes might be:
#
# * Changes <tt>pop</tt> so that it no longer returns a value (you must use
# <tt>top</tt> to get the top of the stack).
# * Rename the methods to <tt>push_item</tt> and <tt>pop_item</tt>.
#
# == RubyGems Rational Versioning
#
# * Versions shall be represented by three non-negative integers, separated
# by periods (e.g. 3.1.4). The first integers is the "major" version
# number, the second integer is the "minor" version number, and the third
# integer is the "build" number.
#
# * A category 1 change (implementation detail) will increment the build
# number.
#
# * A category 2 change (backwards compatible) will increment the minor
# version number and reset the build number.
#
# * A category 3 change (incompatible) will increment the major build number
# and reset the minor and build numbers.
#
# * Any "public" release of a gem should have a different version. Normally
# that means incrementing the build number. This means a developer can
# generate builds all day long for himself, but as soon as he/she makes a
# public release, the version must be updated.
#
# === Examples
#
# Let's work through a project lifecycle using our Stack example from above.
#
# Version 0.0.1:: The initial Stack class is release.
# Version 0.0.2:: Switched to a linked=list implementation because it is
# cooler.
# Version 0.1.0:: Added a <tt>depth</tt> method.
# Version 1.0.0:: Added <tt>top</tt> and made <tt>pop</tt> return nil
# (<tt>pop</tt> used to return the old top item).
# Version 1.1.0:: <tt>push</tt> now returns the value pushed (it used it
# return nil).
# Version 1.1.1:: Fixed a bug in the linked list implementation.
# Version 1.1.2:: Fixed a bug introduced in the last fix.
#
# Client A needs a stack with basic push/pop capability. He writes to the
# original interface (no <tt>top</tt>), so his version constraint looks
# like:
#
# gem 'stack', '~> 0.0'
#
# Essentially, any version is OK with Client A. An incompatible change to
# the library will cause him grief, but he is willing to take the chance (we
# call Client A optimistic).
#
# Client B is just like Client A except for two things: (1) He uses the
# <tt>depth</tt> method and (2) he is worried about future
# incompatibilities, so he writes his version constraint like this:
#
# gem 'stack', '~> 0.1'
#
# The <tt>depth</tt> method was introduced in version 0.1.0, so that version
# or anything later is fine, as long as the version stays below version 1.0
# where incompatibilities are introduced. We call Client B pessimistic
# because he is worried about incompatible future changes (it is OK to be
# pessimistic!).
#
# == Preventing Version Catastrophe:
#
# From: http://blog.zenspider.com/2008/10/rubygems-howto-preventing-cata.html
#
# Let's say you're depending on the fnord gem version 2.y.z. If you
# specify your dependency as ">= 2.0.0" then, you're good, right? What
# happens if fnord 3.0 comes out and it isn't backwards compatible
# with 2.y.z? Your stuff will break as a result of using ">=". The
# better route is to specify your dependency with a "spermy" version
# specifier. They're a tad confusing, so here is how the dependency
# specifiers work:
#
# Specification From ... To (exclusive)
# ">= 3.0" 3.0 ... &infin;
# "~> 3.0" 3.0 ... 4.0
# "~> 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 class Gem::Version
class Part
include Comparable
attr_reader :value
def initialize(value)
@value = (value =~ /\A\d+\z/) ? value.to_i : value
end
def to_s
self.value.to_s
end
def inspect
@value
end
def alpha?
String === value
end
def numeric?
Fixnum === value
end
def <=>(other)
if self.numeric? && other.alpha? then
1
elsif self.alpha? && other.numeric? then
-1
else
self.value <=> other.value
end
end
def succ
self.class.new(self.value.succ)
end
end
include Comparable include Comparable
VERSION_PATTERN = '[0-9]+(\.[0-9a-z]+)*' VERSION_PATTERN = '[0-9]+(\.[0-9a-zA-Z]+)*' # :nodoc:
ANCHORED_VERSION_PATTERN = /\A\s*(#{VERSION_PATTERN})*\s*\z/ # :nodoc:
##
# A string representation of this Version.
attr_reader :version attr_reader :version
alias to_s version
def self.correct?(version) ##
pattern = /\A\s*(#{VERSION_PATTERN})*\s*\z/ # True if the +version+ string matches RubyGems' requirements.
version.is_a? Integer or def self.correct? version
version =~ pattern or version.to_s =~ ANCHORED_VERSION_PATTERN
version.to_s =~ pattern
end end
## ##
# Factory method to create a Version object. Input may be a Version or a # Factory method to create a Version object. Input may be a Version
# String. Intended to simplify client code. # or a String. Intended to simplify client code.
# #
# ver1 = Version.create('1.3.17') # -> (Version object) # ver1 = Version.create('1.3.17') # -> (Version object)
# ver2 = Version.create(ver1) # -> (ver1) # ver2 = Version.create(ver1) # -> (ver1)
# ver3 = Version.create(nil) # -> nil # ver3 = Version.create(nil) # -> nil
def self.create(input) def self.create input
if input.respond_to? :version then if input.respond_to? :version then
input input
elsif input.nil? then elsif input.nil? then
@ -103,149 +178,129 @@ class Gem::Version
# Constructs a Version from the +version+ string. A version string is a # Constructs a Version from the +version+ string. A version string is a
# series of digits or ASCII letters separated by dots. # series of digits or ASCII letters separated by dots.
def initialize(version) def initialize version
raise ArgumentError, "Malformed version number string #{version}" unless raise ArgumentError, "Malformed version number string #{version}" unless
self.class.correct?(version) self.class.correct?(version)
self.version = version @version = version.to_s
@version.strip!
segments # prime @segments
end
##
# Return a new version object where the next to the last revision
# number is one greater (e.g., 5.3.1 => 5.4).
#
# Pre-release (alpha) parts, e.g, 5.3.1.b2 => 5.4, are ignored.
def bump
segments = self.segments.dup
segments.pop while segments.any? { |s| String === s }
segments.pop if segments.size > 1
segments[-1] = segments[-1].succ
self.class.new segments.join(".")
end
##
# A Version is only eql? to another version if it's specified to the
# same precision. Version "1.0" is not the same as version "1".
def eql? other
self.class === other and segments == other.segments
end
def hash # :nodoc:
segments.hash
end end
def inspect # :nodoc: def inspect # :nodoc:
"#<#{self.class} #{@version.inspect}>" "#<#{self.class} #{version.inspect}>"
end end
## ##
# Dump only the raw version string, not the complete object # Dump only the raw version string, not the complete object. It's a
# string for backwards (RubyGems 1.3.5 and earlier) compatibility.
def marshal_dump def marshal_dump
[@version] [version]
end end
## ##
# Load custom marshal format # Load custom marshal format. It's a string for backwards (RubyGems
# 1.3.5 and earlier) compatibility.
def marshal_load(array) def marshal_load array
self.version = array[0] initialize array[0]
end end
def parts
@parts ||= normalize
end
## ##
# Strip ignored trailing zeros. # A version is considered a prerelease if it contains a letter.
def normalize
parts_arr = parse_parts_from_version_string
if parts_arr.length != 1
parts_arr.pop while parts_arr.last && parts_arr.last.value == 0
parts_arr = [Part.new(0)] if parts_arr.empty?
end
parts_arr
end
##
# Returns the text representation of the version
def to_s
@version
end
def to_yaml_properties
['@version']
end
def version=(version)
@version = version.to_s.strip
normalize
end
##
# A version is considered a prerelease if any part contains a letter.
def prerelease? def prerelease?
parts.any? { |part| part.alpha? } @prerelease ||= segments.any? { |s| String === s }
end
def pretty_print q # :nodoc:
q.text "Gem::Version.new(#{version.inspect})"
end
##
# The release for this version (e.g. 1.2.0.a -> 1.2.0).
# Non-prerelease versions return themselves.
def release
return self unless prerelease?
segments = self.segments.dup
segments.pop while segments.any? { |s| String === s }
self.class.new segments.join('.')
end
def segments # :nodoc:
# @segments is lazy so it can pick up @version values that come
# from old marshaled versions, which don't go through
# marshal_load. +segments+ is called in +initialize+ to "prime
# the pump" in normal cases.
@segments ||= @version.scan(/[0-9a-z]+/i).map do |s|
/^\d+$/ =~ s ? s.to_i : s
end
end end
## ##
# The release for this version (e.g. 1.2.0.a -> 1.2.0) # A recommended version for use with a ~> Requirement.
# Non-prerelease versions return themselves
def release
return self unless prerelease?
rel_parts = parts.dup
rel_parts.pop while rel_parts.any? { |part| part.alpha? }
self.class.new(rel_parts.join('.'))
end
def yaml_initialize(tag, values) def spermy_recommendation
self.version = values['version'] segments = self.segments.dup
segments.pop while segments.any? { |s| String === s }
segments.pop while segments.size > 2
segments.push 0 while segments.size < 2
"~> #{segments.join(".")}"
end end
## ##
# Compares this version with +other+ returning -1, 0, or 1 if the other # Compares this version with +other+ returning -1, 0, or 1 if the other
# version is larger, the same, or smaller than this one. # version is larger, the same, or smaller than this one.
def <=>(other) def <=> other
return 1 unless other # HACK: comparable with nil? why?
return nil unless self.class === other return nil unless self.class === other
return 1 unless other
mine, theirs = balance(self.parts.dup, other.parts.dup) lhsize = segments.size
mine <=> theirs rhsize = other.segments.size
limit = (lhsize > rhsize ? lhsize : rhsize) - 1
0.upto(limit) do |i|
lhs, rhs = segments[i] || 0, other.segments[i] || 0
return -1 if String === lhs && Numeric === rhs
return 1 if Numeric === lhs && String === rhs
return lhs <=> rhs if lhs != rhs
end
return 0
end end
def balance(a, b)
a << Part.new(0) while a.size < b.size
b << Part.new(0) while b.size < a.size
[a, b]
end
##
# A Version is only eql? to another version if it has the same version
# string. "1.0" is not the same version as "1".
def eql?(other)
self.class === other and @version == other.version
end
def hash # :nodoc:
@version.hash
end
##
# Return a new version object where the next to the last revision number is
# one greater. (e.g. 5.3.1 => 5.4)
#
# Pre-release (alpha) parts are ignored. (e.g 5.3.1.b2 => 5.4)
def bump
parts = parse_parts_from_version_string
parts.pop while parts.any? { |part| part.alpha? }
parts.pop if parts.size > 1
parts[-1] = parts[-1].succ
self.class.new(parts.join("."))
end
def parse_parts_from_version_string # :nodoc:
@version.to_s.scan(/[0-9a-z]+/i).map { |s| Part.new(s) }
end
def pretty_print(q) # :nodoc:
q.text "Gem::Version.new(#{@version.inspect})"
end
#:stopdoc:
require 'rubygems/requirement'
##
# Gem::Requirement's original definition is nested in Version.
# Although an inappropriate place, current gems specs reference the nested
# class name explicitly. To remain compatible with old software loading
# gemspecs, we leave a copy of original definition in Version, but define an
# alias Gem::Requirement for use everywhere else.
Requirement = ::Gem::Requirement
# :startdoc:
end end

View file

@ -6,10 +6,14 @@
require 'rubygems' require 'rubygems'
##
# Mixin methods for --version and --platform Gem::Command options. # Mixin methods for --version and --platform Gem::Command options.
module Gem::VersionOption module Gem::VersionOption
##
# Add the --platform option to the option parser. # Add the --platform option to the option parser.
def add_platform_option(task = command, *wrap) def add_platform_option(task = command, *wrap)
OptionParser.accept Gem::Platform do |value| OptionParser.accept Gem::Platform do |value|
if value == Gem::Platform::RUBY then if value == Gem::Platform::RUBY then
@ -31,7 +35,19 @@ module Gem::VersionOption
end end
end end
##
# Add the --prerelease option to the option parser.
def add_prerelease_option(*wrap)
add_option("--[no-]prerelease",
"Allow prerelease versions of a gem", *wrap) do |value, options|
options[:prerelease] = value
end
end
##
# Add the --version option to the option parser. # Add the --version option to the option parser.
def add_version_option(task = command, *wrap) def add_version_option(task = command, *wrap)
OptionParser.accept Gem::Requirement do |value| OptionParser.accept Gem::Requirement do |value|
Gem::Requirement.new value Gem::Requirement.new value

View file

@ -4,4 +4,4 @@
# See LICENSE.txt for permissions. # See LICENSE.txt for permissions.
#++ #++
fail LoadError, "no such file to load -- openssl" raise LoadError, "no such file to load -- openssl"

View file

@ -1,10 +1,3 @@
#!/usr/bin/env ruby
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'rubygems' require 'rubygems'
require 'minitest/unit' require 'minitest/unit'
require 'test/insure_session' require 'test/insure_session'

View file

@ -20,12 +20,12 @@ class GemInstallerTestCase < RubyGemTestCase
super super
@spec = quick_gem 'a' @spec = quick_gem 'a'
@gem = File.join @tempdir, "#{@spec.full_name}.gem" @gem = File.join @tempdir, @spec.file_name
@installer = util_installer @spec, @gem, @gemhome @installer = util_installer @spec, @gem, @gemhome
@user_spec = quick_gem 'b' @user_spec = quick_gem 'b'
@user_gem = File.join @tempdir, "#{@user_spec.full_name}.gem" @user_gem = File.join @tempdir, @user_spec.file_name
@user_installer = util_installer @user_spec, @user_gem, Gem.user_dir @user_installer = util_installer @user_spec, @user_gem, Gem.user_dir
@user_installer.gem_dir = File.join(Gem.user_dir, 'gems', @user_installer.gem_dir = File.join(Gem.user_dir, 'gems',
@ -82,7 +82,7 @@ class GemInstallerTestCase < RubyGemTestCase
def util_installer(spec, gem_path, gem_home) def util_installer(spec, gem_path, gem_home)
util_build_gem spec util_build_gem spec
FileUtils.mv File.join(@gemhome, 'cache', "#{spec.full_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', spec.file_name),
@tempdir @tempdir
installer = Gem::Installer.new gem_path installer = Gem::Installer.new gem_path

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
at_exit { $SAFE = 1 } at_exit { $SAFE = 1 }
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
@ -82,6 +76,8 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
@orig_ruby = ruby @orig_ruby = ruby
end end
Gem.ensure_gem_subdirectories @gemhome
@orig_ENV_HOME = ENV['HOME'] @orig_ENV_HOME = ENV['HOME']
ENV['HOME'] = @userhome ENV['HOME'] = @userhome
Gem.instance_variable_set :@user_home, nil Gem.instance_variable_set :@user_home, nil
@ -159,7 +155,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
Gem.clear_paths Gem.clear_paths
if ruby = @orig_ruby if ruby = @orig_ruby
Gem.class_eval {@ruby = @ruby} Gem.class_eval {@ruby = ruby}
end end
if @orig_ENV_HOME then if @orig_ENV_HOME then
@ -178,7 +174,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
end end
end end
gem = File.join(@tempdir, "#{gem.full_name}.gem").untaint gem = File.join(@tempdir, gem.file_name).untaint
Gem::Installer.new(gem, :wrappers => true).install Gem::Installer.new(gem, :wrappers => true).install
end end
@ -256,7 +252,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
yield(s) if block_given? yield(s) if block_given?
end end
path = File.join "specifications", "#{spec.full_name}.gemspec" path = File.join "specifications", spec.spec_name
written_path = write_file path do |io| written_path = write_file path do |io|
io.write(spec.to_ruby) io.write(spec.to_ruby)
end end
@ -283,7 +279,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
Gem::Builder.new(spec).build Gem::Builder.new(spec).build
end end
FileUtils.mv "#{spec.full_name}.gem", FileUtils.mv spec.file_name,
File.join(@gemhome, 'cache', "#{spec.original_name}.gem") File.join(@gemhome, 'cache', "#{spec.original_name}.gem")
end end
end end
@ -302,8 +298,7 @@ class RubyGemTestCase < MiniTest::Unit::TestCase
cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"),
cache_file cache_file
FileUtils.rm File.join(@gemhome, 'specifications', FileUtils.rm File.join(@gemhome, 'specifications', spec.spec_name)
"#{spec.full_name}.gemspec")
spec.loaded_from = nil spec.loaded_from = nil
spec.loaded = false spec.loaded = false
@ -417,26 +412,6 @@ Also, a list:
Gem::RemoteFetcher.fetcher = @fetcher Gem::RemoteFetcher.fetcher = @fetcher
end end
def util_setup_source_info_cache(*specs)
require 'rubygems/source_info_cache'
require 'rubygems/source_info_cache_entry'
specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
si = Gem::SourceIndex.new specs
sice = Gem::SourceInfoCacheEntry.new si, 0
sic = Gem::SourceInfoCache.new
sic.set_cache_data( { @gem_repo => sice } )
sic.update
sic.write_cache
sic.reset_cache_data
Gem::SourceInfoCache.instance_variable_set :@cache, sic
si
end
def util_setup_spec_fetcher(*specs) def util_setup_spec_fetcher(*specs)
specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten] specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
si = Gem::SourceIndex.new specs si = Gem::SourceIndex.new specs
@ -583,6 +558,35 @@ Also, a list:
'rake' 'rake'
end end
##
# Construct a new Gem::Dependency.
def dep name, *requirements
Gem::Dependency.new name, *requirements
end
##
# Construct a new Gem::Requirement.
def req *requirements
return requirements.first if Gem::Requirement === requirements.first
Gem::Requirement.create requirements
end
##
# Construct a new Gem::Specification.
def spec name, version, &block
Gem::Specification.new name, v(version), &block
end
##
# Construct a new Gem::Version.
def v string
Gem::Version.create string
end
end end
MiniTest::Unit.autorun MiniTest::Unit.autorun

View file

@ -1,11 +1,3 @@
#!/usr/bin/env ruby
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'rubygems' require 'rubygems'
def install_session def install_session

View file

@ -1,11 +1,3 @@
#!/usr/bin/env ruby
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require 'stringio' require 'stringio'
require 'rubygems/user_interaction' require 'rubygems/user_interaction'

View file

@ -1,10 +1,4 @@
#-- SIMPLE_GEM = <<-GEMDATA
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
SIMPLE_GEM = <<-GEMDATA
MD5SUM = "b12a4d48febeb2289c539c2574c4b6f8" MD5SUM = "b12a4d48febeb2289c539c2574c4b6f8"
if $0 == __FILE__ if $0 == __FILE__
require 'optparse' require 'optparse'
@ -69,4 +63,4 @@ g1CKTjX9BGAj1w==
eJwDAAAAAAE= eJwDAAAAAAE=
--- ---
eJwrKC0pVlAvzy9XyE3MU+cCACwiBP4= eJwrKC0pVlAvzy9XyE3MU+cCACwiBP4=
GEMDATA GEMDATA

View file

@ -1,11 +1,4 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rbconfig'
require 'rubygems' require 'rubygems'
class TestConfig < RubyGemTestCase class TestConfig < RubyGemTestCase

View file

@ -181,7 +181,7 @@ class TestGem < RubyGemTestCase
end end
def test_self_default_sources def test_self_default_sources
assert_equal %w[http://gems.rubyforge.org/], Gem.default_sources assert_equal %w[http://rubygems.org/], Gem.default_sources
end end
def test_self_dir def test_self_dir
@ -441,13 +441,13 @@ class TestGem < RubyGemTestCase
def test_self_refresh def test_self_refresh
util_make_gems util_make_gems
a1_spec = File.join @gemhome, "specifications", "#{@a1.full_name}.gemspec" a1_spec = File.join @gemhome, "specifications", @a1.spec_name
FileUtils.mv a1_spec, @tempdir FileUtils.mv a1_spec, @tempdir
refute Gem.source_index.gems.include?(@a1.full_name) refute Gem.source_index.gems.include?(@a1.full_name)
FileUtils.mv File.join(@tempdir, "#{@a1.full_name}.gemspec"), a1_spec FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec
Gem.refresh Gem.refresh

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/builder' require 'rubygems/builder'

View file

@ -1,10 +1,3 @@
#!/usr/bin/env ruby
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/command' require 'rubygems/command'

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/command_manager' require 'rubygems/command_manager'

View file

@ -15,7 +15,7 @@ class TestGemCommandsBuildCommand < RubyGemTestCase
end end
def test_execute def test_execute
gemspec_file = File.join(@tempdir, "#{@gem.full_name}.gemspec") gemspec_file = File.join(@tempdir, @gem.spec_name)
File.open gemspec_file, 'w' do |gs| File.open gemspec_file, 'w' do |gs|
gs.write @gem.to_ruby gs.write @gem.to_ruby
@ -25,7 +25,7 @@ class TestGemCommandsBuildCommand < RubyGemTestCase
end end
def test_execute_yaml def test_execute_yaml
gemspec_file = File.join(@tempdir, "#{@gem.full_name}.gemspec") gemspec_file = File.join(@tempdir, @gem.spec_name)
File.open gemspec_file, 'w' do |gs| File.open gemspec_file, 'w' do |gs|
gs.write @gem.to_yaml gs.write @gem.to_yaml
@ -61,7 +61,7 @@ class TestGemCommandsBuildCommand < RubyGemTestCase
assert_equal [], output assert_equal [], output
assert_equal '', @ui.error assert_equal '', @ui.error
gem_file = File.join @tempdir, "#{gem.full_name}.gem" gem_file = File.join @tempdir, gem.file_name
assert File.exist?(gem_file) assert File.exist?(gem_file)
spec = Gem::Format.from_file_by_path(gem_file).spec spec = Gem::Format.from_file_by_path(gem_file).spec

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/commands/check_command' require 'rubygems/commands/check_command'

View file

@ -9,12 +9,13 @@ class TestGemCommandsDependencyCommand < RubyGemTestCase
@cmd = Gem::Commands::DependencyCommand.new @cmd = Gem::Commands::DependencyCommand.new
@cmd.options[:domain] = :local @cmd.options[:domain] = :local
util_setup_fake_fetcher util_setup_fake_fetcher true
end end
def test_execute def test_execute
quick_gem 'foo' do |gem| quick_gem 'foo' do |gem|
gem.add_dependency 'bar', '> 1' gem.add_dependency 'bar', '> 1'
gem.add_dependency 'baz', '> 1'
end end
Gem.source_index = nil Gem.source_index = nil
@ -25,7 +26,8 @@ class TestGemCommandsDependencyCommand < RubyGemTestCase
@cmd.execute @cmd.execute
end end
assert_equal "Gem foo-2\n bar (> 1, runtime)\n\n", @ui.output assert_equal "Gem foo-2\n bar (> 1, runtime)\n baz (> 1, runtime)\n\n",
@ui.output
assert_equal '', @ui.error assert_equal '', @ui.error
end end
@ -41,6 +43,8 @@ class TestGemCommandsDependencyCommand < RubyGemTestCase
expected = <<-EOF expected = <<-EOF
Gem a-1 Gem a-1
Gem a-2.a
Gem a-2 Gem a-2
Gem a-3.a Gem a-3.a
@ -100,6 +104,8 @@ Gem pl-1-x86-linux
expected = <<-EOF expected = <<-EOF
Gem a-1 Gem a-1
Gem a-2.a
Gem a-2 Gem a-2
Gem a-3.a Gem a-3.a
@ -173,8 +179,7 @@ ERROR: Only reverse dependencies for local gems are supported.
util_setup_spec_fetcher foo util_setup_spec_fetcher foo
FileUtils.rm File.join(@gemhome, 'specifications', FileUtils.rm File.join(@gemhome, 'specifications', foo.spec_name)
"#{foo.full_name}.gemspec")
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:domain] = :remote @cmd.options[:domain] = :remote
@ -187,43 +192,24 @@ ERROR: Only reverse dependencies for local gems are supported.
assert_equal '', @ui.error assert_equal '', @ui.error
end end
def test_execute_remote_legacy def test_execute_prerelease
foo = quick_gem 'foo' do |gem|
gem.add_dependency 'bar', '> 1'
end
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher Gem::RemoteFetcher.fetcher = @fetcher
Gem::SpecFetcher.fetcher = nil util_setup_spec_fetcher @a2_pre
si = util_setup_source_info_cache foo
@fetcher.data["#{@gem_repo}yaml"] = YAML.dump si FileUtils.rm File.join(@gemhome, 'specifications', @a2_pre.spec_name)
@fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] =
si.dump
@fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz" @cmd.options[:args] = %w[a]
FileUtils.rm File.join(@gemhome, 'specifications',
"#{foo.full_name}.gemspec")
@cmd.options[:args] = %w[foo]
@cmd.options[:domain] = :remote @cmd.options[:domain] = :remote
@cmd.options[:prerelease] = true
use_ui @ui do use_ui @ui do
@cmd.execute @cmd.execute
end end
assert_equal "Gem foo-2\n bar (> 1, runtime)\n\n", @ui.output assert_equal "Gem a-2.a\n\n", @ui.output
assert_equal '', @ui.error
expected = <<-EOF
WARNING: RubyGems 1.2+ index not found for:
\t#{@gem_repo}
RubyGems will revert to legacy indexes degrading performance.
EOF
assert_equal expected, @ui.error
end end
end end

View file

@ -15,8 +15,8 @@ class TestGemCommandsFetchCommand < RubyGemTestCase
util_setup_fake_fetcher util_setup_fake_fetcher
util_setup_spec_fetcher @a2 util_setup_spec_fetcher @a2
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
File.read(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) File.read(File.join(@gemhome, 'cache', @a2.file_name))
@cmd.options[:args] = [@a2.name] @cmd.options[:args] = [@a2.name]
@ -26,19 +26,21 @@ class TestGemCommandsFetchCommand < RubyGemTestCase
end end
end end
assert File.exist?(File.join(@tempdir, "#{@a2.full_name}.gem")), assert File.exist?(File.join(@tempdir, @a2.file_name)),
"#{@a2.full_name} fetched" "#{@a2.full_name} fetched"
end end
def test_execute_legacy def test_execute_prerelease
util_setup_fake_fetcher util_setup_fake_fetcher true
util_setup_source_info_cache @a2 util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}yaml"] = '' @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = File.read(File.join(@gemhome, 'cache', @a2.file_name))
File.read(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
File.read(File.join(@gemhome, 'cache', @a2_pre.file_name))
@cmd.options[:args] = [@a2.name] @cmd.options[:args] = [@a2.name]
@cmd.options[:prerelease] = true
use_ui @ui do use_ui @ui do
Dir.chdir @tempdir do Dir.chdir @tempdir do
@ -46,8 +48,8 @@ class TestGemCommandsFetchCommand < RubyGemTestCase
end end
end end
assert File.exist?(File.join(@tempdir, "#{@a2.full_name}.gem")), assert File.exist?(File.join(@tempdir, @a2_pre.file_name)),
"#{@a2.full_name} fetched" "#{@a2_pre.full_name} not fetched"
end end
end end

View file

@ -15,10 +15,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher(:prerelease) util_setup_fake_fetcher(:prerelease)
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2.file_name))
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2_pre.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name))
@cmd.options[:args] = [@a2.name] @cmd.options[:args] = [@a2.name]
@ -37,10 +37,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher(:prerelease) util_setup_fake_fetcher(:prerelease)
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2.file_name))
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2_pre.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name))
@cmd.handle_options [@a2_pre.name, '--version', @a2_pre.version.to_s] @cmd.handle_options [@a2_pre.name, '--version', @a2_pre.version.to_s]
assert @cmd.options[:prerelease] assert @cmd.options[:prerelease]
@ -79,7 +79,7 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@cmd.options[:domain] = :local @cmd.options[:domain] = :local
FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name),
File.join(@tempdir) File.join(@tempdir)
@cmd.options[:args] = [@a2.name] @cmd.options[:args] = [@a2.name]
@ -109,7 +109,7 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@cmd.options[:user_install] = false @cmd.options[:user_install] = false
FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name),
File.join(@tempdir) File.join(@tempdir)
@cmd.options[:args] = [@a2.name] @cmd.options[:args] = [@a2.name]
@ -178,10 +178,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher(:prerelease) util_setup_fake_fetcher(:prerelease)
util_setup_spec_fetcher @a2, @a2_pre util_setup_spec_fetcher @a2, @a2_pre
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2.file_name))
@fetcher.data["#{@gem_repo}gems/#{@a2_pre.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2_pre.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2_pre.file_name))
@cmd.options[:prerelease] = true @cmd.options[:prerelease] = true
@cmd.options[:args] = [@a2_pre.name] @cmd.options[:args] = [@a2_pre.name]
@ -204,8 +204,8 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher util_setup_fake_fetcher
util_setup_spec_fetcher @a2 util_setup_spec_fetcher @a2
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) read_binary(File.join(@gemhome, 'cache', @a2.file_name))
@cmd.options[:args] = [@a2.name] @cmd.options[:args] = [@a2.name]
@ -232,10 +232,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@cmd.options[:domain] = :local @cmd.options[:domain] = :local
FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', @a2.file_name),
File.join(@tempdir) File.join(@tempdir)
FileUtils.mv File.join(@gemhome, 'cache', "#{@b2.full_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', @b2.file_name),
File.join(@tempdir) File.join(@tempdir)
@cmd.options[:args] = [@a2.name, @b2.name] @cmd.options[:args] = [@a2.name, @b2.name]

View file

@ -46,10 +46,10 @@ class TestGemCommandsMirrorCommand < RubyGemTestCase
@cmd.execute @cmd.execute
end end
assert File.exist?(File.join(mirror, 'gems', "#{@a1.full_name}.gem")) assert File.exist?(File.join(mirror, 'gems', @a1.file_name))
assert File.exist?(File.join(mirror, 'gems', "#{@a2.full_name}.gem")) assert File.exist?(File.join(mirror, 'gems', @a2.file_name))
assert File.exist?(File.join(mirror, 'gems', "#{@b2.full_name}.gem")) assert File.exist?(File.join(mirror, 'gems', @b2.file_name))
assert File.exist?(File.join(mirror, 'gems', "#{@c1_2.full_name}.gem")) assert File.exist?(File.join(mirror, 'gems', @c1_2.file_name))
assert File.exist?(File.join(mirror, "Marshal.#{@marshal_version}")) assert File.exist?(File.join(mirror, "Marshal.#{@marshal_version}"))
ensure ensure
orig_HOME.nil? ? ENV.delete('HOME') : ENV['HOME'] = orig_HOME orig_HOME.nil? ? ENV.delete('HOME') : ENV['HOME'] = orig_HOME

View file

@ -19,12 +19,10 @@ class TestGemCommandsOutdatedCommand < RubyGemTestCase
remote_10 = quick_gem 'foo', '1.0' remote_10 = quick_gem 'foo', '1.0'
remote_20 = quick_gem 'foo', '2.0' remote_20 = quick_gem 'foo', '2.0'
remote_spec_file = File.join @gemhome, 'specifications', remote_spec_file = File.join @gemhome, 'specifications', remote_10.spec_name
remote_10.full_name + ".gemspec"
FileUtils.rm remote_spec_file FileUtils.rm remote_spec_file
remote_spec_file = File.join @gemhome, 'specifications', remote_spec_file = File.join @gemhome, 'specifications', remote_20.spec_name
remote_20.full_name + ".gemspec"
FileUtils.rm remote_spec_file FileUtils.rm remote_spec_file
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new

View file

@ -0,0 +1,105 @@
require_relative 'gemutilities'
require 'rubygems/commands/owner_command'
class TestGemCommandsOwnerCommand < RubyGemTestCase
def setup
super
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
@cmd = Gem::Commands::OwnerCommand.new
end
def test_show_owners
response = <<EOF
---
- email: user1@example.com
- email: user2@example.com
EOF
@fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK']
use_ui @ui do
@cmd.show_owners("freewill")
end
assert_equal Net::HTTP::Get, @fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
assert_match %r{Owners for gem: freewill}, @ui.output
assert_match %r{- user1@example.com}, @ui.output
assert_match %r{- user2@example.com}, @ui.output
end
def test_show_owners_denied
response = "You don't have permission to push to this gem"
@fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners.yaml"] = [response, 403, 'Forbidden']
assert_raises MockGemUi::TermError do
use_ui @ui do
@cmd.show_owners("freewill")
end
end
assert_match response, @ui.output
end
def test_add_owners
response = "Owner added successfully."
@fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
use_ui @ui do
@cmd.add_owners("freewill", ["user-new1@example.com"])
end
assert_equal Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
assert_equal "email=user-new1%40example.com", @fetcher.last_request.body
assert_match response, @ui.output
end
def test_add_owners_denied
response = "You don't have permission to push to this gem"
@fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden']
assert_raises MockGemUi::TermError do
use_ui @ui do
@cmd.add_owners("freewill", ["user-new1@example.com"])
end
end
assert_match response, @ui.output
end
def test_remove_owners
response = "Owner removed successfully."
@fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
use_ui @ui do
@cmd.remove_owners("freewill", ["user-remove1@example.com"])
end
assert_equal Net::HTTP::Delete, @fetcher.last_request.class
assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
assert_equal "email=user-remove1%40example.com", @fetcher.last_request.body
assert_match response, @ui.output
end
def test_remove_owners_denied
response = "You don't have permission to push to this gem"
@fetcher.data["https://rubygems.org/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden']
assert_raises MockGemUi::TermError do
use_ui @ui do
@cmd.remove_owners("freewill", ["user-remove1@example.com"])
end
end
assert_match response, @ui.output
end
end

View file

@ -75,7 +75,7 @@ class TestGemCommandsPristineCommand < RubyGemTestCase
install_gem a install_gem a
FileUtils.rm File.join(@gemhome, 'cache', "#{a.full_name}.gem") FileUtils.rm File.join(@gemhome, 'cache', a.file_name)
@cmd.options[:args] = %w[a] @cmd.options[:args] = %w[a]

View file

@ -0,0 +1,61 @@
require_relative 'gemutilities'
require 'rubygems/commands/push_command'
class TestGemCommandsPushCommand < RubyGemTestCase
def setup
super
@gems_dir = File.join @tempdir, 'gems'
@cache_dir = File.join @gemhome, 'cache'
FileUtils.mkdir @gems_dir
Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
@spec, @path = util_gem("freewill", "1.0.0")
@fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher
@cmd = Gem::Commands::PushCommand.new
end
def test_sending_gem
response = "Successfully registered gem: freewill (1.0.0)"
@fetcher.data["https://rubygems.org/api/v1/gems"] = [response, 200, 'OK']
use_ui @ui do
@cmd.send_gem(@path)
end
assert_match %r{Pushing gem to RubyGems.org...}, @ui.output
assert_equal Net::HTTP::Post, @fetcher.last_request.class
assert_equal Gem.read_binary(@path), @fetcher.last_request.body
assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
assert_match response, @ui.output
end
def test_raises_error_with_no_arguments
def @cmd.sign_in; end
assert_raises Gem::CommandLineError do
@cmd.execute
end
end
def test_sending_gem_denied
response = "You don't have permission to push to this gem"
@fetcher.data["https://rubygems.org/api/v1/gems"] = [response, 403, 'Forbidden']
assert_raises MockGemUi::TermError do
use_ui @ui do
@cmd.send_gem(@path)
end
end
assert_match response, @ui.output
end
end

View file

@ -58,6 +58,28 @@ pl (1)
assert_equal '', @ui.error assert_equal '', @ui.error
end end
def test_execute_all_prerelease
a1_name = @a1.full_name
a2_name = @a2.full_name
@cmd.handle_options %w[-r --all --prerelease]
use_ui @ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (3.a, 2, 1)
pl (1)
EOF
assert_equal expected, @ui.output
assert_equal '', @ui.error
end
def test_execute_details def test_execute_details
@a2.summary = 'This is a lot of text. ' * 4 @a2.summary = 'This is a lot of text. ' * 4
@a2.authors = ['Abraham Lincoln', 'Hirohito'] @a2.authors = ['Abraham Lincoln', 'Hirohito']
@ -216,61 +238,6 @@ pl (1)
assert_equal 1, e.exit_code assert_equal 1, e.exit_code
end end
def test_execute_legacy
Gem::SpecFetcher.fetcher = nil
si = util_setup_source_info_cache @a1, @a2, @pl1
@fetcher.data["#{@gem_repo}yaml"] = YAML.dump si
@fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] =
si.dump
@fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"
@cmd.handle_options %w[-r]
use_ui @ui do
@cmd.execute
end
expected = <<-EOF
*** REMOTE GEMS ***
a (2)
pl (1)
EOF
assert_equal expected, @ui.output
expected = <<-EOF
WARNING: RubyGems 1.2+ index not found for:
\t#{@gem_repo}
RubyGems will revert to legacy indexes degrading performance.
EOF
assert_equal expected, @ui.error
end
def test_execute_legacy_prerelease
Gem::SpecFetcher.fetcher = nil
si = util_setup_source_info_cache @a1, @a2, @pl1
@fetcher.data["#{@gem_repo}yaml"] = YAML.dump si
@fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] =
si.dump
@fetcher.data.delete "#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"
@cmd.handle_options %w[-r --prerelease]
e = assert_raises Gem::OperationNotSupportedError do
@cmd.execute
end
assert_equal 'Prereleases not supported on legacy repositories', e.message
end
def test_execute_local_details def test_execute_local_details
@a3a.summary = 'This is a lot of text. ' * 4 @a3a.summary = 'This is a lot of text. ' * 4
@a3a.authors = ['Abraham Lincoln', 'Hirohito'] @a3a.authors = ['Abraham Lincoln', 'Hirohito']

View file

@ -115,48 +115,9 @@ beta-gems.example.com is not a URI
assert_equal '', @ui.error assert_equal '', @ui.error
end end
def test_execute_add_legacy
util_setup_fake_fetcher
util_setup_source_info_cache
si = Gem::SourceIndex.new
si.add_spec @a1
@fetcher.data["#{@new_repo}/yaml"] = ''
@cmd.handle_options %W[--add #{@new_repo}]
use_ui @ui do
@cmd.execute
end
assert_equal [@gem_repo], Gem.sources
expected = <<-EOF
WARNING: RubyGems 1.2+ index not found for:
\t#{@new_repo}
Will cause RubyGems to revert to legacy indexes, degrading performance.
EOF
assert_equal "#{@new_repo} added to sources\n", @ui.output
assert_equal expected, @ui.error
end
def test_execute_clear_all def test_execute_clear_all
@cmd.handle_options %w[--clear-all] @cmd.handle_options %w[--clear-all]
util_setup_source_info_cache
cache = Gem::SourceInfoCache.cache
cache.update
cache.write_cache
assert File.exist?(cache.system_cache_file),
'system cache file'
assert File.exist?(cache.latest_system_cache_file),
'latest system cache file'
util_setup_spec_fetcher util_setup_spec_fetcher
fetcher = Gem::SpecFetcher.fetcher fetcher = Gem::SpecFetcher.fetcher
@ -179,11 +140,6 @@ Will cause RubyGems to revert to legacy indexes, degrading performance.
assert_equal expected, @ui.output assert_equal expected, @ui.output
assert_equal '', @ui.error assert_equal '', @ui.error
refute File.exist?(cache.system_cache_file),
'system cache file'
refute File.exist?(cache.latest_system_cache_file),
'latest system cache file'
refute File.exist?(fetcher.dir), 'cache dir removed' refute File.exist?(fetcher.dir), 'cache dir removed'
end end
@ -249,30 +205,5 @@ Will cause RubyGems to revert to legacy indexes, degrading performance.
assert_equal '', @ui.error assert_equal '', @ui.error
end end
def test_execute_update_legacy
@cmd.handle_options %w[--update]
util_setup_fake_fetcher
util_setup_source_info_cache
Gem::SourceInfoCache.reset
si = Gem::SourceIndex.new
si.add_spec @a1
@fetcher.data["#{@gem_repo}yaml"] = YAML.dump si
@fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump
use_ui @ui do
@cmd.execute
end
expected = <<-EOF
Bulk updating Gem source index for: #{@gem_repo}
source cache successfully updated
EOF
assert_equal expected, @ui.output
assert_equal '', @ui.error
end
end end

View file

@ -80,7 +80,7 @@ class TestGemCommandsSpecificationCommand < RubyGemTestCase
@cmd.execute @cmd.execute
end end
assert_equal "--- foo\n\n", @ui.output assert_equal "foo", YAML.load(@ui.output)
end end
def test_execute_marshal def test_execute_marshal
@ -106,8 +106,7 @@ class TestGemCommandsSpecificationCommand < RubyGemTestCase
util_setup_spec_fetcher foo util_setup_spec_fetcher foo
FileUtils.rm File.join(@gemhome, 'specifications', FileUtils.rm File.join(@gemhome, 'specifications', foo.spec_name)
"#{foo.full_name}.gemspec")
@cmd.options[:args] = %w[foo] @cmd.options[:args] = %w[foo]
@cmd.options[:domain] = :remote @cmd.options[:domain] = :remote

View file

@ -59,7 +59,7 @@ class TestGemCommandsUninstallCommand < GemInstallerTestCase
def test_execute_prerelease def test_execute_prerelease
@spec = quick_gem "pre", "2.b" @spec = quick_gem "pre", "2.b"
@gem = File.join @tempdir, "#{@spec.full_name}.gem" @gem = File.join @tempdir, @spec.file_name
FileUtils.touch @gem FileUtils.touch @gem
util_setup_gem util_setup_gem

View file

@ -13,14 +13,14 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase
util_setup_fake_fetcher util_setup_fake_fetcher
@a1_path = File.join @gemhome, 'cache', "#{@a1.full_name}.gem" @a1_path = File.join @gemhome, 'cache', @a1.file_name
@a2_path = File.join @gemhome, 'cache', "#{@a2.full_name}.gem" @a2_path = File.join @gemhome, 'cache', @a2.file_name
util_setup_spec_fetcher @a1, @a2 util_setup_spec_fetcher @a1, @a2
@fetcher.data["#{@gem_repo}gems/#{@a1.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] =
read_binary @a1_path read_binary @a1_path
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] =
read_binary @a2_path read_binary @a2_path
end end
@ -65,9 +65,9 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase
@a2.add_dependency 'c', '2' @a2.add_dependency 'c', '2'
@a2.add_dependency 'b', '2' @a2.add_dependency 'b', '2'
@b2_path = File.join @gemhome, 'cache', "#{@b2.full_name}.gem" @b2_path = File.join @gemhome, 'cache', @b2.file_name
@c1_2_path = File.join @gemhome, 'cache', "#{@c1_2.full_name}.gem" @c1_2_path = File.join @gemhome, 'cache', @c1_2.file_name
@c2_path = File.join @gemhome, 'cache', "#{@c2.full_name}.gem" @c2_path = File.join @gemhome, 'cache', @c2.file_name
@source_index = Gem::SourceIndex.new @source_index = Gem::SourceIndex.new
@source_index.add_spec @a1 @source_index.add_spec @a1
@ -80,12 +80,12 @@ class TestGemCommandsUpdateCommand < RubyGemTestCase
util_build_gem @a2 util_build_gem @a2
util_build_gem @c2 util_build_gem @c2
@fetcher.data["#{@gem_repo}gems/#{@a1.full_name}.gem"] = read_binary @a1_path @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = read_binary @a1_path
@fetcher.data["#{@gem_repo}gems/#{@a2.full_name}.gem"] = read_binary @a2_path @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = read_binary @a2_path
@fetcher.data["#{@gem_repo}gems/#{@b2.full_name}.gem"] = read_binary @b2_path @fetcher.data["#{@gem_repo}gems/#{@b2.file_name}"] = read_binary @b2_path
@fetcher.data["#{@gem_repo}gems/#{@c1_2.full_name}.gem"] = @fetcher.data["#{@gem_repo}gems/#{@c1_2.file_name}"] =
read_binary @c1_2_path read_binary @c1_2_path
@fetcher.data["#{@gem_repo}gems/#{@c2.full_name}.gem"] = read_binary @c2_path @fetcher.data["#{@gem_repo}gems/#{@c2.file_name}"] = read_binary @c2_path
util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2 util_setup_spec_fetcher @a1, @a2, @b2, @c1_2, @c2
util_clear_gems util_clear_gems

View file

@ -0,0 +1,66 @@
require_relative 'gemutilities'
require 'rubygems/commands/which_command'
class TestGemCommandsWhichCommand < RubyGemTestCase
def setup
super
@cmd = Gem::Commands::WhichCommand.new
end
def test_execute
util_foo_bar
@cmd.handle_options %w[foo_bar]
use_ui @ui do
@cmd.execute
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
assert_equal '', @ui.error
end
def test_execute_one_missing
util_foo_bar
@cmd.handle_options %w[foo_bar missing]
use_ui @ui do
@cmd.execute
end
assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
assert_match %r%Can't find ruby library file or shared library missing\n%,
@ui.error
end
def test_execute_missing
@cmd.handle_options %w[missing]
use_ui @ui do
assert_raises MockGemUi::TermError do
@cmd.execute
end
end
assert_equal '', @ui.output
assert_match %r%Can't find ruby library file or shared library missing\n%,
@ui.error
end
def util_foo_bar
files = %w[lib/foo_bar.rb Rakefile]
@foo_bar = quick_gem 'foo_bar' do |gem|
gem.files = files
end
files.each do |file|
filename = @foo_bar.full_gem_path + "/#{file}"
FileUtils.mkdir_p File.dirname(filename)
FileUtils.touch filename
end
end
end

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/config_file' require 'rubygems/config_file'
@ -271,6 +265,18 @@ class TestGemConfigFile < RubyGemTestCase
assert_equal %w[http://even-more-gems.example.com], Gem.sources assert_equal %w[http://even-more-gems.example.com], Gem.sources
end end
def test_load_rubygems_api_key_from_credentials
temp_cred = File.join Gem.user_home, '.gem', 'credentials'
FileUtils.mkdir File.dirname(temp_cred)
File.open temp_cred, 'w' do |fp|
fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
end
util_config_file
assert_equal "701229f217cdf23b1344c7b4b54ca97", @cfg.rubygems_api_key
end
def util_config_file(args = @cfg_args) def util_config_file(args = @cfg_args)
@cfg = Gem::ConfigFile.new args @cfg = Gem::ConfigFile.new args
end end

View file

@ -1,189 +1,137 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/version' require 'rubygems/dependency'
class TestGemDependency < RubyGemTestCase class TestGemDependency < RubyGemTestCase
def setup def test_subclass
super sc = Class.new Gem::Dependency
def sc.requirement() bogus; end
@pkg1_0 = Gem::Dependency.new 'pkg', ['> 1.0'] out, err = capture_io do
@pkg1_1 = Gem::Dependency.new 'pkg', ['> 1.1'] assert_equal Gem::Requirement.default, sc.new('a').version_requirement
end
@oth1_0 = Gem::Dependency.new 'other', ['> 1.0'] assert_match %r%deprecated%, err
@r1_0 = Gem::Requirement.new ['> 1.0']
end
def dep(name, version)
Gem::Dependency.new name, version
end end
def test_initialize def test_initialize
assert_equal "pkg", @pkg1_0.name d = dep "pkg", "> 1.0"
assert_equal @r1_0, @pkg1_0.version_requirements
assert_equal "pkg", d.name
assert_equal req("> 1.0"), d.requirement
end end
def test_initialize_double def test_initialize_double
dep = Gem::Dependency.new("pkg", ["> 1.0", "< 2.0"]) d = dep "pkg", "> 1.0", "< 2.0"
assert_equal req("> 1.0", "< 2.0"), d.requirement
assert_equal Gem::Requirement.new(["> 1.0", "< 2.0"]),
dep.version_requirements
end end
def test_initialize_empty def test_initialize_empty
dep = Gem::Dependency.new("pkg", []) d = dep "pkg"
req = @r1_0 assert_equal req(">= 0"), d.requirement
end
req.instance_eval do def test_initialize_type
@version = ">= 1.0" assert_equal :runtime, dep("pkg").type
@op = ">=" assert_equal :development, dep("pkg", [], :development).type
@nums = [1,0]
@requirements = nil assert_raises ArgumentError do
dep "pkg", :sometimes
end end
dep.instance_eval do
@version_requirement = req
@version_requirements = nil
end
assert_equal Gem::Requirement.new([">= 1.0"]), dep.version_requirements
end end
def test_initialize_version def test_initialize_version
dep = Gem::Dependency.new 'pkg', Gem::Version.new('2') d = dep "pkg", v("2")
assert_equal req("= 2"), d.requirement
assert_equal 'pkg', dep.name
assert_equal Gem::Requirement.new('= 2'), dep.version_requirements
end
def test_initialize_with_type
dep = Gem::Dependency.new("pkg", [], :development)
assert_equal(:development, dep.type)
end
def test_type_is_runtime_by_default
assert_equal(:runtime, Gem::Dependency.new("pkg", []).type)
end
def test_type_is_restricted
assert_raises ArgumentError do
Gem::Dependency.new("pkg", [:sometimes])
end
end end
def test_equals2 def test_equals2
assert_equal @pkg1_0, @pkg1_0.dup o = dep "other"
assert_equal @pkg1_0.dup, @pkg1_0 d = dep "pkg", "> 1.0"
d1 = dep "pkg", "> 1.1"
refute_equal @pkg1_0, @pkg1_1, "requirements different" assert_equal d, d.dup
refute_equal @pkg1_1, @pkg1_0, "requirements different" assert_equal d.dup, d
refute_equal @pkg1_0, @oth1_0, "names different" refute_equal d, d1
refute_equal @oth1_0, @pkg1_0, "names different" refute_equal d1, d
refute_equal @pkg1_0, Object.new refute_equal d, o
refute_equal Object.new, @pkg1_0 refute_equal o, d
refute_equal d, Object.new
refute_equal Object.new, d
end end
def test_equals2_type def test_equals2_type
runtime = Gem::Dependency.new("pkg", []) refute_equal dep("pkg", :runtime), dep("pkg", :development)
development = Gem::Dependency.new("pkg", [], :development)
refute_equal(runtime, development)
end end
def test_equals_tilde def test_equals_tilde
a0 = dep 'a', '0' d = dep "a", "0"
a1 = dep 'a', '1'
b0 = dep 'b', '0'
pa0 = dep 'a', '>= 0' assert_match d, d, "matche self"
pa0r = dep(/a/, '>= 0') assert_match dep("a", ">= 0"), d, "match version exact"
pab0r = dep(/a|b/, '>= 0') assert_match dep("a", ">= 0"), dep("a", "1"), "match version"
assert_match dep(/a/, ">= 0"), d, "match simple regexp"
assert_match dep(/a|b/, ">= 0"), d, "match scary regexp"
assert_match a0, a0, 'match self' refute_match dep(/a/), dep("b")
assert_match pa0, a0, 'match version exact' refute_match dep("a"), Object.new
assert_match pa0, a1, 'match version'
assert_match pa0r, a0, 'match regex simple'
assert_match pab0r, a0, 'match regex complex'
refute_match pa0r, b0, 'fail match regex'
refute_match pa0r, Object.new, 'fail match Object'
end end
def test_equals_tilde_escape def test_equals_tilde_escape
a1 = Gem::Dependency.new 'a', '1' refute_match dep("a|b"), dep("a", "1")
assert_match dep(/a|b/), dep("a", "1")
pab1 = Gem::Dependency.new 'a|b', '>= 1'
pab1r = Gem::Dependency.new(/a|b/, '>= 1')
refute_match pab1, a1, 'escaped'
assert_match pab1r, a1, 'exact regexp'
end end
def test_equals_tilde_object def test_equals_tilde_object
a0 = Object.new o = Object.new
def o.name ; 'a' end
def o.version ; '0' end
def a0.name() 'a' end assert_match dep("a"), o
def a0.version() '0' end
pa0 = Gem::Dependency.new 'a', '>= 0'
assert_match pa0, a0, 'match version exact'
end end
def test_equals_tilde_spec def test_equals_tilde_spec
def spec(name, version) assert_match dep("a", ">= 0"), spec("a", "0")
Gem::Specification.new do |spec| assert_match dep("a", "1"), spec("a", "1")
spec.name = name assert_match dep(/a/, ">= 0"), spec("a", "0")
spec.version = version assert_match dep(/a|b/, ">= 0"), spec("b", "0")
end refute_match dep(/a/, ">= 0"), spec("b", "0")
end
a0 = spec 'a', '0'
a1 = spec 'a', '1'
b0 = spec 'b', '0'
pa0 = dep 'a', '>= 0'
pa0r = dep(/a/, '>= 0')
pab0r = dep(/a|b/, '>= 0')
assert_match pa0, a0, 'match version exact'
assert_match pa0, a1, 'match version'
assert_match pa0r, a0, 'match regex simple'
assert_match pa0r, a1, 'match regex simple'
assert_match pab0r, a0, 'match regex complex'
assert_match pab0r, b0, 'match regex complex'
refute_match pa0r, b0, 'fail match regex'
refute_match pa0r, Object.new, 'fail match Object'
end end
def test_hash def test_hash
assert_equal @pkg1_0.hash, @pkg1_0.dup.hash d = dep "pkg", "1.0"
assert_equal @pkg1_0.dup.hash, @pkg1_0.hash
refute_equal @pkg1_0.hash, @pkg1_1.hash, "requirements different" assert_equal d.hash, d.dup.hash
refute_equal @pkg1_1.hash, @pkg1_0.hash, "requirements different" assert_equal d.dup.hash, d.hash
refute_equal @pkg1_0.hash, @oth1_0.hash, "names different" refute_equal dep("pkg", "1.0").hash, dep("pkg", "2.0").hash, "requirement"
refute_equal @oth1_0.hash, @pkg1_0.hash, "names different" refute_equal dep("pkg", "1.0").hash, dep("abc", "1.0").hash, "name"
refute_equal dep("pkg", :development), dep("pkg", :runtime), "type"
end end
def test_hash_type def test_prerelease_eh
runtime = Gem::Dependency.new("pkg", []) d = dep "pkg", "= 1"
development = Gem::Dependency.new("pkg", [], :development)
refute_equal(runtime.hash, development.hash) refute d.prerelease?
d.prerelease = true
assert d.prerelease?
d = dep "pkg", "= 1.a"
assert d.prerelease?
d.prerelease = false
assert d.prerelease?
d = dep "pkg", "> 1.a", "> 2"
assert d.prerelease?
end end
end end

View file

@ -23,6 +23,16 @@ class TestGemDependencyInstaller < RubyGemTestCase
s.add_development_dependency 'aa' s.add_development_dependency 'aa'
end end
@b1_pre, @b1_pre_gem = util_gem 'b', '1.a' do |s|
s.add_dependency 'a'
s.add_development_dependency 'aa'
end
@c1_pre, @c1_pre_gem = util_gem 'c', '1.a' do |s|
s.add_dependency 'a', '1.a'
s.add_dependency 'b', '1'
end
@d1, @d1_gem = util_gem 'd', '1' @d1, @d1_gem = util_gem 'd', '1'
@d2, @d2_gem = util_gem 'd', '2' @d2, @d2_gem = util_gem 'd', '2'
@ -46,8 +56,8 @@ class TestGemDependencyInstaller < RubyGemTestCase
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher Gem::RemoteFetcher.fetcher = @fetcher
si = util_setup_spec_fetcher(@a1, @a1_pre, @b1, @d1, @d2, @x1_m, @x1_o, @w1, @y1, si = util_setup_spec_fetcher(@a1, @a1_pre, @b1, @b1_pre, @c1_pre, @d1, @d2,
@y1_1_p, @z1) @x1_m, @x1_o, @w1, @y1, @y1_1_p, @z1)
util_clear_gems util_clear_gems
end end
@ -104,8 +114,8 @@ class TestGemDependencyInstaller < RubyGemTestCase
assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
assert File.exist?(File.join(@tempdir, 'cache', "#{@a1.full_name}.gem")) assert File.exist?(File.join(@tempdir, 'cache', @a1.file_name))
assert File.exist?(File.join(@tempdir, 'cache', "#{@b1.full_name}.gem")) assert File.exist?(File.join(@tempdir, 'cache', @b1.file_name))
end end
def test_install_dependencies_satisfied def test_install_dependencies_satisfied
@ -124,7 +134,7 @@ class TestGemDependencyInstaller < RubyGemTestCase
inst.install 'a-2' inst.install 'a-2'
end end
FileUtils.rm File.join(@tempdir, "#{a2.full_name}.gem") FileUtils.rm File.join(@tempdir, a2.file_name)
Dir.chdir @tempdir do Dir.chdir @tempdir do
inst = Gem::DependencyInstaller.new inst = Gem::DependencyInstaller.new
@ -259,7 +269,9 @@ class TestGemDependencyInstaller < RubyGemTestCase
inst.install 'a' inst.install 'a'
end end
assert_match %r|\A#!/\S+/env #{Gem::ConfigMap[:ruby_install_name]}\n|, env = "/\\S+/env" unless Gem.win_platform?
assert_match %r|\A#!#{env} #{Gem::ConfigMap[:ruby_install_name]}\n|,
File.read(File.join(@gemhome, 'bin', 'a_bin')) File.read(File.join(@gemhome, 'bin', 'a_bin'))
end end
@ -302,10 +314,8 @@ class TestGemDependencyInstaller < RubyGemTestCase
assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
assert File.exist?(File.join(gemhome2, 'specifications', assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name))
"#{@a1.full_name}.gemspec")) assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name))
assert File.exist?(File.join(gemhome2, 'cache',
"#{@a1.full_name}.gem"))
end end
def test_install_domain_both def test_install_domain_both
@ -327,10 +337,8 @@ class TestGemDependencyInstaller < RubyGemTestCase
assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
a1, b1 = inst.installed_gems a1, b1 = inst.installed_gems
a1_expected = File.join(@gemhome, 'specifications', a1_expected = File.join(@gemhome, 'specifications', a1.spec_name)
"#{a1.full_name}.gemspec") b1_expected = File.join(@gemhome, 'specifications', b1.spec_name)
b1_expected = File.join(@gemhome, 'specifications',
"#{b1.full_name}.gemspec")
assert_equal a1_expected, a1.loaded_from assert_equal a1_expected, a1.loaded_from
assert_equal b1_expected, b1.loaded_from assert_equal b1_expected, b1.loaded_from
@ -463,9 +471,9 @@ class TestGemDependencyInstaller < RubyGemTestCase
File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end
File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end
@fetcher.data["http://gems.example.com/gems/#{@a1.full_name}.gem"] = @fetcher.data["http://gems.example.com/gems/#{@a1.file_name}"] =
a1_data a1_data
@fetcher.data["http://gems.example.com/gems/#{a2_o.full_name}.gem"] = @fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] =
a2_o_data a2_o_data
inst = Gem::DependencyInstaller.new :domain => :remote inst = Gem::DependencyInstaller.new :domain => :remote
@ -576,10 +584,29 @@ class TestGemDependencyInstaller < RubyGemTestCase
local = gems.last local = gems.last
assert_equal 'a-1', local.first.full_name, 'local spec' assert_equal 'a-1', local.first.full_name, 'local spec'
assert_equal File.join(@tempdir, "#{@a1.full_name}.gem"), assert_equal File.join(@tempdir, @a1.file_name),
local.last, 'local path' local.last, 'local path'
end end
def test_find_gems_with_sources_prerelease
installer = Gem::DependencyInstaller.new
dependency = Gem::Dependency.new('a', Gem::Requirement.default)
releases =
installer.find_gems_with_sources(dependency).map { |gems, *| gems }
assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' }
refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' }
dependency.prerelease = true
prereleases =
installer.find_gems_with_sources(dependency).map { |gems, *| gems }
assert_equal [@a1_pre], prereleases
end
def test_gather_dependencies def test_gather_dependencies
inst = Gem::DependencyInstaller.new inst = Gem::DependencyInstaller.new
inst.find_spec_by_name_and_version 'b' inst.find_spec_by_name_and_version 'b'
@ -622,6 +649,15 @@ class TestGemDependencyInstaller < RubyGemTestCase
assert_equal %w[y-1 z-1], inst.gems_to_install.map { |s| s.full_name } assert_equal %w[y-1 z-1], inst.gems_to_install.map { |s| s.full_name }
end end
def test_gather_dependencies_prerelease
inst = Gem::DependencyInstaller.new :prerelease => true
inst.find_spec_by_name_and_version 'c', '1.a'
inst.gather_dependencies
assert_equal %w[a-1.a b-1 c-1.a],
inst.gems_to_install.map { |s| s.full_name }
end
def test_gather_dependencies_old_required def test_gather_dependencies_old_required
e1, = util_gem 'e', '1' do |s| s.add_dependency 'd', '= 1' end e1, = util_gem 'e', '1' do |s| s.add_dependency 'd', '= 1' end
@ -636,16 +672,5 @@ class TestGemDependencyInstaller < RubyGemTestCase
assert_equal %w[d-1 e-1], inst.gems_to_install.map { |s| s.full_name } assert_equal %w[d-1 e-1], inst.gems_to_install.map { |s| s.full_name }
end end
def test_prerelease_uses_pre_index
installer = Gem::DependencyInstaller.new
pre_installer = Gem::DependencyInstaller.new(:prerelease => true)
dependency = Gem::Dependency.new('a', Gem::Requirement.default)
releases = installer.find_gems_with_sources(dependency).map{ |gems, *| gems }
prereleases = pre_installer.find_gems_with_sources(dependency).map{ |gems, *| gems }
assert releases.select{ |s| s.name == 'a' and s.version.to_s == '1' }.first
assert releases.select{ |s| s.name == 'a' and s.version.to_s == '1.a' }.empty?
assert_equal [@a1_pre], prereleases
end
end end

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/dependency_list' require 'rubygems/dependency_list'
@ -71,6 +65,33 @@ class TestGemDependencyList < RubyGemTestCase
assert_equal %w[b-1 c-1 a-1], order.map { |s| s.full_name } assert_equal %w[b-1 c-1 a-1], order.map { |s| s.full_name }
end end
def test_dependency_order_development
e1 = quick_gem 'e', '1'
f1 = quick_gem 'f', '1'
g1 = quick_gem 'g', '1'
@a1.add_dependency 'e'
@a1.add_dependency 'f'
@a1.add_dependency 'g'
g1.add_development_dependency 'a'
deplist = Gem::DependencyList.new true
deplist.add @a1, e1, f1, g1
order = deplist.dependency_order
assert_equal %w[g-1 a-1 f-1 e-1], order.map { |s| s.full_name },
'development on'
deplist2 = Gem::DependencyList.new
deplist2.add @a1, e1, f1, g1
order = deplist2.dependency_order
assert_equal %w[a-1 g-1 f-1 e-1], order.map { |s| s.full_name },
'development off'
end
def test_dependency_order_diamond def test_dependency_order_diamond
util_diamond util_diamond
e1 = quick_gem 'e', '1' e1 = quick_gem 'e', '1'

View file

@ -1,46 +0,0 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities'
require "rubygems/digest/md5"
require "rubygems/digest/sha1"
require "rubygems/digest/sha2"
class TestRubygemsGemDigest < RubyGemTestCase
def test_sha256_hex_digest_works
digester = Gem::SHA256.new
assert_equal "b5d4045c3f466fa91fe2cc6abe79232a1a57cdf104f7a26e716e0a1e2789df78", digester.hexdigest("ABC")
end
def test_sha256_digest_works
digester = Gem::SHA256.new
assert_equal "\265\324\004\\?Fo\251\037\342\314j\276y#*\032W\315\361\004\367\242nqn\n\036'\211\337x",
digester.digest("ABC")
end
def test_sha1_hex_digest_works
digester = Gem::SHA1.new
assert_equal "3c01bdbb26f358bab27f267924aa2c9a03fcfdb8", digester.hexdigest("ABC")
end
def test_sha1_digest_works
digester = Gem::SHA1.new
assert_equal "<\001\275\273&\363X\272\262\177&y$\252,\232\003\374\375\270", digester.digest("ABC")
end
def test_md5_hex_digest_works
digester = Gem::MD5.new
assert_equal "902fbdd2b1df0c4f70b4a5d23525e932", digester.hexdigest("ABC")
end
def test_md5_digest_works
digester = Gem::MD5.new
assert_equal "\220/\275\322\261\337\fOp\264\245\3225%\3512", digester.digest("ABC")
end
end

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/doc_manager' require 'rubygems/doc_manager'

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require_relative 'simple_gem' require_relative 'simple_gem'
require 'rubygems/format' require 'rubygems/format'
@ -16,7 +10,7 @@ class TestGemFormat < RubyGemTestCase
@simple_gem = SIMPLE_GEM @simple_gem = SIMPLE_GEM
end end
def test_from_file_by_path def test_class_from_file_by_path
util_make_gems util_make_gems
gems = Dir[File.join(@gemhome, 'cache', '*.gem')] gems = Dir[File.join(@gemhome, 'cache', '*.gem')]
@ -34,13 +28,22 @@ class TestGemFormat < RubyGemTestCase
end end
end end
def test_from_file_by_path_nonexistent def test_class_from_file_by_path_empty
util_make_gems
empty_gem = File.join @tempdir, 'empty.gem'
FileUtils.touch empty_gem
assert_nil Gem::Format.from_file_by_path(empty_gem)
end
def test_class_from_file_by_path_nonexistent
assert_raises Gem::Exception do assert_raises Gem::Exception do
Gem::Format.from_file_by_path '/nonexistent' Gem::Format.from_file_by_path '/nonexistent'
end end
end end
def test_from_io_garbled def test_class_from_io_garbled
e = assert_raises Gem::Package::FormatError do e = assert_raises Gem::Package::FormatError do
# subtly bogus input # subtly bogus input
Gem::Format.from_io(StringIO.new(@simple_gem.upcase)) Gem::Format.from_io(StringIO.new(@simple_gem.upcase))

View file

@ -22,6 +22,9 @@ class TestGemGemPathSearcher < RubyGemTestCase
@foo2 = quick_gem 'foo', '0.2' @foo2 = quick_gem 'foo', '0.2'
@bar1 = quick_gem 'bar', '0.1' @bar1 = quick_gem 'bar', '0.1'
@bar2 = quick_gem 'bar', '0.2' @bar2 = quick_gem 'bar', '0.2'
@nrp = quick_gem 'nil_require_paths', '0.1'
@nrp.require_paths = nil
@fetcher = Gem::FakeFetcher.new @fetcher = Gem::FakeFetcher.new
Gem::RemoteFetcher.fetcher = @fetcher Gem::RemoteFetcher.fetcher = @fetcher
@ -50,6 +53,10 @@ class TestGemGemPathSearcher < RubyGemTestCase
assert_equal expected, lib_dirs assert_equal expected, lib_dirs
end end
def test_lib_dirs_for_nil_require_paths
assert_nil @gps.lib_dirs_for(@nrp)
end
def test_matching_file_eh def test_matching_file_eh
refute @gps.matching_file?(@foo1, 'bar') refute @gps.matching_file?(@foo1, 'bar')
assert @gps.matching_file?(@foo1, 'foo') assert @gps.matching_file?(@foo1, 'foo')
@ -63,5 +70,9 @@ class TestGemGemPathSearcher < RubyGemTestCase
assert_equal [expected], @gps.matching_files(@foo1, 'foo') assert_equal [expected], @gps.matching_files(@foo1, 'foo')
end end
def test_matching_files_nil_require_paths
assert_empty @gps.matching_files(@nrp, 'foo')
end
end end

View file

@ -0,0 +1,103 @@
require_relative 'gemutilities'
require 'rubygems'
require 'rubygems/gemcutter_utilities'
class TestGemGemcutterUtilities < RubyGemTestCase
def setup
super
ENV['RUBYGEMS_HOST'] = nil
Gem.configuration.rubygems_api_key = nil
@cmd = Gem::Command.new '', 'summary'
@cmd.extend Gem::GemcutterUtilities
end
def test_sign_in
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
util_sign_in [api_key, 200, 'OK']
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
assert @fetcher.last_request["authorization"]
assert_match %r{Signed in.}, @sign_in_ui.output
credentials = YAML.load_file Gem.configuration.credentials_path
assert_equal api_key, credentials[:rubygems_api_key]
end
def test_sign_in_with_host
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
util_sign_in [api_key, 200, 'OK'], 'http://example.com'
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
assert @fetcher.last_request["authorization"]
assert_match %r{Signed in.}, @sign_in_ui.output
credentials = YAML.load_file Gem.configuration.credentials_path
assert_equal api_key, credentials[:rubygems_api_key]
end
def test_sign_in_skips_with_existing_credentials
api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'
Gem.configuration.rubygems_api_key = api_key
util_sign_in [api_key, 200, 'OK']
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'
FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path)
open Gem.configuration.credentials_path, 'w' do |f|
f.write Hash[:other_api_key, other_api_key].to_yaml
end
util_sign_in [api_key, 200, 'OK']
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
assert_match %r{Signed in.}, @sign_in_ui.output
credentials = YAML.load_file Gem.configuration.credentials_path
assert_equal api_key, credentials[:rubygems_api_key]
assert_equal other_api_key, credentials[:other_api_key]
end
def test_sign_in_with_bad_credentials
skip 'Always uses $stdin on windows' if Gem.win_platform?
assert_raises MockGemUi::TermError do
util_sign_in ['Access Denied.', 403, 'Forbidden']
end
assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output
assert_match %r{Access Denied.}, @sign_in_ui.output
end
def util_sign_in response, host = nil
skip 'Always uses $stdin on windows' if Gem.win_platform?
email = 'you@example.com'
password = 'secret'
if host
ENV['RUBYGEMS_HOST'] = host
else
host = "https://rubygems.org"
end
@fetcher = Gem::FakeFetcher.new
@fetcher.data["#{host}/api/v1/api_key"] = response
Gem::RemoteFetcher.fetcher = @fetcher
@sign_in_ui = MockGemUi.new "#{email}\n#{password}\n"
use_ui @sign_in_ui do
@cmd.sign_in
end
end
end

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gemutilities' require_relative 'gemutilities'
require 'rubygems/indexer' require 'rubygems/indexer'
@ -145,19 +139,19 @@ pl-1-i386-linux
assert_equal expected, latest_quick_index assert_equal expected, latest_quick_index
assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a1.spec_name}.rz"
assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a2.spec_name}.rz"
assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@b2.spec_name}.rz"
assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
refute_indexed quickdir, "#{@pl1.full_name}.gemspec.rz" refute_indexed quickdir, "#{@pl1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
refute_indexed quickdir, "#{@c1_2.full_name}.gemspec" refute_indexed quickdir, @c1_2.spec_name
refute_indexed marshal_quickdir, "#{@c1_2.full_name}.gemspec" refute_indexed marshal_quickdir, @c1_2.spec_name
assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -172,7 +166,7 @@ pl-1-i386-linux
<title>ExampleForge gems</title> <title>ExampleForge gems</title>
<link>http://example.com</link> <link>http://example.com</link>
<description>Recently released gems from http://example.com</description> <description>Recently released gems from http://example.com</description>
<generator>RubyGems v1.3.4</generator> <generator>RubyGems v#{Gem::RubyGemsVersion}</generator>
<docs>http://cyber.law.harvard.edu/rss/rss.html</docs> <docs>http://cyber.law.harvard.edu/rss/rss.html</docs>
<item> <item>
<title>a-2</title> <title>a-2</title>
@ -325,19 +319,19 @@ eighty characters.&lt;/pre&gt;
assert_indexed quickdir, "latest_index" assert_indexed quickdir, "latest_index"
assert_indexed quickdir, "latest_index.rz" assert_indexed quickdir, "latest_index.rz"
assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a1.spec_name}.rz"
assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a2.spec_name}.rz"
assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@b2.spec_name}.rz"
assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
refute_indexed quickdir, "#{@pl1.full_name}.gemspec.rz" refute_indexed quickdir, "#{@pl1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
refute_indexed quickdir, "#{@c1_2.full_name}.gemspec" refute_indexed quickdir, "#{@c1_2.spec_name}"
refute_indexed marshal_quickdir, "#{@c1_2.full_name}.gemspec" refute_indexed marshal_quickdir, "#{@c1_2.spec_name}"
refute_indexed @tempdir, "specs.#{@marshal_version}" refute_indexed @tempdir, "specs.#{@marshal_version}"
refute_indexed @tempdir, "specs.#{@marshal_version}.gz" refute_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -379,15 +373,15 @@ eighty characters.&lt;/pre&gt;
assert_indexed quickdir, "latest_index" assert_indexed quickdir, "latest_index"
assert_indexed quickdir, "latest_index.rz" assert_indexed quickdir, "latest_index.rz"
assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a1.spec_name}.rz"
assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a2.spec_name}.rz"
assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@b2.spec_name}.rz"
assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -421,19 +415,19 @@ eighty characters.&lt;/pre&gt;
refute_indexed quickdir, "latest_index" refute_indexed quickdir, "latest_index"
refute_indexed quickdir, "latest_index.rz" refute_indexed quickdir, "latest_index.rz"
refute_indexed quickdir, "#{@a1.full_name}.gemspec.rz" refute_indexed quickdir, "#{@a1.spec_name}.rz"
refute_indexed quickdir, "#{@a2.full_name}.gemspec.rz" refute_indexed quickdir, "#{@a2.spec_name}.rz"
refute_indexed quickdir, "#{@b2.full_name}.gemspec.rz" refute_indexed quickdir, "#{@b2.spec_name}.rz"
refute_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" refute_indexed quickdir, "#{@c1_2.spec_name}.rz"
refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
refute_indexed quickdir, "#{@pl1.full_name}.gemspec.rz" refute_indexed quickdir, "#{@pl1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
refute_indexed quickdir, "#{@c1_2.full_name}.gemspec" refute_indexed quickdir, "#{@c1_2.spec_name}"
refute_indexed marshal_quickdir, "#{@c1_2.full_name}.gemspec" refute_indexed marshal_quickdir, "#{@c1_2.spec_name}"
assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -475,15 +469,15 @@ eighty characters.&lt;/pre&gt;
assert_indexed quickdir, "latest_index" assert_indexed quickdir, "latest_index"
assert_indexed quickdir, "latest_index.rz" assert_indexed quickdir, "latest_index.rz"
assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a1.spec_name}.rz"
assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a2.spec_name}.rz"
assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@b2.spec_name}.rz"
assert_indexed quickdir, "#{@c1_2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@c1_2.spec_name}.rz"
assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" assert_indexed quickdir, "#{@pl1.original_name}.gemspec.rz"
assert_indexed marshal_quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a1.spec_name}.rz"
assert_indexed marshal_quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@a2.spec_name}.rz"
assert_indexed @tempdir, "specs.#{@marshal_version}" assert_indexed @tempdir, "specs.#{@marshal_version}"
assert_indexed @tempdir, "specs.#{@marshal_version}.gz" assert_indexed @tempdir, "specs.#{@marshal_version}.gz"
@ -637,14 +631,14 @@ eighty characters.&lt;/pre&gt;
@d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform] @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform]
gems = File.join @tempdir, 'gems' gems = File.join @tempdir, 'gems'
FileUtils.mv File.join(@gemhome, 'cache', "#{@d2_1.full_name}.gem"), gems FileUtils.mv File.join(@gemhome, 'cache', @d2_1.file_name), gems
FileUtils.mv File.join(@gemhome, 'cache', "#{@d2_1_a.full_name}.gem"), gems FileUtils.mv File.join(@gemhome, 'cache', @d2_1_a.file_name), gems
use_ui @ui do use_ui @ui do
@indexer.update_index @indexer.update_index
end end
assert_indexed marshal_quickdir, "#{@d2_1.full_name}.gemspec.rz" assert_indexed marshal_quickdir, "#{@d2_1.spec_name}.rz"
specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index) specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index)

View file

@ -19,11 +19,6 @@ class TestGemInstallUpdateOptions < GemInstallerTestCase
assert @cmd.handles?(args) assert @cmd.handles?(args)
end end
def test_prerelease
@cmd.handle_options %w[--prerelease]
assert_equal true, @cmd.options[:prerelease]
end
def test_security_policy def test_security_policy
@cmd.handle_options %w[-P HighSecurity] @cmd.handle_options %w[-P HighSecurity]

View file

@ -1,9 +1,3 @@
#--
# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
# All rights reserved.
# See LICENSE.txt for permissions.
#++
require_relative 'gem_installer_test_case' require_relative 'gem_installer_test_case'
class TestGemInstaller < GemInstallerTestCase class TestGemInstaller < GemInstallerTestCase
@ -107,19 +101,6 @@ load Gem.bin_path('a', 'my_exec', version)
assert_equal 'a requires b (> 2, runtime)', e.message assert_equal 'a requires b (> 2, runtime)', e.message
end end
def test_expand_and_validate_gem_dir
@installer.gem_dir = '/nonexistent'
expanded_gem_dir = @installer.send(:expand_and_validate_gem_dir)
if win_platform?
expected = File.expand_path('/nonexistent').downcase
expanded_gem_dir = expanded_gem_dir.downcase
else
expected = '/nonexistent'
end
assert_equal expected, expanded_gem_dir
end
def test_extract_files def test_extract_files
format = Object.new format = Object.new
def format.file_entries def format.file_entries
@ -523,11 +504,11 @@ load Gem.bin_path('a', 'my_exec', version)
def test_initialize def test_initialize
spec = quick_gem 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end spec = quick_gem 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end
gem = File.join @tempdir, "#{spec.full_name}.gem" gem = File.join @tempdir, spec.file_name
Dir.mkdir util_inst_bindir Dir.mkdir util_inst_bindir
util_build_gem spec util_build_gem spec
FileUtils.mv File.join(@gemhome, 'cache', "#{spec.full_name}.gem"), FileUtils.mv File.join(@gemhome, 'cache', spec.file_name),
@tempdir @tempdir
installer = Gem::Installer.new gem installer = Gem::Installer.new gem
@ -539,7 +520,7 @@ load Gem.bin_path('a', 'my_exec', version)
Dir.mkdir util_inst_bindir Dir.mkdir util_inst_bindir
util_setup_gem util_setup_gem
cache_file = File.join @gemhome, 'cache', "#{@spec.full_name}.gem" cache_file = File.join @gemhome, 'cache', @spec.file_name
Gem.pre_install do |installer| Gem.pre_install do |installer|
refute File.exist?(cache_file), 'cache file should not exist yet' refute File.exist?(cache_file), 'cache file should not exist yet'
@ -567,8 +548,7 @@ load Gem.bin_path('a', 'my_exec', version)
assert File.exist?(File.join(gemdir, 'ext', 'a', 'Rakefile')) assert File.exist?(File.join(gemdir, 'ext', 'a', 'Rakefile'))
spec_file = File.join(@gemhome, 'specifications', spec_file = File.join(@gemhome, 'specifications', @spec.spec_name)
"#{@spec.full_name}.gemspec")
assert_equal spec_file, @spec.loaded_from assert_equal spec_file, @spec.loaded_from
assert File.exist?(spec_file) assert File.exist?(spec_file)
@ -582,7 +562,7 @@ load Gem.bin_path('a', 'my_exec', version)
use_ui @ui do use_ui @ui do
Dir.chdir @tempdir do Gem::Builder.new(@spec).build end Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
gem = File.join @tempdir, "#{@spec.full_name}.gem" gem = File.join @tempdir, @spec.file_name
end end
gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end
@ -665,8 +645,7 @@ load Gem.bin_path('a', 'my_exec', version)
assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform? assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
assert File.exist?(File.join(gemdir, 'lib', 'code.rb')) assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
assert File.exist?(File.join(@gemhome, 'specifications', assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
"#{@spec.full_name}.gemspec"))
end end
def test_install_missing_dirs def test_install_missing_dirs
@ -676,7 +655,7 @@ load Gem.bin_path('a', 'my_exec', version)
use_ui @ui do use_ui @ui do
Dir.chdir @tempdir do Gem::Builder.new(@spec).build end Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
gem = File.join @tempdir, "#{@spec.full_name}.gem" gem = File.join @tempdir, @spec.file_name
@installer.install @installer.install
end end
@ -685,50 +664,8 @@ load Gem.bin_path('a', 'my_exec', version)
File.directory? File.join(Gem.dir, 'docs') File.directory? File.join(Gem.dir, 'docs')
File.directory? File.join(Gem.dir, 'specifications') File.directory? File.join(Gem.dir, 'specifications')
assert File.exist?(File.join(@gemhome, 'cache', "#{@spec.full_name}.gem")) assert File.exist?(File.join(@gemhome, 'cache', @spec.file_name))
assert File.exist?(File.join(@gemhome, 'specifications', assert File.exist?(File.join(@gemhome, 'specifications', @spec.spec_name))
"#{@spec.full_name}.gemspec"))
end
unless win_platform? # File.chmod doesn't work
def test_install_user_local_fallback
Dir.mkdir util_inst_bindir
File.chmod 0755, @userhome
File.chmod 0000, util_inst_bindir
File.chmod 0000, Gem.dir
@spec.executables = ["executable"]
build_rake_in do
use_ui @ui do
util_setup_gem
@installer.install
end
end
assert File.exist?(File.join(Gem.user_dir, 'gems',
@spec.full_name, 'lib', 'code.rb'))
assert File.exist?(File.join(Gem.user_dir, 'bin', 'executable'))
ensure
File.chmod 0755, Gem.dir
File.chmod 0755, util_inst_bindir
end
def test_install_bindir_read_only
Dir.mkdir util_inst_bindir
File.chmod 0755, @userhome
File.chmod 0000, util_inst_bindir
build_rake_in do
use_ui @ui do
util_setup_gem
@installer.install
end
end
assert File.exist?(File.join(Gem.user_dir, 'bin', 'executable'))
ensure
File.chmod 0755, util_inst_bindir
end
end end
def test_install_with_message def test_install_with_message
@ -749,7 +686,7 @@ load Gem.bin_path('a', 'my_exec', version)
e = assert_raises Gem::InstallError do e = assert_raises Gem::InstallError do
installer.install installer.install
end end
assert_equal 'old_ruby_required requires Ruby version = 1.4.6', assert_equal 'old_ruby_required requires Ruby version = 1.4.6.',
e.message e.message
end end
end end
@ -761,15 +698,15 @@ load Gem.bin_path('a', 'my_exec', version)
util_build_gem spec util_build_gem spec
gem = File.join @gemhome, 'cache', "#{spec.full_name}.gem" gem = File.join @gemhome, 'cache', spec.file_name
use_ui @ui do use_ui @ui do
@installer = Gem::Installer.new gem @installer = Gem::Installer.new gem
e = assert_raises Gem::InstallError do e = assert_raises Gem::InstallError do
@installer.install @installer.install
end end
assert_equal 'old_rubygems_required requires RubyGems version < 0', assert_equal 'old_rubygems_required requires RubyGems version < 0. ' +
e.message "Try 'gem update --system' to update RubyGems itself.", e.message
end end
end end
@ -825,7 +762,11 @@ load Gem.bin_path('a', 'my_exec', version)
@installer.env_shebang = true @installer.env_shebang = true
shebang = @installer.shebang 'my_exec' shebang = @installer.shebang 'my_exec'
assert_equal "#!/usr/bin/env #{Gem::ConfigMap[:ruby_install_name]}", shebang
env_shebang = "/usr/bin/env" unless Gem.win_platform?
assert_equal("#!#{env_shebang} #{Gem::ConfigMap[:ruby_install_name]}",
shebang)
end end
def test_shebang_nested def test_shebang_nested
@ -889,7 +830,7 @@ load Gem.bin_path('a', 'my_exec', version)
def test_write_spec def test_write_spec
spec_dir = File.join @gemhome, 'specifications' spec_dir = File.join @gemhome, 'specifications'
spec_file = File.join spec_dir, "#{@spec.full_name}.gemspec" spec_file = File.join spec_dir, @spec.spec_name
FileUtils.rm spec_file FileUtils.rm spec_file
refute File.exist?(spec_file) refute File.exist?(spec_file)
@ -909,7 +850,7 @@ load Gem.bin_path('a', 'my_exec', version)
util_build_gem spec util_build_gem spec
File.join @gemhome, 'cache', "#{spec.full_name}.gem" File.join @gemhome, 'cache', spec.file_name
end end
end end

Some files were not shown because too many files have changed in this diff Show more