Browse files

Merge remote-tracking branch 'upstream/1.8' into wp-1.8

Conflicts:
	lib/rubygems.rb
  • Loading branch information...
2 parents 1244030 + a1827da commit ad191b6a4269e29cd8551ca5026ff6343c051ea5 @jfoy jfoy committed Aug 24, 2012
Showing with 4,795 additions and 167 deletions.
  1. +2 −1 .gitignore
  2. +0 −2 .travis.yml
  3. +124 −0 History.txt
  4. +7 −0 Manifest.txt
  5. +18 −5 Rakefile
  6. +9 −0 bin/gem
  7. +48 −20 lib/rubygems.rb
  8. +2 −2 lib/rubygems/builder.rb
  9. +6 −2 lib/rubygems/commands/build_command.rb
  10. +11 −2 lib/rubygems/commands/fetch_command.rb
  11. +5 −1 lib/rubygems/commands/pristine_command.rb
  12. +18 −8 lib/rubygems/commands/setup_command.rb
  13. +24 −2 lib/rubygems/commands/specification_command.rb
  14. +15 −1 lib/rubygems/config_file.rb
  15. +3 −2 lib/rubygems/custom_require.rb
  16. +7 −0 lib/rubygems/defaults.rb
  17. +15 −5 lib/rubygems/installer.rb
  18. +3 −1 lib/rubygems/installer_test_case.rb
  19. +18 −14 lib/rubygems/package/tar_input.rb
  20. +1 −0 lib/rubygems/platform.rb
  21. +9 −0 lib/rubygems/psych_additions.rb
  22. +27 −0 lib/rubygems/psych_tree.rb
  23. +58 −9 lib/rubygems/remote_fetcher.rb
  24. +11 −0 lib/rubygems/requirement.rb
  25. +6 −2 lib/rubygems/spec_fetcher.rb
  26. +55 −11 lib/rubygems/specification.rb
  27. +3,366 −0 lib/rubygems/ssl_certs/ca-bundle.pem
  28. +13 −0 lib/rubygems/syck_hack.rb
  29. +13 −20 lib/rubygems/test_case.rb
  30. +10 −0 lib/rubygems/version.rb
  31. +45 −0 test/rubygems/ca_cert.pem
  32. BIN test/rubygems/data/null-type.gemspec.rz
  33. +19 −0 test/rubygems/ssl_cert.pem
  34. +15 −0 test/rubygems/ssl_key.pem
  35. +105 −2 test/rubygems/test_gem.rb
  36. +16 −0 test/rubygems/test_gem_commands_build_command.rb
  37. +25 −0 test/rubygems/test_gem_commands_fetch_command.rb
  38. +33 −0 test/rubygems/test_gem_commands_install_command.rb
  39. +98 −0 test/rubygems/test_gem_commands_specification_command.rb
  40. +20 −0 test/rubygems/test_gem_config_file.rb
  41. +2 −2 test/rubygems/test_gem_ext_configure_builder.rb
  42. +197 −20 test/rubygems/test_gem_installer.rb
  43. +45 −31 test/rubygems/test_gem_platform.rb
  44. +103 −2 test/rubygems/test_gem_remote_fetcher.rb
  45. +10 −0 test/rubygems/test_gem_security.rb
  46. +158 −0 test/rubygems/test_gem_specification.rb
View
3 .gitignore
@@ -1,10 +1,11 @@
*.rbc
*.swp
.DS_Store
+scratch
/.rvmrc
/TAGS
/doc
/pkg
/tmp
/misc
-/notes.txt
+/notes.txt
View
2 .travis.yml
@@ -7,8 +7,6 @@ rvm:
- 1.8.7
- 1.9.2
- 1.9.3
- - jruby
- - rbx-2.0
- ruby-head
notifications:
email:
View
124 History.txt
@@ -1,5 +1,129 @@
# coding: UTF-8
+=== 1.8.24 / 2012-04-27
+
+* 1 bug fix:
+
+ * Install the .pem files properly. Fixes #320
+ * Remove OpenSSL dependency from the http code path
+
+=== 1.8.23 / 2012-04-19
+
+This release increases the security used when RubyGems is talking to
+an https server. If you use a custom RubyGems server over SSL, this
+release will cause RubyGems to no longer connect unless your SSL cert
+is globally valid.
+
+You can configure SSL certificate usage in RubyGems through the
+:ssl_ca_cert and :ssl_verify_mode options in ~/.gemrc and /etc/gemrc.
+The recommended way is to set :ssl_ca_cert to the CA certificate for
+your server or a certificate bundle containing your CA certification.
+
+You may also set :ssl_verify_mode to 0 to completely disable SSL
+certificate checks, but this is not recommended.
+
+
+* 2 security fixes:
+ * Disallow redirects from https to http
+ * Turn on verification of server SSL certs
+
+* 1 minor feature:
+ * Add --clear-sources to fetch
+
+* 2 bug fixes:
+ * Use File.identical? to check if two files are the same.
+ * Fixed init_with warning when using psych
+
+=== 1.8.22 / 2012-04-13
+
+* 4 bug fixes:
+
+ * Workaround for psych/syck YAML date parsing issue
+ * Don't trust the encoding of ARGV. Fixes #307
+ * Quiet default warnings about missing spec variables
+ * Read a binary file properly (windows fix)
+
+=== 1.8.21 / 2012-03-22
+
+* 2 bug fixes:
+
+ * Add workaround for buggy yaml output from 1.9.2
+ * Force 1.9.1 to remove it's prelude code. Fixes #305
+
+=== 1.8.20 / 2012-03-21
+
+* 4 bug fixes:
+
+ * Add --force to `gem build` to skip validation. Fixes #297
+ * Gracefully deal with YAML::PrivateType objects in Marshal'd gemspecs
+ * Treat the source as a proper url base. Fixes #304
+ * Warn when updating the specs cache fails. Fixes #300
+
+=== 1.8.19 / 2012-03-14
+
+* 3 bug fixes:
+
+ * Handle loading psych vs syck properly. Fixes #298
+ * Make sure Date objects don't leak in via Marshal
+ * Perform Date => Time coercion on yaml loading. Fixes #266
+
+=== 1.8.18 / 2012-03-11
+
+* 4 bug fixes:
+
+ * Use Psych API to emit more compatible YAML
+ * Download and write inside `gem fetch` directly. Fixes #289
+ * Honor sysconfdir on 1.8. Fixes #291
+ * Search everywhere for a spec for `gem spec`. Fixes #288
+ * Fix Gem.all_load_path. Fixes #171
+
+=== 1.8.17 / 2012-02-17
+
+* 2 minor enhancements:
+
+ * Add MacRuby to the list of special cases for platforms (ferrous26)
+ * Add a default for where to install rubygems itself
+
+* 3 bug fixes:
+
+ * Fixed gem loading issue caused by dependencies not resolving.
+ * Fixed umask error when stdlib is required and unresolved dependencies exist.
+ * Shebang munging would only take one arg after the cmd
+ * Define SUCKAGE better, ie only MRI 1.9.2
+ * Propagate env-shebang to the pristine command if set for install.
+
+=== 1.8.16 / 2012-02-12
+
+* 3 bug fixes:
+
+ * Fix gem specification loading when encoding is not UTF-8. #146
+ * Allow group writable if umask allows it already.
+ * Uniquify the spec list based on directory order priority
+
+=== 1.8.15 / 2012-01-06
+
+* 1 bug fix:
+
+ * Don't eager load yaml, it creates a bad loop. Fixes #256
+
+=== 1.8.14 / 2012-01-05
+
+* 2 bug fixes:
+
+ * Ignore old/bad cache data in Version
+ * Make sure our YAML workarounds are loaded properly. Fixes #250.
+
+=== 1.8.13 / 2011-12-21
+
+* 1 bug fix:
+
+ * Check loaded_specs properly when trying to satisfy a dep
+
+* 2 minor enhancements:
+
+ * Remove using #loaded_path? for performance
+ * Remove Zlib workaround for Windows build.
+
=== 1.8.12 / 2011-12-02
* Bug fix:
View
7 Manifest.txt
@@ -86,6 +86,8 @@ lib/rubygems/package/tar_writer.rb
lib/rubygems/package_task.rb
lib/rubygems/path_support.rb
lib/rubygems/platform.rb
+lib/rubygems/psych_additions.rb
+lib/rubygems/psych_tree.rb
lib/rubygems/remote_fetcher.rb
lib/rubygems/require_paths_builder.rb
lib/rubygems/requirement.rb
@@ -94,6 +96,7 @@ lib/rubygems/server.rb
lib/rubygems/source_index.rb
lib/rubygems/spec_fetcher.rb
lib/rubygems/specification.rb
+lib/rubygems/ssl_certs/ca-bundle.pem
lib/rubygems/syck_hack.rb
lib/rubygems/test_case.rb
lib/rubygems/test_utilities.rb
@@ -106,8 +109,10 @@ lib/rubygems/version_option.rb
lib/ubygems.rb
setup.rb
test/rubygems/bogussources.rb
+test/rubygems/ca_cert.pem
test/rubygems/data/gem-private_key.pem
test/rubygems/data/gem-public_cert.pem
+test/rubygems/data/null-type.gemspec.rz
test/rubygems/fake_certlib/openssl.rb
test/rubygems/fix_openssl_warnings.rb
test/rubygems/foo/discover.rb
@@ -121,6 +126,8 @@ test/rubygems/rubygems/commands/crash_command.rb
test/rubygems/rubygems_plugin.rb
test/rubygems/sff/discover.rb
test/rubygems/simple_gem.rb
+test/rubygems/ssl_cert.pem
+test/rubygems/ssl_key.pem
test/rubygems/test_config.rb
test/rubygems/test_deprecate.rb
test/rubygems/test_gem.rb
View
23 Rakefile
@@ -18,7 +18,7 @@ Hoe::RUBY_FLAGS << " --disable-gems" if RUBY_VERSION > "1.9"
Hoe.plugin :minitest
Hoe.plugin :git
-Hoe.plugin :isolate
+# Hoe.plugin :isolate
hoe = Hoe.spec 'rubygems-update' do
self.rubyforge_name = 'rubygems'
@@ -56,6 +56,8 @@ hoe = Hoe.spec 'rubygems-update' do
rdoc_options << "--title=RubyGems #{self.version} Documentation"
end
+ self.rsync_args += " --no-p -O"
+
# FIX: this exists because update --system installs the gem and
# doesn't uninstall it. It should uninstall or better, not install
# in the first place.
@@ -82,7 +84,7 @@ end
task :prerelease => [:clobber, :check_manifest, :test]
-task :postrelease => :publish_docs
+task :postrelease => [:publish_docs, :upload]
pkg_dir_path = "pkg/rubygems-update-#{hoe.version}"
task :package do
@@ -93,13 +95,23 @@ task :package do
end
end
+desc "Upload release to rubyforge"
task :upload_to_rubyforge do
v = hoe.version
sh "rubyforge add_release rubygems rubygems #{v} pkg/rubygems-update-#{v}.gem"
sh "rubyforge add_file rubygems rubygems #{v} pkg/rubygems-#{v}.zip"
sh "rubyforge add_file rubygems rubygems #{v} pkg/rubygems-#{v}.tgz"
end
+desc "Upload release to gemcutter S3"
+task :upload_to_gemcutter do
+ v = hoe.version
+ sh "s3cmd put -P pkg/rubygems-update-#{v}.gem pkg/rubygems-#{v}.zip pkg/rubygems-#{v}.tgz s3://production.s3.rubygems.org/rubygems/"
+end
+
+desc "Upload release to rubyforge and gemcutter"
+task :upload => [:upload_to_rubyforge, :upload_to_gemcutter]
+
# Misc Tasks ---------------------------------------------------------
# These tasks expect to have the following directory structure:
@@ -126,7 +138,7 @@ def diff_with dir
sh "diff #{diff_options} lib/rubygems.rb #{dir}/lib/rubygems.rb; true"
sh "diff #{diff_options} lib/rubygems #{dir}/lib/rubygems; true"
sh "diff #{diff_options} lib/rbconfig #{dir}/lib/rbconfig; true"
- sh "diff #{diff_options} test #{dir}/test/rubygems; true"
+ sh "diff #{diff_options} test/rubygems #{dir}/test/rubygems; true"
end
rubinius_dir = ENV['RUBINIUS_PATH'] || '../git.rubini.us/code'
@@ -214,10 +226,11 @@ task "git:newchangelog" do
now = Time.new.strftime "%Y-%m-%d"
changes = `#{cmd}`.split(/\|\|\|/).each_slice(3).map do |msg, author, email|
- msg.split(/\n/).reject { |s| s.empty? }
+ c = msg.split(/\n/).reject { |s| s.empty? }
+ c.empty? ? nil : c.first
end
- changes = changes.flatten
+ changes = changes.flatten.compact
next if changes.empty?
View
9 bin/gem
@@ -5,6 +5,15 @@
# See LICENSE.txt for permissions.
#++
+# The prelude in 1.9.1 injects rubygems.rb into $LOADED_FEATURES
+# which prevents the `require 'rubygems'` from actually loading
+# the site's version of rubygems. So we have to use it's API
+# to get it's prelude out of the way.
+#
+if RUBY_VERSION =~ /^1\.9\.1/ && defined?(Gem::QuickLoader)
+ Gem::QuickLoader.load_full_rubygems_library
+end
+
require 'rubygems'
require 'rubygems/gem_runner'
require 'rubygems/exceptions'
View
68 lib/rubygems.rb
@@ -7,7 +7,9 @@
module Gem
QUICKLOADER_SUCKAGE = RUBY_VERSION =~ /^1\.9\.1/
- GEM_PRELUDE_SUCKAGE = RUBY_VERSION =~ /^1\.9\.2/
+
+ # Only MRI 1.9.2 has the custom prelude.
+ GEM_PRELUDE_SUCKAGE = RUBY_VERSION =~ /^1\.9\.2/ && RUBY_ENGINE == "ruby"
end
if Gem::GEM_PRELUDE_SUCKAGE and defined?(Gem::QuickLoader) then
@@ -111,6 +113,7 @@ class << Gem
# * Phil Hagelberg -- technomancy(at)gmail.com
# * Ryan Davis -- ryand-ruby(at)zenspider.com
# * Alex Chaffee -- alex(at)stinky.com
+# * Evan Phoenix -- evan@phx.io
#
# (If your name is missing, PLEASE let us know!)
#
@@ -119,7 +122,7 @@ class << Gem
# -The RubyGems Team
module Gem
- VERSION = '1.8.12'
+ VERSION = '1.8.24'
##
# Raised when RubyGems is unable to load or activate a gem. Contains the
@@ -257,7 +260,7 @@ def self.all_load_paths
Gem.path.each do |gemdir|
each_load_path all_partials(gemdir) do |load_path|
- result << gemdir.add(load_path).expand_path
+ result << load_path
end
end
@@ -443,10 +446,10 @@ def self.each_load_path(partials)
# problem, then we will silently continue.
def self.ensure_gem_subdirectories dir = Gem.dir
- require 'fileutils'
-
old_umask = File.umask
- File.umask old_umask | 022
+ File.umask old_umask | 002
+
+ require 'fileutils'
%w[cache doc gems specifications].each do |name|
subdir = File.join dir, name
@@ -640,28 +643,54 @@ def self.load_path_insert_index
index
end
+ @yaml_loaded = false
+
##
# Loads YAML, preferring Psych
def self.load_yaml
- begin
- gem 'psych', '~> 1.2', '>= 1.2.1' unless ENV['TEST_SYCK']
- rescue Gem::LoadError
- # It's OK if the user does not have the psych gem installed. We will
- # attempt to require the stdlib version
+ return if @yaml_loaded
+
+ test_syck = ENV['TEST_SYCK']
+
+ unless test_syck
+ begin
+ gem 'psych', '~> 1.2', '>= 1.2.1'
+ rescue Gem::LoadError
+ # It's OK if the user does not have the psych gem installed. We will
+ # attempt to require the stdlib version
+ end
+
+ begin
+ # Try requiring the gem version *or* stdlib version of psych.
+ require 'psych'
+ rescue ::LoadError
+ # If we can't load psych, thats fine, go on.
+ else
+ # If 'yaml' has already been required, then we have to
+ # be sure to switch it over to the newly loaded psych.
+ if defined?(YAML::ENGINE) && YAML::ENGINE.yamler != "psych"
+ YAML::ENGINE.yamler = "psych"
+ end
+
+ require 'rubygems/psych_additions'
+ require 'rubygems/psych_tree'
+ end
end
- begin
- # Try requiring the gem version *or* stdlib version of psych.
- require 'psych' unless ENV['TEST_SYCK']
- rescue ::LoadError
- ensure
- require 'yaml'
+ require 'yaml'
+
+ # If we're supposed to be using syck, then we may have to force
+ # activate it via the YAML::ENGINE API.
+ if test_syck and defined?(YAML::ENGINE)
+ YAML::ENGINE.yamler = "syck" unless YAML::ENGINE.syck?
end
# Now that we're sure some kind of yaml library is loaded, pull
# in our hack to deal with Syck's DefaultKey ugliness.
require 'rubygems/syck_hack'
+
+ @yaml_loaded = true
end
##
@@ -981,9 +1010,8 @@ def self.suffix_pattern
def self.loaded_path? path
# TODO: ruby needs a feature to let us query what's loaded in 1.8 and 1.9
- $LOADED_FEATURES.find { |s|
- s =~ /(^|\/)#{Regexp.escape path}#{Regexp.union(*Gem.suffixes)}$/
- }
+ re = /(^|\/)#{Regexp.escape path}#{Regexp.union(*Gem.suffixes)}$/
+ $LOADED_FEATURES.any? { |s| s =~ re }
end
##
View
4 lib/rubygems/builder.rb
@@ -32,9 +32,9 @@ def initialize(spec)
# Builds the gem from the specification. Returns the name of the file
# written.
- def build
+ def build(skip_validation=false)
@spec.mark_version
- @spec.validate
+ @spec.validate unless skip_validation
@signer = sign
write_package
say success if Gem.configuration.verbose
View
8 lib/rubygems/commands/build_command.rb
@@ -4,7 +4,11 @@
class Gem::Commands::BuildCommand < Gem::Command
def initialize
- super('build', 'Build a gem from a gemspec')
+ super 'build', 'Build a gem from a gemspec'
+
+ add_option '--force', 'skip validation of the spec' do |value, options|
+ options[:force] = true
+ end
end
def arguments # :nodoc:
@@ -22,7 +26,7 @@ def execute
spec = load_gemspec gemspec
if spec then
- Gem::Builder.new(spec).build
+ Gem::Builder.new(spec).build options[:force]
else
alert_error "Error loading gemspec. Aborting."
terminate_interaction 1
View
13 lib/rubygems/commands/fetch_command.rb
@@ -13,6 +13,7 @@ def initialize
add_bulk_threshold_option
add_proxy_option
add_source_option
+ add_clear_sources_option
add_version_option
add_platform_option
@@ -58,8 +59,16 @@ def execute
next
end
- path = Gem::RemoteFetcher.fetcher.download spec, source_uri
- FileUtils.mv path, File.basename(spec.cache_file)
+ file = "#{spec.full_name}.gem"
+ remote_path = URI.parse(source_uri) + "gems/#{file}"
+
+ fetch = Gem::RemoteFetcher.fetcher
+
+ gem = fetch.fetch_path remote_path.to_s
+
+ File.open file, "wb" do |f|
+ f.write gem
+ end
say "Downloaded #{spec.full_name}"
end
View
6 lib/rubygems/commands/pristine_command.rb
@@ -94,10 +94,14 @@ def execute
end
# TODO use installer options
+ install_defaults = Gem::ConfigFile::PLATFORM_DEFAULTS['install']
+ installer_env_shebang = install_defaults.to_s['--env-shebang']
+
installer = Gem::Installer.new(gem,
:wrappers => true,
:force => true,
- :install_dir => spec.base_dir)
+ :install_dir => spec.base_dir,
+ :env_shebang => installer_env_shebang)
installer.install
say "Restored #{spec.full_name}"
View
26 lib/rubygems/commands/setup_command.rb
@@ -165,7 +165,7 @@ def install_executables(bin_dir)
end
dest_file = File.join bin_dir, bin_file_formatted
- bin_tmp_file = File.join Dir.tmpdir, bin_file
+ bin_tmp_file = File.join Dir.tmpdir, "#{bin_file}.#{$$}"
begin
bin = File.readlines bin_file
@@ -209,7 +209,10 @@ def install_lib(lib_dir)
say "Installing RubyGems" if @verbose
Dir.chdir 'lib' do
- lib_files = Dir[File.join('**', '*rb')]
+ lib_files = Dir[File.join('**', '*rb')]
+
+ # Be sure to include our SSL ca bundles
+ lib_files += Dir[File.join('**', '*pem')]
lib_files.each do |lib_file|
dest_file = File.join lib_dir, lib_file
@@ -252,9 +255,19 @@ def install_rdoc
end
def make_destination_dirs(install_destdir)
- lib_dir = nil
- bin_dir = nil
+ lib_dir, bin_dir = Gem.default_rubygems_dirs
+
+ unless lib_dir
+ lib_dir, bin_dir = generate_default_dirs(install_destdir)
+ end
+ mkdir_p lib_dir
+ mkdir_p bin_dir
+
+ return lib_dir, bin_dir
+ end
+
+ def generate_default_dirs(install_destdir)
prefix = options[:prefix]
site_or_vendor = options[:site_or_vendor]
@@ -283,10 +296,7 @@ def make_destination_dirs(install_destdir)
bin_dir = File.join install_destdir, bin_dir.gsub(/^[a-zA-Z]:/, '')
end
- mkdir_p lib_dir
- mkdir_p bin_dir
-
- return lib_dir, bin_dir
+ [lib_dir, bin_dir]
end
def remove_old_bin_files(bin_dir)
View
26 lib/rubygems/commands/specification_command.rb
@@ -62,7 +62,25 @@ def execute
"Please specify a gem name or file on the command line"
end
- dep = Gem::Dependency.new gem, options[:version]
+ case options[:version]
+ when String
+ req = Gem::Requirement.parse options[:version]
+ when Gem::Requirement
+ req = options[:version]
+ else
+ raise Gem::CommandLineError, "Unsupported version type: #{options[:version]}"
+ end
+
+ if !req.none? and options[:all]
+ alert_error "Specify --all or -v, not both"
+ terminate_interaction 1
+ end
+
+ if options[:all]
+ dep = Gem::Dependency.new gem
+ else
+ dep = Gem::Dependency.new gem, options[:version]
+ end
field = get_one_optional_argument
@@ -80,7 +98,11 @@ def execute
end
if remote? then
- found = Gem::SpecFetcher.fetcher.fetch dep
+ found = Gem::SpecFetcher.fetcher.fetch dep, true
+
+ if dep.prerelease? or options[:prerelease]
+ found += Gem::SpecFetcher.fetcher.fetch dep, false, true, true
+ end
specs.push(*found.map { |spec,| spec })
end
View
16 lib/rubygems/config_file.rb
@@ -25,6 +25,8 @@
# +:sources+:: Sets Gem::sources
# +:verbose+:: See #verbose
+require 'rbconfig'
+
class Gem::ConfigFile
DEFAULT_BACKTRACE = false
@@ -68,7 +70,7 @@ class Gem::ConfigFile
path.strip
rescue LoadError
- "/etc"
+ RbConfig::CONFIG["sysconfdir"] || "/etc"
end
end
@@ -129,6 +131,16 @@ class Gem::ConfigFile
attr_reader :api_keys
##
+ # openssl verify mode value, used for remote https connection
+
+ attr_reader :ssl_verify_mode
+
+ ##
+ # Path name of directory or file of openssl CA certificate, used for remote https connection
+
+ attr_reader :ssl_ca_cert
+
+ ##
# Create the config file object. +args+ is the list of arguments
# from the command line.
#
@@ -190,6 +202,8 @@ def initialize(arg_list)
@path = @hash[:gempath] if @hash.key? :gempath
@update_sources = @hash[:update_sources] if @hash.key? :update_sources
@verbose = @hash[:verbose] if @hash.key? :verbose
+ @ssl_verify_mode = @hash[:ssl_verify_mode] if @hash.key? :ssl_verify_mode
+ @ssl_ca_cert = @hash[:ssl_ca_cert] if @hash.key? :ssl_ca_cert
load_api_keys
View
5 lib/rubygems/custom_require.rb
@@ -32,7 +32,7 @@ module Kernel
# that file has already been loaded is preserved.
def require path
- if Gem.unresolved_deps.empty? or Gem.loaded_path? path then
+ if Gem.unresolved_deps.empty? then
gem_original_require path
else
spec = Gem::Specification.find { |s|
@@ -55,7 +55,8 @@ def require path
return gem_original_require path
end
rescue LoadError => load_error
- if load_error.message.end_with?(path) and Gem.try_activate(path) then
+ if load_error.message.start_with?("Could not find") or
+ (load_error.message.end_with?(path) and Gem.try_activate(path)) then
return gem_original_require(path)
end
View
7 lib/rubygems/defaults.rb
@@ -44,6 +44,13 @@ def self.default_dir
end
##
+ # Paths where RubyGems' .rb files and bin files are installed
+
+ def self.default_rubygems_dirs
+ nil # default to standard layout
+ end
+
+ ##
# Path for gems in the user's home directory
def self.user_dir
View
20 lib/rubygems/installer.rb
@@ -366,7 +366,7 @@ def shebang(bin_file_name)
if /\A#!/ =~ first_line then
# Preserve extra words on shebang line, like "-w". Thanks RPA.
- shebang = first_line.sub(/\A\#!.*?ruby\S*(?=(\s+\S+))/, "#!#{Gem.ruby}")
+ shebang = first_line.sub(/\A\#!.*?ruby\S*((\s+\S+)+)/, "#!#{Gem.ruby}")
opts = $1
shebang.strip! # Avoid nasty ^M issues.
end
@@ -435,7 +435,13 @@ def process_options
def check_that_user_bin_dir_is_in_path
user_bin_dir = @bin_dir || Gem.bindir(gem_home)
user_bin_dir.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if File::ALT_SEPARATOR
- unless ENV['PATH'].split(File::PATH_SEPARATOR).include? user_bin_dir then
+ path = ENV['PATH']
+ if Gem.win_platform? then
+ path = path.downcase
+ user_bin_dir = user_bin_dir.downcase
+ end
+
+ unless path.split(File::PATH_SEPARATOR).include? user_bin_dir then
unless self.class.path_warning then
alert_warning "You don't have #{user_bin_dir} in your PATH,\n\t gem executables will not run."
self.class.path_warning = true
@@ -466,9 +472,13 @@ def app_script_text(bin_file_name)
version = "#{Gem::Requirement.default}"
-if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
- version = $1
- ARGV.shift
+if ARGV.first
+ str = ARGV.first
+ str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+ if str =~ /\\A_(.*)_\\z/
+ version = $1
+ ARGV.shift
+ end
end
gem '#{spec.name}', version
View
4 lib/rubygems/installer_test_case.rb
@@ -118,7 +118,9 @@ def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic
FileUtils.mkdir_p 'bin'
FileUtils.mkdir_p 'lib'
FileUtils.mkdir_p File.join('ext', 'a')
- File.open File.join('bin', 'executable'), 'w' do |f| f.puts '1' end
+ File.open File.join('bin', 'executable'), 'w' do |f|
+ f.puts "raise 'ran executable'"
+ end
File.open File.join('lib', 'code.rb'), 'w' do |f| f.puts '1' end
File.open File.join('ext', 'a', 'mkrf_conf.rb'), 'w' do |f|
f << <<-EOF
View
32 lib/rubygems/package/tar_input.rb
@@ -210,21 +210,25 @@ def load_gemspec(io)
# the unpacking speed) we threw our hands in the air and declared that
# this method would use the String IO approach on all platforms at all
# times. And that's the way it is.
-
+ #
+ # Revisited. Here's the beginning of the long story.
+ # http://osdir.com/ml/lang.ruby.gems.devel/2007-06/msg00045.html
+ #
+ # StringIO wraping has never worked as a workaround by definition. Skipping
+ # initial 10 bytes and passing -MAX_WBITS to Zlib::Inflate luckily works as
+ # gzip reader, but it only works if the GZip header is 10 bytes long (see
+ # below) and it does not check inflated stream consistency (CRC value in the
+ # Gzip trailer.)
+ #
+ # RubyGems generated Gzip Header: 10 bytes
+ # magic(2) + method(1) + flag(1) + mtime(4) + exflag(1) + os(1) +
+ # orig_name(0) + comment(0)
+ #
+ # Ideally, it must return a GZipReader without meaningless buffering. We
+ # have lots of CRuby committers around so let's fix windows build when we
+ # received an error.
def zipped_stream(entry)
- if defined? Rubinius or defined? Maglev then
- # these implementations have working Zlib
- zis = Zlib::GzipReader.new entry
- dis = zis.read
- is = StringIO.new(dis)
- else
- # This is Jamis Buck's Zlib workaround for some unknown issue
- entry.read(10) # skip the gzip header
- zis = Zlib::Inflate.new(-Zlib::MAX_WBITS)
- is = StringIO.new(zis.inflate(entry.read))
- end
- ensure
- zis.finish if zis
+ Zlib::GzipReader.new entry
end
end
View
1 lib/rubygems/platform.rb
@@ -68,6 +68,7 @@ def initialize(arch)
when /aix(\d+)/ then [ 'aix', $1 ]
when /cygwin/ then [ 'cygwin', nil ]
when /darwin(\d+)?/ then [ 'darwin', $1 ]
+ when /^macruby$/ then [ 'macruby', nil ]
when /freebsd(\d+)/ then [ 'freebsd', $1 ]
when /hpux(\d+)/ then [ 'hpux', $1 ]
when /^java$/, /^jruby$/ then [ 'java', nil ]
View
9 lib/rubygems/psych_additions.rb
@@ -0,0 +1,9 @@
+# This exists just to satify bugs in marshal'd gemspecs that
+# contain a reference to YAML::PrivateType. We prune these out
+# in Specification._load, but if we don't have the constant, Marshal
+# blows up.
+
+module Psych
+ class PrivateType
+ end
+end
View
27 lib/rubygems/psych_tree.rb
@@ -0,0 +1,27 @@
+module Gem
+ if defined? ::Psych::Visitors
+ class NoAliasYAMLTree < Psych::Visitors::YAMLTree
+ def visit_String(str)
+ return super unless str == '=' # or whatever you want
+
+ quote = Psych::Nodes::Scalar::SINGLE_QUOTED
+ @emitter.scalar str, nil, nil, false, true, quote
+ end
+
+ # Noop this out so there are no anchors
+ def register(target, obj)
+ end
+
+ # This is ported over from the yaml_tree in 1.9.3
+ def format_time time
+ if time.utc?
+ time.strftime("%Y-%m-%d %H:%M:%S.%9N Z")
+ else
+ time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z")
+ end
+ end
+
+ private :format_time
+ end
+ end
+end
View
67 lib/rubygems/remote_fetcher.rb
@@ -8,6 +8,8 @@
class Gem::RemoteFetcher
+ BuiltinSSLCerts = File.expand_path("./ssl_certs/*.pem", File.dirname(__FILE__))
+
include Gem::UserInteraction
##
@@ -174,7 +176,7 @@ def download(spec, source_uri, install_dir = Gem.dir)
begin
FileUtils.cp source_path, local_gem_path unless
- File.expand_path(source_path) == File.expand_path(local_gem_path)
+ File.identical?(source_path, local_gem_path)
rescue Errno::EACCES
local_gem_path = source_uri.to_s
end
@@ -210,6 +212,11 @@ def fetch_http uri, last_modified = nil, head = false, depth = 0
raise FetchError.new('too many redirects', uri) if depth > 10
location = URI.parse response['Location']
+
+ if https?(uri) && !https?(location)
+ raise FetchError.new("redirecting to non-https resource: #{location}", uri)
+ end
+
fetch_http(location, last_modified, head, depth + 1)
else
raise FetchError.new("bad response #{response.message} #{response.code}", uri)
@@ -312,17 +319,55 @@ def connection_for(uri)
@connections[connection_id] ||= Net::HTTP.new(*net_http_args)
connection = @connections[connection_id]
- if uri.scheme == 'https' and not connection.started? then
- require 'net/https'
- connection.use_ssl = true
- connection.verify_mode = OpenSSL::SSL::VERIFY_NONE
- end
+ if https?(uri) and !connection.started? then
+ configure_connection_for_https(connection)
- connection.start unless connection.started?
+ # Don't refactor this with the else branch. We don't want the
+ # http-only code path to not depend on anything in OpenSSL.
+ #
+ begin
+ connection.start
+ rescue OpenSSL::SSL::SSLError, Errno::EHOSTDOWN => e
+ raise FetchError.new(e.message, uri)
+ end
+ else
+ begin
+ connection.start unless connection.started?
+ rescue Errno::EHOSTDOWN => e
+ raise FetchError.new(e.message, uri)
+ end
+ end
connection
- rescue Errno::EHOSTDOWN => e
- raise FetchError.new(e.message, uri)
+ end
+
+ def configure_connection_for_https(connection)
+ require 'net/https'
+
+ connection.use_ssl = true
+ connection.verify_mode =
+ Gem.configuration.ssl_verify_mode || OpenSSL::SSL::VERIFY_PEER
+
+ store = OpenSSL::X509::Store.new
+
+ if Gem.configuration.ssl_ca_cert
+ if File.directory? Gem.configuration.ssl_ca_cert
+ store.add_path Gem.configuration.ssl_ca_cert
+ else
+ store.add_file Gem.configuration.ssl_ca_cert
+ end
+ else
+ store.set_default_paths
+ add_rubygems_trusted_certs(store)
+ end
+
+ connection.cert_store = store
+ end
+
+ def add_rubygems_trusted_certs(store)
+ Dir.glob(BuiltinSSLCerts).each do |ssl_cert_file|
+ store.add_file ssl_cert_file
+ end
end
def correct_for_windows_path(path)
@@ -465,5 +510,9 @@ def user_agent
ua
end
+ def https?(uri)
+ uri.scheme.downcase == 'https'
+ end
+
end
View
11 lib/rubygems/requirement.rb
@@ -4,6 +4,15 @@
# A Requirement is a set of one or more version restrictions. It supports a
# few (<tt>=, !=, >, <, >=, <=, ~></tt>) different restriction operators.
+# REFACTOR: The fact that a requirement is singular or plural is kind of
+# awkward. Is Requirement the right name for this? Or should it be one
+# [op, number] pair, and we call the list of requirements something else?
+# Since a Requirement is held by a Dependency, maybe this should be made
+# singular and the list aspect should be pulled up into Dependency?
+
+require "rubygems/version"
+require "rubygems/deprecate"
+
class Gem::Requirement
include Comparable
@@ -174,6 +183,8 @@ def <=> other # :nodoc:
private
def fix_syck_default_key_in_requirements
+ Gem.load_yaml
+
# Fixup the Syck DefaultKey bug
@requirements.each do |r|
if r[0].kind_of? Gem::SyckDefaultKey
View
8 lib/rubygems/spec_fetcher.rb
@@ -255,8 +255,12 @@ def load_specs(source_uri, file)
loaded = false
if File.exist? local_file then
- spec_dump =
- @fetcher.fetch_path(spec_path, File.mtime(local_file)) rescue nil
+ begin
+ spec_dump =
+ @fetcher.fetch_path(spec_path, File.mtime(local_file))
+ rescue Gem::RemoteFetcher::FetchError => e
+ alert_warning "Error fetching data: #{e.message}"
+ end
loaded = true if spec_dump
View
66 lib/rubygems/specification.rb
@@ -262,18 +262,19 @@ class Gem::Specification
def self._all # :nodoc:
unless defined?(@@all) && @@all then
- specs = []
+ specs = {}
- self.dirs.reverse_each { |dir|
+ self.dirs.each { |dir|
Dir[File.join(dir, "*.gemspec")].each { |path|
spec = Gem::Specification.load path.untaint
# #load returns nil if the spec is bad, so we just ignore
# it at this stage
- specs << spec if spec
+ specs[spec.full_name] ||= spec if spec
}
}
- @@all = specs
+ @@all = specs.values
+
_resort!
end
@@all
@@ -484,6 +485,8 @@ def self.find_in_unresolved_tree path
# +input+ can be anything that YAML.load() accepts: String or IO.
def self.from_yaml(input)
+ Gem.load_yaml
+
input = normalize_yaml_input input
spec = YAML.load input
@@ -535,7 +538,7 @@ def self.load file
file = file.dup.untaint
code = if defined? Encoding
- File.read file, :encoding => "UTF-8"
+ File.read file, :mode => 'r:UTF-8:-'
else
File.read file
end
@@ -663,11 +666,16 @@ def self._load(str)
raise TypeError, "invalid Gem::Specification format #{array.inspect}"
end
+ # Cleanup any YAML::PrivateType. They only show up for an old bug
+ # where nil => null, so just convert them to nil based on the type.
+
+ array.map! { |e| e.kind_of?(YAML::PrivateType) ? nil : e }
+
spec.instance_variable_set :@rubygems_version, array[0]
# spec version
spec.instance_variable_set :@name, array[2]
spec.instance_variable_set :@version, array[3]
- spec.instance_variable_set :@date, array[4]
+ spec.date = array[4]
spec.instance_variable_set :@summary, array[5]
spec.instance_variable_set :@required_ruby_version, array[6]
spec.instance_variable_set :@required_rubygems_version, array[7]
@@ -756,8 +764,16 @@ def activate
def activate_dependencies
self.runtime_dependencies.each do |spec_dep|
- # TODO: check for conflicts! not just name!
- next if Gem.loaded_specs.include? spec_dep.name
+ if loaded = Gem.loaded_specs[spec_dep.name]
+ next if spec_dep.matches_spec? loaded
+
+ msg = "can't satisfy '#{spec_dep}', already activated '#{loaded.full_name}'"
+ e = Gem::LoadError.new msg
+ e.name = spec_dep.name
+
+ raise e
+ end
+
specs = spec_dep.to_specs
if specs.size == 1 then
@@ -986,6 +1002,12 @@ def date= date
when String then
if /\A(\d{4})-(\d{2})-(\d{2})\Z/ =~ date then
Time.utc($1.to_i, $2.to_i, $3.to_i)
+
+ # Workaround for where the date format output from psych isn't
+ # parsed as a Time object by syck and thus comes through as a
+ # string.
+ elsif /\A(\d{4})-(\d{2})-(\d{2}) \d{2}:\d{2}:\d{2}\.\d+?Z\z/ =~ date then
+ Time.utc($1.to_i, $2.to_i, $3.to_i)
else
raise(Gem::InvalidSpecificationException,
"invalid date format in specification: #{date.inspect}")
@@ -1362,7 +1384,7 @@ def initialize_copy other_spec
val = other_spec.instance_variable_get(name)
if val then
instance_variable_set name, val.dup
- else
+ elsif Gem.configuration.really_verbose
warn "WARNING: #{full_name} has an invalid nil value for #{name}"
end
rescue TypeError
@@ -1912,7 +1934,23 @@ def to_s # :nodoc:
def to_yaml(opts = {}) # :nodoc:
if YAML.const_defined?(:ENGINE) && !YAML::ENGINE.syck? then
- super.gsub(/ !!null \n/, " \n")
+ # Because the user can switch the YAML engine behind our
+ # back, we have to check again here to make sure that our
+ # psych code was properly loaded, and load it if not.
+ unless Gem.const_defined?(:NoAliasYAMLTree)
+ require 'rubygems/psych_tree'
+ end
+
+ builder = Gem::NoAliasYAMLTree.new({})
+ builder << self
+ ast = builder.tree
+
+ io = StringIO.new
+ io.set_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
+
+ Psych::Visitors::Emitter.new(io).accept(ast)
+
+ io.string.gsub(/ !!null \n/, " \n")
else
YAML.quick_emit object_id, opts do |out|
out.map taguri, to_yaml_style do |map|
@@ -2097,7 +2135,13 @@ def version= version
# FIX: have this handle the platform/new_platform/original_platform bullshit
def yaml_initialize(tag, vals) # :nodoc:
vals.each do |ivar, val|
- instance_variable_set "@#{ivar}", val
+ case ivar
+ when "date"
+ # Force Date to go through the extra coerce logic in date=
+ self.date = val.untaint
+ else
+ instance_variable_set "@#{ivar}", val.untaint
+ end
end
@original_platform = @platform # for backwards compatibility
View
3,366 lib/rubygems/ssl_certs/ca-bundle.pem
3,366 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
13 lib/rubygems/syck_hack.rb
@@ -15,8 +15,16 @@ module YAML
# being underneith YAML. If so, reference it back under YAML as
# well.
if defined? ::Syck
+ # for tests that change YAML::ENGINE
+ # 1.8 does not support the second argument to const_defined?
+ remove_const :Syck rescue nil
+
Syck = ::Syck
+ # JRuby's "Syck" is called "Yecht"
+ elsif defined? YAML::Yecht
+ Syck = YAML::Yecht
+
# Otherwise, if there is no YAML::Syck, then we've got just psych
# loaded, so lets define a stub for DefaultKey.
elsif !defined? YAML::Syck
@@ -31,6 +39,8 @@ class DefaultKey
# should.
module Syck
class DefaultKey
+ remove_method :to_s rescue nil
+
def to_s
'='
end
@@ -55,6 +65,9 @@ def to_s
# place to find the DefaultKey class for comparison.
module Gem
+ # for tests that change YAML::ENGINE
+ remove_const :SyckDefaultKey if const_defined? :SyckDefaultKey
+
SyckDefaultKey = YAML::Syck::DefaultKey
end
View
33 lib/rubygems/test_case.rb
@@ -243,7 +243,7 @@ def teardown
##
# Builds and installs the Gem::Specification +spec+
- def install_gem spec
+ def install_gem spec, options = {}
require 'rubygems/installer'
use_ui Gem::MockGemUi.new do
@@ -254,26 +254,14 @@ def install_gem spec
gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint
- Gem::Installer.new(gem, :wrappers => true).install
+ Gem::Installer.new(gem, options.merge({:wrappers => true})).install
end
##
# Builds and installs the Gem::Specification +spec+ into the user dir
def install_gem_user spec
- require 'rubygems/installer'
-
- use_ui Gem::MockGemUi.new do
- Dir.chdir @tempdir do
- Gem::Builder.new(spec).build
- end
- end
-
- gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint
-
- i = Gem::Installer.new(gem, :wrappers => true, :user_install => true)
- i.install
- i.spec
+ install_gem spec, :user_install => true
end
##
@@ -499,8 +487,11 @@ def util_spec(name, version, deps = nil, &block)
if deps then
block = proc do |s|
- deps.each do |n, req|
- s.add_dependency n, (req || '>= 0')
+ # Since Hash#each is unordered in 1.8, sort
+ # the keys and iterate that way so the tests are
+ # deteriminstic on all implementations.
+ deps.keys.sort.each do |n|
+ s.add_dependency n, (deps[n] || '>= 0')
end
end
end
@@ -520,8 +511,11 @@ def util_gem(name, version, deps = nil, &block)
if deps then
block = proc do |s|
- deps.each do |n, req|
- s.add_dependency n, (req || '>= 0')
+ # Since Hash#each is unordered in 1.8, sort
+ # the keys and iterate that way so the tests are
+ # deteriminstic on all implementations.
+ deps.keys.sort.each do |n|
+ s.add_dependency n, (deps[n] || '>= 0')
end
end
end
@@ -874,4 +868,3 @@ def v string
end
end
-
View
10 lib/rubygems/version.rb
@@ -218,6 +218,10 @@ def hash # :nodoc:
@hash ||= segments.hash
end
+ def init_with coder # :nodoc:
+ yaml_initialize coder.tag, coder.map
+ end
+
def inspect # :nodoc:
"#<#{self.class} #{version.inspect}>"
end
@@ -238,6 +242,12 @@ def marshal_load array
initialize array[0]
end
+ def yaml_initialize(tag, map)
+ @version = map['version']
+ @segments = nil
+ @hash = nil
+ end
+
##
# A version is considered a prerelease if it contains a letter.
View
45 test/rubygems/ca_cert.pem
@@ -0,0 +1,45 @@
+-----BEGIN CERTIFICATE-----
+MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
+DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ
+BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR
+wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d
+L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY
+bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi
+JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm
+dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA
+AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w
+ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f
+USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe
+31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu
+SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD
+ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+
+r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY
+MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
+PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
+PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
+d/xgcK06UVQRL/HbEYGiQL056mc=
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
+DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
+BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
+ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
+d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
+kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
+3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
+4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
+AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
+cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
+LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
+rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
+c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
+LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
+ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
+SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
+uY/bPeOBYiVsOYVe
+-----END CERTIFICATE-----
View
BIN test/rubygems/data/null-type.gemspec.rz
Binary file not shown.
View
19 test/rubygems/ssl_cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB
+MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx
+EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh
+bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku
+p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S
+vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/
+vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg
+hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
+BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud
+JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP
+CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo
+zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ
+RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60
+DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0
+jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM
+rRlQ
+-----END CERTIFICATE-----
View
15 test/rubygems/ssl_key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2
+cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv
+MkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB
+AoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O
+rk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W
+IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ
+Oynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK
+gQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma
+qm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU
+9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm
+syhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L
+mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH
+LjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy
+-----END RSA PRIVATE KEY-----
View
107 test/rubygems/test_gem.rb
@@ -353,6 +353,29 @@ def test_self_activate_conflict
##
# [A] depends on
+ # [C] = 1.0 depends on
+ # [B] = 2.0
+ # [B] ~> 1.0 (satisfied by 1.0)
+
+ def test_self_activate_checks_dependencies
+ a, _ = util_spec 'a', '1.0'
+ a.add_dependency 'c', '= 1.0'
+ a.add_dependency 'b', '~> 1.0'
+
+ util_spec 'b', '1.0'
+ util_spec 'b', '2.0'
+ c, _ = util_spec 'c', '1.0', 'b' => '= 2.0'
+
+ e = assert_raises Gem::LoadError do
+ assert_activate nil, a, c, "b"
+ end
+
+ expected = "can't satisfy 'b (~> 1.0)', already activated 'b-2.0'"
+ assert_equal expected, e.message
+ end
+
+ ##
+ # [A] depends on
# [B] ~> 1.0 (satisfied by 1.0)
# [C] = 1.0 depends on
# [B] = 2.0
@@ -606,8 +629,8 @@ def test_self_ensure_gem_directories_safe_permissions
File.umask 0
Gem.ensure_gem_subdirectories @gemhome
- assert_equal 0, File::Stat.new(@gemhome).mode & 022
- assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 022
+ assert_equal 0, File::Stat.new(@gemhome).mode & 002
+ assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 002
ensure
File.umask old_umask
end unless win_platform?
@@ -1099,6 +1122,86 @@ def test_latest_load_paths
end
end
+ def test_gem_path_ordering
+ refute_equal Gem.dir, Gem.user_dir
+
+ write_file File.join(@tempdir, 'lib', "g.rb") { |fp| fp.puts "" }
+ write_file File.join(@tempdir, 'lib', 'm.rb') { |fp| fp.puts "" }
+
+ g = new_spec 'g', '1', nil, "lib/g.rb"
+ m = new_spec 'm', '1', nil, "lib/m.rb"
+
+ install_gem g, :install_dir => Gem.dir
+ m0 = install_gem m, :install_dir => Gem.dir
+ m1 = install_gem m, :install_dir => Gem.user_dir
+
+ assert_equal m0.gem_dir, File.join(Gem.dir, "gems", "m-1")
+ assert_equal m1.gem_dir, File.join(Gem.user_dir, "gems", "m-1")
+
+ tests = [
+ [:dir0, [ Gem.dir, Gem.user_dir], m0],
+ [:dir1, [ Gem.user_dir, Gem.dir], m1]
+ ]
+
+ tests.each do |_name, _paths, expected|
+ Gem.paths = { 'GEM_HOME' => _paths.first, 'GEM_PATH' => _paths }
+ Gem::Specification.reset
+ Gem.searcher = nil
+
+ assert_equal Gem::Dependency.new('m','1').to_specs,
+ Gem::Dependency.new('m','1').to_specs.sort
+
+ assert_equal \
+ [expected.gem_dir],
+ Gem::Dependency.new('m','1').to_specs.map(&:gem_dir).sort,
+ "Wrong specs for #{_name}"
+
+ spec = Gem::Dependency.new('m','1').to_spec
+
+ assert_equal \
+ File.join(_paths.first, "gems", "m-1"),
+ spec.gem_dir,
+ "Wrong spec before require for #{_name}"
+ refute spec.activated?, "dependency already activated for #{_name}"
+
+ gem "m"
+
+ spec = Gem::Dependency.new('m','1').to_spec
+ assert spec.activated?, "dependency not activated for #{_name}"
+
+ assert_equal \
+ File.join(_paths.first, "gems", "m-1"),
+ spec.gem_dir,
+ "Wrong spec after require for #{_name}"
+
+ spec.instance_variable_set :@activated, false
+ Gem.loaded_specs.delete(spec.name)
+ $:.delete(File.join(spec.gem_dir, "lib"))
+ end
+ end
+
+ def test_gem_path_ordering_short
+ write_file File.join(@tempdir, 'lib', "g.rb") { |fp| fp.puts "" }
+ write_file File.join(@tempdir, 'lib', 'm.rb') { |fp| fp.puts "" }
+
+ g = new_spec 'g', '1', nil, "lib/g.rb"
+ m = new_spec 'm', '1', nil, "lib/m.rb"
+
+ install_gem g, :install_dir => Gem.dir
+ install_gem m, :install_dir => Gem.dir
+ install_gem m, :install_dir => Gem.user_dir
+
+ Gem.paths = {
+ 'GEM_HOME' => Gem.dir,
+ 'GEM_PATH' => [ Gem.dir, Gem.user_dir]
+ }
+
+ assert_equal \
+ File.join(Gem.dir, "gems", "m-1"),
+ Gem::Dependency.new('m','1').to_spec.gem_dir,
+ "Wrong spec selected"
+ end
+
def with_plugin(path)
test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}",
@@project_dir)
View
16 test/rubygems/test_gem_commands_build_command.rb
@@ -98,5 +98,21 @@ def util_test_build_gem(gem, gemspec_file)
assert_equal "this is a summary", spec.summary
end
+ def test_execute_force
+ @gem.instance_variable_set :@required_rubygems_version, nil
+
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_yaml
+ end
+
+ @cmd.options[:args] = [gemspec_file]
+ @cmd.options[:force] = true
+
+ util_test_build_gem @gem, gemspec_file
+ end
+
+
end
View
25 test/rubygems/test_gem_commands_fetch_command.rb
@@ -73,5 +73,30 @@ def test_execute_version
"#{@a1.full_name} not fetched"
end
+ def test_execute_handles_sources_properly
+ repo = "http://gems.example.com"
+ @uri = URI.parse repo
+
+ Gem.sources.replace [repo]
+
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher @a1, @a2
+
+ @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] =
+ File.read(@a1.cache_file)
+
+ @cmd.options[:args] = [@a2.name]
+ @cmd.options[:version] = Gem::Requirement.new '1'
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, @a1.file_name)),
+ "#{@a1.full_name} not fetched"
+ end
+
end
View
33 test/rubygems/test_gem_commands_install_command.rb
@@ -3,6 +3,7 @@
begin
gem "rdoc"
+ gem "json"
rescue Gem::LoadError
# ignore
end
@@ -177,6 +178,38 @@ def test_execute_nonexistent
assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error)
end
+ def test_execute_bad_source
+ util_setup_fake_fetcher
+ util_setup_spec_fetcher
+
+ # This is needed because we need to exercise the cache path
+ # within SpecFetcher
+ path = File.join Gem.user_home, '.gem', 'specs', "not-there.nothing%80",
+ "latest_specs.4.8"
+
+ FileUtils.mkdir_p File.dirname(path)
+
+ File.open path, "w" do |f|
+ f.write Marshal.dump([])
+ end
+
+ Gem.sources.replace ["http://not-there.nothing"]
+
+ @cmd.options[:args] = %w[nonexistent]
+
+ use_ui @ui do
+ e = assert_raises Gem::SystemExitException do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ errs = @ui.error.split("\n")
+
+ assert_match(/WARNING: Error fetching data/, errs.shift)
+ assert_match(/ould not find a valid gem 'nonexistent'/, errs.shift)
+ end
+
def test_execute_nonexistent_with_hint
misspelled = "nonexistent_with_hint"
correctly_spelled = "non_existent_with_hint"
View
98 test/rubygems/test_gem_commands_specification_command.rb
@@ -43,6 +43,24 @@ def test_execute_all
assert_equal '', @ui.error
end
+ def test_execute_all_conflicts_with_version
+ quick_spec 'foo', '0.0.1'
+ quick_spec 'foo', '0.0.2'
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:all] = true
+ @cmd.options[:version] = "1"
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Specify --all or -v, not both\n", @ui.error
+ end
+
def test_execute_bad_name
@cmd.options[:args] = %w[foo]
@@ -122,6 +140,86 @@ def test_execute_remote
assert_match %r|name: foo|, @ui.output
end
+ def test_execute_remote_with_version
+ foo1 = quick_gem 'foo', "1"
+ foo2 = quick_gem 'foo', "2"
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher foo1, foo2
+
+ FileUtils.rm File.join(@gemhome, 'specifications', foo1.spec_name)
+ FileUtils.rm File.join(@gemhome, 'specifications', foo2.spec_name)
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:version] = "1"
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ spec = Gem::Specification.from_yaml @ui.output
+
+ assert_equal Gem::Version.new("1"), spec.version
+ end
+
+ def test_execute_remote_without_prerelease
+ foo = new_spec 'foo', '2.0.0'
+ foo_pre = new_spec 'foo', '2.0.1.pre'
+
+ install_specs foo, foo_pre
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher foo
+ util_setup_spec_fetcher foo_pre
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+
+ spec = YAML.load @ui.output
+
+ assert_equal Gem::Version.new("2.0.0"), spec.version
+ end
+
+ def test_execute_remote_with_prerelease
+ foo = new_spec 'foo', '2.0.0'
+ foo_pre = new_spec 'foo', '2.0.1.pre'
+
+ install_specs foo, foo_pre
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ util_setup_spec_fetcher foo
+ util_setup_spec_fetcher foo_pre
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+
+ spec = YAML.load @ui.output
+
+ assert_equal Gem::Version.new("2.0.1.pre"), spec.version
+ end
+
def test_execute_ruby
foo = quick_spec 'foo'
View
20 test/rubygems/test_gem_config_file.rb
@@ -52,6 +52,8 @@ def test_initialize
fp.puts ":gempath:"
fp.puts "- /usr/ruby/1.8/lib/ruby/gems/1.8"
fp.puts "- /var/ruby/1.8/gem_home"
+ fp.puts ":ssl_verify_mode: 0"
+ fp.puts ":ssl_ca_cert: /etc/ssl/certs"
end
util_config_file
@@ -65,6 +67,8 @@ def test_initialize
assert_equal '--wrappers', @cfg[:install]
assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'],
@cfg.path)
+ assert_equal 0, @cfg.ssl_verify_mode
+ assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert
end
def test_initialize_handle_arguments_config_file
@@ -291,6 +295,22 @@ def test_load_api_keys_from_config
:other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys)
end
+ def test_load_ssl_verify_mode_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_verify_mode: 1"
+ end
+ util_config_file
+ assert_equal(1, @cfg.ssl_verify_mode)
+ end
+
+ def test_load_ssl_ca_cert_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_ca_cert: /home/me/certs"
+ end
+ util_config_file
+ assert_equal('/home/me/certs', @cfg.ssl_ca_cert)
+ end
+
def util_config_file(args = @cfg_args)
@cfg = Gem::ConfigFile.new args
end
View
4 test/rubygems/test_gem_ext_configure_builder.rb
@@ -46,13 +46,13 @@ def test_self_build_fail
end
end
- shell_error_msg = %r{(\./configure: .*)|(Can't open \./configure(?:: No such file or directory)?)}
+ shell_error_msg = %r{(\./configure: .*)|((?:Can't|cannot) open \./configure(?:: No such file or directory)?)}
sh_prefix_configure = "sh ./configure --prefix="
expected = %r(configure failed:
#{Regexp.escape sh_prefix_configure}#{Regexp.escape @dest_path}
-.*?: #{shell_error_msg}
+(?:.*?: )?#{shell_error_msg}
)
assert_match expected, error.message
View
217 test/rubygems/test_gem_installer.rb
@@ -2,26 +2,23 @@
class TestGemInstaller < Gem::InstallerTestCase
- def setup
- super
+ def util_setup_install
+ @gemhome = @installer_tmp
+ Gem.use_paths @installer_tmp
- if __name__ !~ /^test_install(_|$)/ then
- @gemhome = @installer_tmp
- Gem.use_paths @installer_tmp
+ @spec = Gem::Specification.find_by_name 'a'
+ @user_spec = Gem::Specification.find_by_name 'b'
- @spec = Gem::Specification.find_by_name 'a'
- @user_spec = Gem::Specification.find_by_name 'b'
-
- @installer.spec = @spec
- @installer.gem_home = @installer_tmp
- @installer.gem_dir = @spec.gem_dir
- @user_installer.spec = @user_spec
- @user_installer.gem_home = @installer_tmp
- end
+ @installer.spec = @spec
+ @installer.gem_home = @installer_tmp
+ @installer.gem_dir = @spec.gem_dir
+ @user_installer.spec = @user_spec
+ @user_installer.gem_home = @installer_tmp
end
-
def test_app_script_text
+ util_setup_install
+
@spec.version = 2
util_make_exec @spec, ''
@@ -38,9 +35,13 @@ def test_app_script_text
version = \">= 0\"
-if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
- version = $1
- ARGV.shift
+if ARGV.first
+ str = ARGV.first
+ str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
+ if str =~ /\\A_(.*)_\\z/
+ version = $1
+ ARGV.shift
+ end
end
gem 'a', version
@@ -52,6 +53,8 @@ def test_app_script_text
end
def test_build_extensions_none
+ util_setup_install
+
use_ui @ui do
@installer.build_extensions
end
@@ -63,6 +66,8 @@ def test_build_extensions_none
end
def test_build_extensions_extconf_bad
+ util_setup_install
+
@spec.extensions << 'extconf.rb'
e = assert_raises Gem::Installer::ExtensionBuildError do
@@ -86,6 +91,8 @@ def test_build_extensions_extconf_bad
end
def test_build_extensions_unsupported
+ util_setup_install
+
gem_make_out = File.join @gemhome, 'gems', @spec.full_name, 'gem_make.out'
@spec.extensions << nil
@@ -107,6 +114,8 @@ def test_build_extensions_unsupported
end
def test_ensure_dependency
+ util_setup_install
+
dep = Gem::Dependency.new 'a', '>= 2'
assert @installer.ensure_dependency(@spec, dep)
@@ -119,6 +128,8 @@ def test_ensure_dependency
end
def test_extract_files
+ util_setup_install
+
format = Object.new
def format.file_entries
[[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'content']]
@@ -137,6 +148,8 @@ def format.file_entries
end
def test_extract_files_bad_dest
+ util_setup_install
+
@installer.gem_dir = 'somedir'
@installer.format = nil
e = assert_raises ArgumentError do
@@ -147,6 +160,8 @@ def test_extract_files_bad_dest
end
def test_extract_files_relative
+ util_setup_install
+
format = Object.new
def format.file_entries
[[{'size' => 10, 'mode' => 0644, 'path' => '../thefile'}, '../thefile']]
@@ -166,6 +181,8 @@ def format.file_entries
end
def test_extract_files_absolute
+ util_setup_install
+
format = Object.new
def format.file_entries
[[{'size' => 8, 'mode' => 0644, 'path' => '/thefile'}, '/thefile']]
@@ -183,6 +200,8 @@ def format.file_entries
end
def test_generate_bin_bindir
+ util_setup_install
+
@installer.wrappers = true
@spec.executables = %w[executable]
@@ -208,7 +227,10 @@ def test_generate_bin_bindir
end
def test_generate_bin_bindir_with_user_install_warning
- bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]) : "/usr/bin"
+ util_setup_install
+
+ bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase :
+ "/usr/bin"
options = {
:bin_dir => bin_dir,