diff options
Diffstat (limited to 'lib/rubygems')
-rw-r--r-- | lib/rubygems/commands/check_command.rb | 3 | ||||
-rw-r--r-- | lib/rubygems/commands/unpack_command.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/commands/update_command.rb | 9 | ||||
-rw-r--r-- | lib/rubygems/config_file.rb | 5 | ||||
-rwxr-xr-x | lib/rubygems/custom_require.rb | 22 | ||||
-rw-r--r-- | lib/rubygems/defaults.rb | 5 | ||||
-rw-r--r-- | lib/rubygems/installer.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/rubygems_version.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/source_index.rb | 3 | ||||
-rwxr-xr-x | lib/rubygems/validator.rb | 272 |
10 files changed, 181 insertions, 144 deletions
diff --git a/lib/rubygems/commands/check_command.rb b/lib/rubygems/commands/check_command.rb index ca5e14b12d..17c2c8f9c7 100644 --- a/lib/rubygems/commands/check_command.rb +++ b/lib/rubygems/commands/check_command.rb @@ -31,7 +31,8 @@ class Gem::Commands::CheckCommand < Gem::Command def execute if options[:test] version = options[:version] || Gem::Requirement.default - gem_spec = Gem::SourceIndex.from_installed_gems.search(get_one_gem_name, version).first + dep = Gem::Dependency.new get_one_gem_name, version + gem_spec = Gem::SourceIndex.from_installed_gems.search(dep).first Gem::Validator.new.unit_test(gem_spec) end diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb index ef9436ae34..ab2494b0da 100644 --- a/lib/rubygems/commands/unpack_command.rb +++ b/lib/rubygems/commands/unpack_command.rb @@ -43,7 +43,7 @@ class Gem::Commands::UnpackCommand < Gem::Command basename = File.basename(path).sub(/\.gem$/, '') target_dir = File.expand_path File.join(options[:target], basename) FileUtils.mkdir_p target_dir - Gem::Installer.new(path).unpack target_dir + Gem::Installer.new(path, :unpack => true).unpack target_dir say "Unpacked gem: '#{target_dir}'" else alert_error "Gem '#{gemname}' not installed." diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index 4490f385dc..28d3a5d382 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -54,11 +54,10 @@ class Gem::Commands::UpdateCommand < Gem::Command fail "No gem names are allowed with the --system option" end - spec = Gem::Specification.new - spec.name = 'rubygems-update' - spec.version = Gem::Version.new Gem::RubyGemsVersion - spec.version = Gem::Version.new '1.1.1' - hig['rubygems-update'] = spec + rubygems_update = Gem::Specification.new + rubygems_update.name = 'rubygems-update' + rubygems_update.version = Gem::Version.new Gem::RubyGemsVersion + hig['rubygems-update'] = rubygems_update options[:user_install] = false else diff --git a/lib/rubygems/config_file.rb b/lib/rubygems/config_file.rb index 0a35ca9417..276a5c151d 100644 --- a/lib/rubygems/config_file.rb +++ b/lib/rubygems/config_file.rb @@ -52,6 +52,8 @@ class Gem::ConfigFile # Where to look for gems attr_accessor :path + attr_accessor :home + # True if we print backtraces on errors. attr_writer :backtrace @@ -129,7 +131,8 @@ class Gem::ConfigFile Gem.sources = @hash[:sources] if @hash.key? :sources @verbose = @hash[:verbose] if @hash.key? :verbose @update_sources = @hash[:update_sources] if @hash.key? :update_sources - @path = @hash[:gempath] + @path = @hash[:gempath] if @hash.key? :gempath + @home = @hash[:gemhome] if @hash.key? :gemhome handle_arguments arg_list end diff --git a/lib/rubygems/custom_require.rb b/lib/rubygems/custom_require.rb index 90e6b53959..78c7872b6f 100755 --- a/lib/rubygems/custom_require.rb +++ b/lib/rubygems/custom_require.rb @@ -7,11 +7,15 @@ require 'rubygems' module Kernel - alias gem_original_require require # :nodoc: - # - # We replace Ruby's require with our own, which is capable of - # loading gems on demand. + ## + # The Kernel#require from before RubyGems was loaded. + + alias gem_original_require require + + ## + # When RubyGems is required, Kernel#require is replaced with our own which + # is capable of loading gems on demand. # # When you call <tt>require 'x'</tt>, this is what happens: # * If the file can be loaded from the existing Ruby loadpath, it @@ -22,8 +26,8 @@ module Kernel # # The normal <tt>require</tt> functionality of returning false if # that file has already been loaded is preserved. - # - def require(path) # :nodoc: + + def require(path) # :doc: gem_original_require path rescue LoadError => load_error if load_error.message =~ /#{Regexp.escape path}\z/ and @@ -34,5 +38,9 @@ module Kernel raise load_error end end -end # module Kernel + + private :require + private :gem_original_require + +end diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb index 7eba0cb049..c894bf41be 100644 --- a/lib/rubygems/defaults.rb +++ b/lib/rubygems/defaults.rb @@ -1,5 +1,10 @@ module Gem + @post_install_hooks ||= [] + @post_uninstall_hooks ||= [] + @pre_uninstall_hooks ||= [] + @pre_install_hooks ||= [] + ## # An Array of the default sources that come with RubyGems diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb index d9006f9fc7..d719580a0a 100644 --- a/lib/rubygems/installer.rb +++ b/lib/rubygems/installer.rb @@ -137,7 +137,7 @@ class Gem::Installer options[:user_install] = true end - if options[:user_install] then + if options[:user_install] and not options[:unpack] then @gem_home = Gem.user_dir user_bin_dir = File.join(@gem_home, 'bin') diff --git a/lib/rubygems/rubygems_version.rb b/lib/rubygems/rubygems_version.rb index 06e2104715..d7b5622d97 100644 --- a/lib/rubygems/rubygems_version.rb +++ b/lib/rubygems/rubygems_version.rb @@ -2,5 +2,5 @@ # This file is auto-generated by build scripts. # See: rake update_version module Gem - RubyGemsVersion = '1.3.0' + RubyGemsVersion = '1.3.1' end diff --git a/lib/rubygems/source_index.rb b/lib/rubygems/source_index.rb index c6499ed2a8..8a8db2ef0d 100644 --- a/lib/rubygems/source_index.rb +++ b/lib/rubygems/source_index.rb @@ -257,8 +257,7 @@ class Gem::SourceIndex # TODO - Remove support and warning for legacy arguments after 2008/11 unless Gem::Dependency === gem_pattern - warn "Gem::SourceIndex#search support for #{gem_pattern.class} patterns is deprecated" - warn "#{caller[0]} is outdated" + warn "#{Gem.location_of_caller.join ':'}:Warning: Gem::SourceIndex#search support for #{gem_pattern.class} patterns is deprecated" end case gem_pattern diff --git a/lib/rubygems/validator.rb b/lib/rubygems/validator.rb index 8aaaa5a413..4595ad9a40 100755 --- a/lib/rubygems/validator.rb +++ b/lib/rubygems/validator.rb @@ -10,118 +10,130 @@ require 'rubygems/digest/md5' require 'rubygems/format' require 'rubygems/installer' -module Gem +## +# Validator performs various gem file and gem database validation + +class Gem::Validator + + include Gem::UserInteraction ## - # Validator performs various gem file and gem database validation - class Validator - include UserInteraction - - ## - # Given a gem file's contents, validates against its own MD5 checksum - # gem_data:: [String] Contents of the gem file - def verify_gem(gem_data) - raise VerificationError, 'empty gem file' if gem_data.size == 0 - - unless gem_data =~ /MD5SUM/ then - return # Don't worry about it...this sucks. Need to fix MD5 stuff for - # new format - # FIXME - end + # Given a gem file's contents, validates against its own MD5 checksum + # gem_data:: [String] Contents of the gem file - sum_data = gem_data.gsub(/MD5SUM = "([a-z0-9]+)"/, - "MD5SUM = \"#{"F" * 32}\"") + def verify_gem(gem_data) + raise Gem::VerificationError, 'empty gem file' if gem_data.size == 0 - unless Gem::MD5.hexdigest(sum_data) == $1.to_s then - raise VerificationError, 'invalid checksum for gem file' - end + unless gem_data =~ /MD5SUM/ then + return # Don't worry about it...this sucks. Need to fix MD5 stuff for + # new format + # FIXME end - ## - # Given the path to a gem file, validates against its own MD5 checksum - # - # gem_path:: [String] Path to gem file - def verify_gem_file(gem_path) - open gem_path, Gem.binary_mode do |file| - gem_data = file.read - verify_gem gem_data - end - rescue Errno::ENOENT - raise Gem::VerificationError.new("missing gem file #{gem_path}") + sum_data = gem_data.gsub(/MD5SUM = "([a-z0-9]+)"/, + "MD5SUM = \"#{"F" * 32}\"") + + unless Gem::MD5.hexdigest(sum_data) == $1.to_s then + raise Gem::VerificationError, 'invalid checksum for gem file' end + end - private - def find_files_for_gem(gem_directory) - installed_files = [] - Find.find(gem_directory) {|file_name| - fn = file_name.slice((gem_directory.size)..(file_name.size-1)).sub(/^\//, "") - if(!(fn =~ /CVS/ || File.directory?(fn) || fn == "")) then - installed_files << fn - end - - } - installed_files + ## + # Given the path to a gem file, validates against its own MD5 checksum + # + # gem_path:: [String] Path to gem file + + def verify_gem_file(gem_path) + open gem_path, Gem.binary_mode do |file| + gem_data = file.read + verify_gem gem_data end - - - public - ErrorData = Struct.new(:path, :problem) - - ## - # Checks the gem directory for the following potential - # inconsistencies/problems: - # * Checksum gem itself - # * For each file in each gem, check consistency of installed versions - # * Check for files that aren't part of the gem but are in the gems directory - # * 1 cache - 1 spec - 1 directory. - # - # returns a hash of ErrorData objects, keyed on the problem gem's name. - def alien - errors = {} - Gem::SourceIndex.from_installed_gems.each do |gem_name, gem_spec| - errors[gem_name] ||= [] - gem_path = File.join(Gem.dir, "cache", gem_spec.full_name) + ".gem" - spec_path = File.join(Gem.dir, "specifications", gem_spec.full_name) + ".gemspec" - gem_directory = File.join(Gem.dir, "gems", gem_spec.full_name) - installed_files = find_files_for_gem(gem_directory) - - if(!File.exist?(spec_path)) then - errors[gem_name] << ErrorData.new(spec_path, "Spec file doesn't exist for installed gem") - end - - begin - verify_gem_file(gem_path) - open gem_path, Gem.binary_mode do |file| - format = Gem::Format.from_file_by_path(gem_path) - format.file_entries.each do |entry, data| - # Found this file. Delete it from list - installed_files.delete remove_leading_dot_dir(entry['path']) - - next unless data # HACK `gem check -a mkrf` - - open File.join(gem_directory, entry['path']), Gem.binary_mode do |f| - unless Gem::MD5.hexdigest(f.read).to_s == - Gem::MD5.hexdigest(data).to_s then - errors[gem_name] << ErrorData.new(entry['path'], "installed file doesn't match original from gem") - end + rescue Errno::ENOENT + raise Gem::VerificationError, "missing gem file #{gem_path}" + end + + private + + def find_files_for_gem(gem_directory) + installed_files = [] + Find.find(gem_directory) {|file_name| + fn = file_name.slice((gem_directory.size)..(file_name.size-1)).sub(/^\//, "") + if(!(fn =~ /CVS/ || File.directory?(fn) || fn == "")) then + installed_files << fn + end + + } + installed_files + end + + public + + ErrorData = Struct.new :path, :problem + + ## + # Checks the gem directory for the following potential + # inconsistencies/problems: + # + # * Checksum gem itself + # * For each file in each gem, check consistency of installed versions + # * Check for files that aren't part of the gem but are in the gems directory + # * 1 cache - 1 spec - 1 directory. + # + # returns a hash of ErrorData objects, keyed on the problem gem's name. + + def alien + errors = {} + + Gem::SourceIndex.from_installed_gems.each do |gem_name, gem_spec| + errors[gem_name] ||= [] + + gem_path = File.join(Gem.dir, "cache", gem_spec.full_name) + ".gem" + spec_path = File.join(Gem.dir, "specifications", gem_spec.full_name) + ".gemspec" + gem_directory = File.join(Gem.dir, "gems", gem_spec.full_name) + + installed_files = find_files_for_gem(gem_directory) + + unless File.exist? spec_path then + errors[gem_name] << ErrorData.new(spec_path, "Spec file doesn't exist for installed gem") + end + + begin + verify_gem_file(gem_path) + + open gem_path, Gem.binary_mode do |file| + format = Gem::Format.from_file_by_path(gem_path) + format.file_entries.each do |entry, data| + # Found this file. Delete it from list + installed_files.delete remove_leading_dot_dir(entry['path']) + + next unless data # HACK `gem check -a mkrf` + + open File.join(gem_directory, entry['path']), Gem.binary_mode do |f| + unless Gem::MD5.hexdigest(f.read).to_s == + Gem::MD5.hexdigest(data).to_s then + errors[gem_name] << ErrorData.new(entry['path'], "installed file doesn't match original from gem") end end end - rescue VerificationError => e - errors[gem_name] << ErrorData.new(gem_path, e.message) - end - # Clean out directories that weren't explicitly included in the gemspec - # FIXME: This still allows arbitrary incorrect directories. - installed_files.delete_if {|potential_directory| - File.directory?(File.join(gem_directory, potential_directory)) - } - if(installed_files.size > 0) then - errors[gem_name] << ErrorData.new(gem_path, "Unmanaged files in gem: #{installed_files.inspect}") end + rescue Gem::VerificationError => e + errors[gem_name] << ErrorData.new(gem_path, e.message) + end + + # Clean out directories that weren't explicitly included in the gemspec + # FIXME: This still allows arbitrary incorrect directories. + installed_files.delete_if {|potential_directory| + File.directory?(File.join(gem_directory, potential_directory)) + } + if(installed_files.size > 0) then + errors[gem_name] << ErrorData.new(gem_path, "Unmanaged files in gem: #{installed_files.inspect}") end - errors end + errors + end + + if RUBY_VERSION < '1.9' then class TestRunner def initialize(suite, ui) @suite = suite @@ -147,40 +159,50 @@ module Gem end autoload :TestRunner, 'test/unit/ui/testrunnerutilities' - - ## - # Runs unit tests for a given gem specification - def unit_test(gem_spec) - start_dir = Dir.pwd - Dir.chdir(gem_spec.full_gem_path) - $: << File.join(Gem.dir, "gems", gem_spec.full_name) - # XXX: why do we need this gem_spec when we've already got 'spec'? - test_files = gem_spec.test_files - if test_files.empty? - say "There are no unit tests to run for #{gem_spec.full_name}" - require 'test/unit/ui/console/testrunner' - return Test::Unit::TestResult.new - end - gem gem_spec.name, "= #{gem_spec.version.version}" - test_files.each do |f| require f end + end + + ## + # Runs unit tests for a given gem specification + + def unit_test(gem_spec) + start_dir = Dir.pwd + Dir.chdir(gem_spec.full_gem_path) + $: << File.join(Gem.dir, "gems", gem_spec.full_name) + # XXX: why do we need this gem_spec when we've already got 'spec'? + test_files = gem_spec.test_files + + if test_files.empty? then + say "There are no unit tests to run for #{gem_spec.full_name}" + return nil + end + + gem gem_spec.name, "= #{gem_spec.version.version}" + + test_files.each do |f| require f end + + if RUBY_VERSION < '1.9' then suite = Test::Unit::TestSuite.new("#{gem_spec.name}-#{gem_spec.version}") + ObjectSpace.each_object(Class) do |klass| suite << klass.suite if (klass < Test::Unit::TestCase) end - result = TestRunner.run(suite, ui()) - unless result.passed? - alert_error(result.to_s) - #unless ask_yes_no(result.to_s + "...keep Gem?", true) then - #Gem::Uninstaller.new(gem_spec.name, gem_spec.version.version).uninstall - #end - end - result - ensure - Dir.chdir(start_dir) - end - def remove_leading_dot_dir(path) - path.sub(/^\.\//, "") + result = TestRunner.run suite, ui + + alert_error result.to_s unless result.passed? + else + result = MiniTest::Unit.new + result.run end + + result + ensure + Dir.chdir(start_dir) + end + + def remove_leading_dot_dir(path) + path.sub(/^\.\//, "") end + end + |