diff options
Diffstat (limited to 'lib/rubygems/commands')
-rw-r--r-- | lib/rubygems/commands/build_command.rb | 24 | ||||
-rw-r--r-- | lib/rubygems/commands/cert_command.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/commands/cleanup_command.rb | 29 | ||||
-rw-r--r-- | lib/rubygems/commands/contents_command.rb | 31 | ||||
-rw-r--r-- | lib/rubygems/commands/dependency_command.rb | 68 | ||||
-rw-r--r-- | lib/rubygems/commands/fetch_command.rb | 11 | ||||
-rw-r--r-- | lib/rubygems/commands/install_command.rb | 3 | ||||
-rw-r--r-- | lib/rubygems/commands/lock_command.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/commands/outdated_command.rb | 8 | ||||
-rw-r--r-- | lib/rubygems/commands/pristine_command.rb | 50 | ||||
-rw-r--r-- | lib/rubygems/commands/query_command.rb | 15 | ||||
-rw-r--r-- | lib/rubygems/commands/server_command.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/commands/setup_command.rb | 2 | ||||
-rw-r--r-- | lib/rubygems/commands/specification_command.rb | 31 | ||||
-rw-r--r-- | lib/rubygems/commands/stale_command.rb | 3 | ||||
-rw-r--r-- | lib/rubygems/commands/unpack_command.rb | 60 | ||||
-rw-r--r-- | lib/rubygems/commands/update_command.rb | 40 | ||||
-rw-r--r-- | lib/rubygems/commands/which_command.rb | 14 |
18 files changed, 214 insertions, 187 deletions
diff --git a/lib/rubygems/commands/build_command.rb b/lib/rubygems/commands/build_command.rb index 5aac489459..cdae367365 100644 --- a/lib/rubygems/commands/build_command.rb +++ b/lib/rubygems/commands/build_command.rb @@ -23,32 +23,34 @@ class Gem::Commands::BuildCommand < Gem::Command def execute gemspec = get_one_gem_name - if File.exist?(gemspec) - specs = load_gemspecs(gemspec) - specs.each do |spec| + + if File.exist? gemspec + spec = load_gemspec gemspec + + if spec then Gem::Builder.new(spec).build + else + alert_error "Error loading gemspec. Aborting." + terminate_interaction 1 end else alert_error "Gemspec file not found: #{gemspec}" + terminate_interaction 1 end end - def load_gemspecs(filename) + def load_gemspec filename if yaml?(filename) - result = [] open(filename) do |f| begin - while not f.eof? and spec = Gem::Specification.from_yaml(f) - result << spec - end + Gem::Specification.from_yaml(f) rescue Gem::EndOfYAMLException - # OK + nil end end else - result = [Gem::Specification.load(filename)] + Gem::Specification.load(filename) # can return nil end - result end def yaml?(filename) diff --git a/lib/rubygems/commands/cert_command.rb b/lib/rubygems/commands/cert_command.rb index 17eaaa113f..d667f5c3a3 100644 --- a/lib/rubygems/commands/cert_command.rb +++ b/lib/rubygems/commands/cert_command.rb @@ -56,7 +56,7 @@ class Gem::Commands::CertCommand < Gem::Command 'Build private key and self-signed', 'certificate for EMAIL_ADDR.') do |value, options| vals = Gem::Security.build_self_signed_cert(value) - File.chmod 0600, vals[:key_path] + FileUtils.chmod 0600, vals[:key_path] say "Public Cert: #{vals[:cert_path]}" say "Private Key: #{vals[:key_path]}" say "Don't forget to move the key file to somewhere private..." diff --git a/lib/rubygems/commands/cleanup_command.rb b/lib/rubygems/commands/cleanup_command.rb index 0cdf50433e..2d8d8ff4fc 100644 --- a/lib/rubygems/commands/cleanup_command.rb +++ b/lib/rubygems/commands/cleanup_command.rb @@ -5,7 +5,6 @@ ###################################################################### require 'rubygems/command' -require 'rubygems/source_index' require 'rubygems/dependency_list' require 'rubygems/uninstaller' @@ -44,28 +43,20 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it. say "Cleaning up installed gems..." primary_gems = {} - Gem.source_index.each do |name, spec| + Gem::Specification.each do |spec| if primary_gems[spec.name].nil? or primary_gems[spec.name].version < spec.version then primary_gems[spec.name] = spec end end - gems_to_cleanup = [] - - unless options[:args].empty? then - options[:args].each do |gem_name| - dep = Gem::Dependency.new gem_name, Gem::Requirement.default - specs = Gem.source_index.search dep - specs.each do |spec| - gems_to_cleanup << spec - end - end - else - Gem.source_index.each do |name, spec| - gems_to_cleanup << spec - end - end + gems_to_cleanup = unless options[:args].empty? then + options[:args].map do |gem_name| + Gem::Specification.find_all_by_name gem_name + end.flatten + else + Gem::Specification.to_a + end gems_to_cleanup = gems_to_cleanup.select { |spec| primary_gems[spec.name].version != spec.version @@ -89,8 +80,8 @@ installed elsewhere in GEM_PATH the cleanup command won't touch it. :version => "= #{spec.version}", } - if Gem.user_dir == spec.installation_path then - uninstall_options[:install_dir] = spec.installation_path + if Gem.user_dir == spec.base_dir then + uninstall_options[:install_dir] = spec.base_dir end uninstaller = Gem::Uninstaller.new spec.name, uninstall_options diff --git a/lib/rubygems/commands/contents_command.rb b/lib/rubygems/commands/contents_command.rb index 42ae913b01..8e015ae9da 100644 --- a/lib/rubygems/commands/contents_command.rb +++ b/lib/rubygems/commands/contents_command.rb @@ -58,24 +58,24 @@ class Gem::Commands::ContentsCommand < Gem::Command end.flatten path_kind = if spec_dirs.empty? then - spec_dirs = Gem::SourceIndex.installed_spec_directories + spec_dirs = Gem::Specification.dirs "default gem paths" else "specified path" end - si = Gem::SourceIndex.from_gems_in(*spec_dirs) - gem_names = if options[:all] then - si.map { |_, spec| spec.name } + Gem::Specification.map(&:name) else get_all_gem_names end gem_names.each do |name| - gem_spec = si.find_name(name, version).last + # HACK: find_by_name fails for some reason... ARGH + # How many places must we embed our resolve logic? + spec = Gem::Specification.find_all_by_name(name, version).last - unless gem_spec then + unless spec then say "Unable to find gem '#{name}' in #{path_kind}" if Gem.configuration.verbose then @@ -86,16 +86,19 @@ class Gem::Commands::ContentsCommand < Gem::Command terminate_interaction 1 if gem_names.length == 1 end - files = options[:lib_only] ? gem_spec.lib_files : gem_spec.files + gem_path = spec.full_gem_path + extra = "/{#{spec.require_paths.join ','}}" if options[:lib_only] + glob = "#{gem_path}#{extra}/**/*" + files = Dir[glob] + + gem_path = File.join gem_path, '' # add trailing / if missing + + files.sort.each do |file| + next if File.directory? file - files.each do |f| - path = if options[:prefix] then - File.join gem_spec.full_gem_path, f - else - f - end + file = file.sub gem_path, '' unless options[:prefix] - say path + say file end end end diff --git a/lib/rubygems/commands/dependency_command.rb b/lib/rubygems/commands/dependency_command.rb index b6840c35d4..209fdebd50 100644 --- a/lib/rubygems/commands/dependency_command.rb +++ b/lib/rubygems/commands/dependency_command.rb @@ -49,13 +49,13 @@ class Gem::Commands::DependencyCommand < Gem::Command end def execute - options[:args] << '' if options[:args].empty? - specs = {} - - source_indexes = Hash.new do |h, source_uri| - h[source_uri] = Gem::SourceIndex.new + if options[:reverse_dependencies] and remote? and not local? then + alert_error 'Only reverse dependencies for local gems are supported.' + terminate_interaction 1 end + options[:args] << '' if options[:args].empty? + pattern = if options[:args].length == 1 and options[:args].first =~ /\A\/(.*)\/(i)?\z/m then flags = $2 ? Regexp::IGNORECASE : nil @@ -64,34 +64,30 @@ class Gem::Commands::DependencyCommand < Gem::Command /\A#{Regexp.union(*options[:args])}/ end - dependency = Gem::Dependency.new pattern, options[:version] + # TODO: deprecate for real damnit + dependency = Deprecate.skip_during { + Gem::Dependency.new pattern, options[:version] + } dependency.prerelease = options[:prerelease] - if options[:reverse_dependencies] and remote? and not local? then - alert_error 'Only reverse dependencies for local gems are supported.' - terminate_interaction 1 - end + specs = [] - if local? then - Gem.source_index.search(dependency).each do |spec| - source_indexes[:local].add_spec spec - end - end + specs.concat dependency.matching_specs if local? if remote? and not options[:reverse_dependencies] then fetcher = Gem::SpecFetcher.fetcher - specs_and_sources = fetcher.find_matching(dependency, false, true, + # REFACTOR: fetcher.find_specs_matching => specs + specs_and_sources = fetcher.find_matching(dependency, + dependency.specific?, true, dependency.prerelease?) - specs_and_sources.each do |spec_tuple, source_uri| - spec = fetcher.fetch_spec spec_tuple, URI.parse(source_uri) - - source_indexes[source_uri].add_spec spec - end + specs.concat specs_and_sources.map { |spec_tuple, source_uri| + fetcher.fetch_spec spec_tuple, URI.parse(source_uri) + } end - if source_indexes.empty? then + if specs.empty? then patterns = options[:args].join ',' say "No gems found matching #{patterns} (#{options[:version]})" if Gem.configuration.verbose @@ -99,24 +95,18 @@ class Gem::Commands::DependencyCommand < Gem::Command terminate_interaction 1 end - specs = {} - - source_indexes.values.each do |source_index| - source_index.gems.each do |name, spec| - specs[spec.full_name] = [source_index, spec] - end - end + specs = specs.uniq.sort reverse = Hash.new { |h, k| h[k] = [] } if options[:reverse_dependencies] then - specs.values.each do |_, spec| + specs.each do |spec| reverse[spec.full_name] = find_reverse_dependencies spec end end if options[:pipe_format] then - specs.values.sort_by { |_, spec| spec }.each do |_, spec| + specs.each do |spec| unless spec.dependencies.empty? spec.dependencies.sort_by { |dep| dep.name }.each do |dep| say "#{dep.name} --version '#{dep.requirement}'" @@ -126,7 +116,7 @@ class Gem::Commands::DependencyCommand < Gem::Command else response = '' - specs.values.sort_by { |_, spec| spec }.each do |_, spec| + specs.each do |spec| response << print_dependencies(spec) unless reverse[spec.full_name].empty? then response << " Used by\n" @@ -158,7 +148,7 @@ class Gem::Commands::DependencyCommand < Gem::Command def find_reverse_dependencies(spec) result = [] - Gem.source_index.each do |name, sp| + Gem::Specification.each do |sp| sp.dependencies.each do |dep| dep = Gem::Dependency.new(*dep) unless Gem::Dependency === dep @@ -172,17 +162,5 @@ class Gem::Commands::DependencyCommand < Gem::Command result end - def find_gems(name, source_index) - specs = {} - - spec_list = source_index.search name, options[:version] - - spec_list.each do |spec| - specs[spec.full_name] = [source_index, spec] - end - - specs - end - end diff --git a/lib/rubygems/commands/fetch_command.rb b/lib/rubygems/commands/fetch_command.rb index c0fdc83e46..7d99276506 100644 --- a/lib/rubygems/commands/fetch_command.rb +++ b/lib/rubygems/commands/fetch_command.rb @@ -41,19 +41,22 @@ class Gem::Commands::FetchCommand < Gem::Command version = options[:version] || Gem::Requirement.default all = Gem::Requirement.default != version + platform = Gem.platforms.last gem_names = get_all_gem_names gem_names.each do |gem_name| dep = Gem::Dependency.new gem_name, version dep.prerelease = options[:prerelease] - specs_and_sources = Gem::SpecFetcher.fetcher.fetch(dep, all, true, - dep.prerelease?) - specs_and_sources, errors = Gem::SpecFetcher.fetcher.fetch_with_errors(dep, all, true, dep.prerelease?) + if platform then + filtered = specs_and_sources.select { |s,| s.platform == platform } + specs_and_sources = filtered unless filtered.empty? + end + spec, source_uri = specs_and_sources.sort_by { |s,| s.version }.last if spec.nil? then @@ -62,7 +65,7 @@ class Gem::Commands::FetchCommand < Gem::Command end path = Gem::RemoteFetcher.fetcher.download spec, source_uri - FileUtils.mv path, spec.file_name + FileUtils.mv path, File.basename(spec.cache_file) say "Downloaded #{spec.full_name}" end diff --git a/lib/rubygems/commands/install_command.rb b/lib/rubygems/commands/install_command.rb index 530f746e89..fff41cf6e0 100644 --- a/lib/rubygems/commands/install_command.rb +++ b/lib/rubygems/commands/install_command.rb @@ -120,7 +120,8 @@ to write the specification by hand. For example: get_all_gem_names.each do |gem_name| begin - next if options[:conservative] && Gem.available?(gem_name, options[:version]) + next if options[:conservative] and + not Gem::Dependency.new(gem_name, options[:version]).matching_specs.empty? inst = Gem::DependencyInstaller.new options inst.install gem_name, options[:version] diff --git a/lib/rubygems/commands/lock_command.rb b/lib/rubygems/commands/lock_command.rb index a17dd36d7a..9ce9da6899 100644 --- a/lib/rubygems/commands/lock_command.rb +++ b/lib/rubygems/commands/lock_command.rb @@ -93,7 +93,7 @@ lock it down to the exact version. spec.runtime_dependencies.each do |dep| next if locked[dep.name] - candidates = Gem.source_index.search dep + candidates = dep.matching_specs if candidates.empty? then complain "Unable to satisfy '#{dep}' from currently installed gems" @@ -105,11 +105,11 @@ lock it down to the exact version. end def spec_path(gem_full_name) - gemspecs = Gem.path.map do |path| + gemspecs = Gem.path.map { |path| File.join path, "specifications", "#{gem_full_name}.gemspec" - end + } - gemspecs.find { |gemspec| File.exist? gemspec } + gemspecs.find { |path| File.exist? path } end end diff --git a/lib/rubygems/commands/outdated_command.rb b/lib/rubygems/commands/outdated_command.rb index 7b6e1cfe8e..8b7dda6c7d 100644 --- a/lib/rubygems/commands/outdated_command.rb +++ b/lib/rubygems/commands/outdated_command.rb @@ -22,10 +22,8 @@ class Gem::Commands::OutdatedCommand < Gem::Command end def execute - locals = Gem::SourceIndex.from_installed_gems - - locals.outdated.sort.each do |name| - local = locals.find_name(name).last + Gem::Specification.outdated.sort.each do |name| + local = Gem::Specification.find_all_by_name(name).max dep = Gem::Dependency.new local.name, ">= #{local.version}" remotes = Gem::SpecFetcher.fetcher.fetch dep @@ -35,6 +33,4 @@ class Gem::Commands::OutdatedCommand < Gem::Command say "#{local.name} (#{local.version} < #{remote.version})" end end - end - diff --git a/lib/rubygems/commands/pristine_command.rb b/lib/rubygems/commands/pristine_command.rb index 9a0b2e9f11..99722756ee 100644 --- a/lib/rubygems/commands/pristine_command.rb +++ b/lib/rubygems/commands/pristine_command.rb @@ -16,7 +16,8 @@ class Gem::Commands::PristineCommand < Gem::Command def initialize super 'pristine', 'Restores installed gems to pristine condition from files located in the gem cache', - :version => Gem::Requirement.default + :version => Gem::Requirement.default, :extensions => true, + :all => false add_option('--all', 'Restore all installed gems to pristine', @@ -24,6 +25,11 @@ class Gem::Commands::PristineCommand < Gem::Command options[:all] = value end + add_option('--[no-]extensions', + 'Restore gems with extensions') do |value, options| + options[:extensions] = value + end + add_version_option('restore to', 'pristine condition') end @@ -32,7 +38,7 @@ class Gem::Commands::PristineCommand < Gem::Command end def defaults_str # :nodoc: - "--all" + "--all --extensions" end def description # :nodoc: @@ -46,6 +52,9 @@ for the gem are regenerated. If the cached gem cannot be found, you will need to use `gem install` to revert the gem. + +If --no-extensions is provided pristine will not attempt to restore gems with +extensions. EOF end @@ -54,21 +63,17 @@ revert the gem. end def execute - gem_name = nil - specs = if options[:all] then - Gem::SourceIndex.from_installed_gems.map do |name, spec| - spec - end + Gem::Specification.map else - gem_name = get_one_gem_name - Gem::SourceIndex.from_installed_gems.find_name(gem_name, - options[:version]) + get_all_gem_names.map do |gem_name| + Gem::Specification.find_all_by_name gem_name, options[:version] + end.flatten end - if specs.empty? then + if specs.to_a.empty? then raise Gem::Exception, - "Failed to find gem #{gem_name} #{options[:version]}" + "Failed to find gems #{options[:args]} #{options[:version]}" end install_dir = Gem.dir # TODO use installer option @@ -76,25 +81,32 @@ revert the gem. raise Gem::FilePermissionError.new(install_dir) unless File.writable?(install_dir) - say "Restoring gem(s) to pristine condition..." + say "Restoring gems to pristine condition..." specs.each do |spec| - gem = spec.cache_gem + unless spec.extensions.empty? or options[:extensions] then + say "Skipped #{spec.full_name}, it needs to compile an extension" + next + end + + gem = spec.cache_file + + unless File.exist? gem then + require 'rubygems/remote_fetcher' - if gem.nil? then say "Cached gem for #{spec.full_name} not found, attempting to fetch..." dep = Gem::Dependency.new spec.name, spec.version Gem::RemoteFetcher.fetcher.download_to_cache dep - gem = spec.cache_gem end # TODO use installer options - installer = Gem::Installer.new gem, :wrappers => true, :force => true + installer = Gem::Installer.new(gem, + :wrappers => true, + :force => true, + :install_dir => spec.base_dir) installer.install say "Restored #{spec.full_name}" end end - end - diff --git a/lib/rubygems/commands/query_command.rb b/lib/rubygems/commands/query_command.rb index 29e53065e7..d82f8aea60 100644 --- a/lib/rubygems/commands/query_command.rb +++ b/lib/rubygems/commands/query_command.rb @@ -80,10 +80,12 @@ class Gem::Commands::QueryCommand < Gem::Command exit_code |= 1 end - raise Gem::SystemExitException, exit_code + terminate_interaction exit_code end - dep = Gem::Dependency.new name, Gem::Requirement.default + req = Gem::Requirement.default + # TODO: deprecate for real + dep = Deprecate.skip_during { Gem::Dependency.new name, req } if local? then if prerelease and not both? then @@ -96,7 +98,9 @@ class Gem::Commands::QueryCommand < Gem::Command say end - specs = Gem.source_index.search dep + specs = Gem::Specification.find_all { |s| + s.name =~ name and req =~ s.version + } spec_tuples = specs.map do |spec| [[spec.name, spec.version, spec.original_platform, spec], :local] @@ -129,9 +133,8 @@ class Gem::Commands::QueryCommand < Gem::Command ## # Check if gem +name+ version +version+ is installed. - def installed?(name, version = Gem::Requirement.default) - dep = Gem::Dependency.new name, version - !Gem.source_index.search(dep).empty? + def installed?(name, req = Gem::Requirement.default) + Gem::Specification.any? { |s| s.name =~ name and req =~ s.version } end def output_query_results(spec_tuples) diff --git a/lib/rubygems/commands/server_command.rb b/lib/rubygems/commands/server_command.rb index c59f216262..0d18a82201 100644 --- a/lib/rubygems/commands/server_command.rb +++ b/lib/rubygems/commands/server_command.rb @@ -50,7 +50,7 @@ class Gem::Commands::ServerCommand < Gem::Command options[:addresses].push(*address) end - add_option '-l', '--launch[=COMMAND]', + add_option '-l', '--launch[=COMMAND]', 'launches a browser window', "COMMAND defaults to 'start' on Windows", "and 'open' on all other platforms" do |launch, options| diff --git a/lib/rubygems/commands/setup_command.rb b/lib/rubygems/commands/setup_command.rb index cf844c6674..6aa80054a0 100644 --- a/lib/rubygems/commands/setup_command.rb +++ b/lib/rubygems/commands/setup_command.rb @@ -338,7 +338,7 @@ abort "#{deprecation_message}" args << '--main' << 'README.rdoc' << '--quiet' args << '.' args << 'README.rdoc' << 'UPGRADING.rdoc' - args << 'LICENSE.txt' << 'GPL.txt' << 'History.txt' + args << 'LICENSE.txt' << 'MIT.txt' << 'History.txt' r = RDoc::RDoc.new r.document args diff --git a/lib/rubygems/commands/specification_command.rb b/lib/rubygems/commands/specification_command.rb index 987e401042..e4036aea78 100644 --- a/lib/rubygems/commands/specification_command.rb +++ b/lib/rubygems/commands/specification_command.rb @@ -72,18 +72,8 @@ FIELD name of gemspec field to show field = get_one_optional_argument - if field then - field = field.intern - - if options[:format] == :ruby then - raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive" - end - - unless Gem::Specification.attribute_names.include? field then - raise Gem::CommandLineError, - "no field %p on Gem::Specification" % field.to_s - end - end + raise Gem::CommandLineError, "--ruby and FIELD are mutually exclusive" if + field and options[:format] == :ruby if local? then if File.exist? gem then @@ -91,7 +81,7 @@ FIELD name of gemspec field to show end if specs.empty? then - specs.push(*Gem.source_index.search(dep)) + specs.push(*dep.matching_specs) end end @@ -106,7 +96,11 @@ FIELD name of gemspec field to show terminate_interaction 1 end - output = lambda do |s| + unless options[:all] then + specs = [specs.sort_by { |s| s.version }.last] + end + + specs.each do |s| s = s.send field if field say case options[:format] @@ -117,14 +111,5 @@ FIELD name of gemspec field to show say "\n" end - - if options[:all] then - specs.each(&output) - else - spec = specs.sort_by { |s| s.version }.last - output[spec] - end end - end - diff --git a/lib/rubygems/commands/stale_command.rb b/lib/rubygems/commands/stale_command.rb index 9a024faa6d..712e62aa22 100644 --- a/lib/rubygems/commands/stale_command.rb +++ b/lib/rubygems/commands/stale_command.rb @@ -17,7 +17,8 @@ class Gem::Commands::StaleCommand < Gem::Command def execute gem_to_atime = {} - Gem.source_index.each do |name, spec| + Gem::Specification.each do |spec| + name = spec.full_name Dir["#{spec.full_gem_path}/**/*.*"].each do |file| next if File.directory?(file) stat = File.stat(file) diff --git a/lib/rubygems/commands/unpack_command.rb b/lib/rubygems/commands/unpack_command.rb index ef0d65e073..b0fa2bfb05 100644 --- a/lib/rubygems/commands/unpack_command.rb +++ b/lib/rubygems/commands/unpack_command.rb @@ -25,6 +25,10 @@ class Gem::Commands::UnpackCommand < Gem::Command options[:target] = value end + add_option('--spec', 'unpack the gem specification') do |value, options| + options[:spec] = true + end + add_version_option end @@ -50,14 +54,30 @@ class Gem::Commands::UnpackCommand < Gem::Command dependency = Gem::Dependency.new name, options[:version] path = get_path dependency - if path then + unless path then + alert_error "Gem '#{name}' not installed nor fetchable." + next + end + + if @options[:spec] then + spec, metadata = get_metadata path + + if metadata.nil? then + alert_error "--spec is unsupported on '#{name}' (old format gem)" + next + end + + spec_file = File.basename spec.spec_file + + open spec_file, 'w' do |io| + io.write metadata + end + else basename = File.basename path, '.gem' target_dir = File.expand_path basename, options[:target] FileUtils.mkdir_p target_dir Gem::Installer.new(path, :unpack => true).unpack target_dir say "Unpacked gem: '#{target_dir}'" - else - alert_error "Gem '#{name}' not installed." end end end @@ -70,9 +90,8 @@ class Gem::Commands::UnpackCommand < Gem::Command # TODO: see comments in get_path() about general service. def find_in_cache(filename) - Gem.path.each do |path| - this_path = Gem.cache_gem(filename, path) + this_path = File.join(path, "cache", filename) return this_path if File.exist? this_path end @@ -99,9 +118,9 @@ class Gem::Commands::UnpackCommand < Gem::Command def get_path dependency return dependency.name if dependency.name =~ /\.gem$/i - specs = Gem.source_index.search dependency + specs = dependency.matching_specs - selected = specs.sort_by { |s| s.version }.last + selected = specs.sort_by { |s| s.version }.last # HACK: hunt last down return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless selected @@ -111,12 +130,37 @@ class Gem::Commands::UnpackCommand < Gem::Command # We expect to find (basename).gem in the 'cache' directory. Furthermore, # the name match must be exact (ignoring case). - path = find_in_cache selected.file_name + path = find_in_cache File.basename selected.cache_file return Gem::RemoteFetcher.fetcher.download_to_cache(dependency) unless path path end + ## + # Extracts the Gem::Specification and raw metadata from the .gem file at + # +path+. + + def get_metadata path + format = Gem::Format.from_file_by_path path + spec = format.spec + + metadata = nil + + open path, Gem.binary_mode do |io| + tar = Gem::Package::TarReader.new io + tar.each_entry do |entry| + case entry.full_name + when 'metadata' then + metadata = entry.read + when 'metadata.gz' then + metadata = Gem.gunzip entry.read + end + end + end + + return spec, metadata + end + end diff --git a/lib/rubygems/commands/update_command.rb b/lib/rubygems/commands/update_command.rb index b7c65eb2a4..2d7da445cb 100644 --- a/lib/rubygems/commands/update_command.rb +++ b/lib/rubygems/commands/update_command.rb @@ -71,14 +71,14 @@ class Gem::Commands::UpdateCommand < Gem::Command hig = {} # highest installed gems - Gem.source_index.each do |name, spec| + Gem::Specification.each do |spec| if hig[spec.name].nil? or hig[spec.name].version < spec.version then hig[spec.name] = spec end end end - gems_to_update = which_to_update hig, options[:args] + gems_to_update = which_to_update hig, options[:args].uniq updated = update_gems gems_to_update @@ -123,8 +123,8 @@ class Gem::Commands::UpdateCommand < Gem::Command end def update_gems gems_to_update - gems_to_update.uniq.sort.each do |name| - update_gem name + gems_to_update.uniq.sort.each do |(name, version)| + update_gem name, version end @updated @@ -141,6 +141,9 @@ class Gem::Commands::UpdateCommand < Gem::Command options[:user_install] = false + # TODO: rename version and other variable name conflicts + # TODO: get rid of all this indirection on name and other BS + version = options[:system] if version == true then version = Gem::Version.new Gem::VERSION @@ -158,18 +161,25 @@ class Gem::Commands::UpdateCommand < Gem::Command 'rubygems-update' => rubygems_update } - gems_to_update = which_to_update hig, options[:args] + gems_to_update = which_to_update hig, options[:args], :system + name, up_ver = gems_to_update.first + current_ver = Gem::Version.new Gem::VERSION + + target = if options[:system] == true then + up_ver + else + version + end - if gems_to_update.empty? then + if current_ver == target then + # if options[:system] != true and version == current_ver then say "Latest version currently installed. Aborting." terminate_interaction end - update_gem gems_to_update.first, requirement + update_gem name, target - Gem.source_index.refresh! - - installed_gems = Gem.source_index.find_name 'rubygems-update', requirement + installed_gems = Gem::Specification.find_all_by_name 'rubygems-update', requirement version = installed_gems.last.version args = [] @@ -193,7 +203,7 @@ class Gem::Commands::UpdateCommand < Gem::Command end end - def which_to_update(highest_installed_gems, gem_names) + def which_to_update highest_installed_gems, gem_names, system = false result = [] highest_installed_gems.each do |l_name, l_spec| @@ -213,9 +223,11 @@ class Gem::Commands::UpdateCommand < Gem::Command version end.last - if highest_remote_gem and - l_spec.version < highest_remote_gem.first[1] then - result << l_name + highest_remote_gem ||= [[nil, Gem::Version.new(0), nil]] # "null" object + highest_remote_ver = highest_remote_gem.first[1] + + if system or (l_spec.version < highest_remote_ver) then + result << [l_spec.name, [l_spec.version, highest_remote_ver].max] end end diff --git a/lib/rubygems/commands/which_command.rb b/lib/rubygems/commands/which_command.rb index aeb91f203c..2962491bde 100644 --- a/lib/rubygems/commands/which_command.rb +++ b/lib/rubygems/commands/which_command.rb @@ -5,12 +5,8 @@ ###################################################################### require 'rubygems/command' -require 'rubygems/gem_path_searcher' class Gem::Commands::WhichCommand < Gem::Command - - EXT = %w[.rb .rbw .so .dll .bundle] # HACK - def initialize super 'which', 'Find the location of a library file you can require', :search_gems_first => false, :show_all => false @@ -34,14 +30,13 @@ class Gem::Commands::WhichCommand < Gem::Command end def execute - searcher = Gem::GemPathSearcher.new - found = false options[:args].each do |arg| - arg = arg.sub(/#{Regexp.union(*EXT)}$/, '') + arg = arg.sub(/#{Regexp.union(*Gem.suffixes)}$/, '') dirs = $LOAD_PATH - spec = searcher.find arg + + spec = Gem::Specification.find_by_path arg if spec then if options[:search_gems_first] then @@ -51,6 +46,7 @@ class Gem::Commands::WhichCommand < Gem::Command end end + # TODO: this is totally redundant and stupid paths = find_paths arg, dirs if paths.empty? then @@ -68,7 +64,7 @@ class Gem::Commands::WhichCommand < Gem::Command result = [] dirs.each do |dir| - EXT.each do |ext| + Gem.suffixes.each do |ext| full_path = File.join dir, "#{package_name}#{ext}" if File.exist? full_path then result << full_path |