[Rubygems-developers] rubygems claiming installation for existing latest gems.

Hugh Sasse hgs at dmu.ac.uk
Fri Nov 11 12:20:42 EST 2005


I have just updated rails and associated gems.  Some gems I tried to 
update didn't need updating, they were the latest versions.
However, gem update reported them as being successfully installed.
In some sense it was not a failure, so that's OK but it is odd.

I see from the code that the installation routines supply a list of
what was installed.  However, they have no means of providing
feedback about what wasn't installed, and why it wasn't installed.
The attached patch is an attempt to address this, as yet incomplete.
I think that returning something more structured than an array would
facilitate better communication between the objects involved.  So
I've started out with a class descended from Hash, and an extra
option with a long name to enable this.  Before I make any attempt
to follow this through, is there a reason why this is a bad idea
and, does anyone have a better way to do this?

        Hugh

-------------- next part --------------
--- ./lib/rubygems/remote_installer.rb	2005-11-11 15:18:38.182763000 +0000
+++ ./lib/rubygems/remote_installer.rb.new	2005-11-11 17:07:47.037109000 +0000
@@ -8,6 +8,7 @@
   class GemNotFoundException < Gem::Exception; end
   class RemoteInstallationCancelled < Gem::Exception; end
 
+
   # ==================================================================
   # RemoteSourceFetcher handles the details of fetching gems and gem
   # information from a remote source.  
@@ -368,6 +369,7 @@
   class RemoteInstaller
     include UserInteraction
 
+
     # <tt>http_proxy</tt>::
     # * [String]: explicit specification of proxy; overrides any
     #   environment variable setting
@@ -375,6 +377,12 @@
     # * <tt>:no_proxy</tt>: ignore environment variables and _don't_
     #   use a proxy
     #
+    # Other supported options:
+    #   <tt>ignore_dependencies</tt>
+    #   <tt>include_dependencies</tt>
+    # New options:
+    #   <tt>return_installation_information</tt>
+    #
     def initialize(options={})
       # Ensure http_proxy env vars are used if no proxy explicitly supplied.
       @options = options
@@ -409,17 +417,27 @@
       unless version_requirement.respond_to?(:satisfied_by?)
         version_requirement = Version::Requirement.new(version_requirement)
       end
-      installed_gems = []
       caches = source_index_hash
       spec, source = find_gem_to_install(gem_name, version_requirement, caches)
       dependencies = find_dependencies_not_installed(spec.dependencies)
-      installed_gems << install_dependencies(dependencies, force, install_dir)
+      if @options.has_key?(:return_installation_information)
+        installed_gems = InstallationInformation.new
+        installed_gems.merge(install_dependencies(dependencies, force, install_dir))
+      else
+        installed_gems = []
+        installed_gems << install_dependencies(dependencies, force, install_dir)
+      end
       cache_dir = File.join(install_dir, "cache")
       destination_file = File.join(cache_dir, spec.full_name + ".gem")
       download_gem(destination_file, source, spec)
       installer = new_installer(destination_file)
-      installed_gems.unshift installer.install(force, install_dir, install_stub)
-      installed_gems.flatten
+      if @options.has_key?(:return_installation_information)
+        installed_gems.merge installer.install(force, install_dir, install_stub)
+        installed_gems
+      else
+        installed_gems.unshift installer.install(force, install_dir, install_stub)
+        installed_gems.flatten
+      end
     end
 
     # Search Gem repository for a gem by specifying all or part of
--- ./lib/rubygems/installer.rb	2005-11-11 15:18:38.161653000 +0000
+++ ./lib/rubygems/installer.rb.new	2005-11-11 17:07:51.229336000 +0000
@@ -22,6 +22,9 @@
     #
     # gem:: [String] The file name of the gem
     #
+    # options can include:
+    #   <tt>return_installation_information</tt>
+    #
     def initialize(gem, options={})
       @gem = gem
       @options = options
@@ -90,7 +93,13 @@
       end
 
       format.spec.loaded_from = File.join(install_dir, 'specifications', format.spec.full_name+".gemspec")
-      return format.spec
+      if @options.has_key?(:return_installation_information) 
+        info = InstallationInformation.new()
+        info[installed] = format_spec 
+        return info
+      else
+        return format.spec ;
+      end
     end
 
     ##
--- ./lib/rubygems.rb	2005-11-11 15:18:38.089946000 +0000
+++ ./lib/rubygems.rb.new	2005-11-11 16:54:37.551370000 +0000
@@ -4,6 +4,23 @@
   class LoadError < ::LoadError
     attr_accessor :name, :version_requirement
   end
+
+  
+  # At present the installer returns a list of gems successfully
+  # installed.  There is no facility for saying why a gem was or
+  # was not installed.  This means that rubygems can only say it
+  # has successfully installed a gem when we ask for the latest
+  # version and it is the same as we have, because there is no
+  # mechanism to feed that kind of information back to the user.
+  class InstallationInformation < Hash
+    def initialize()
+      super
+      self[:installed] = nil
+      self[:failed] = nil
+      self[:have_latest] = nil
+    end
+  end
+
 end
 
 module Kernel


More information about the Rubygems-developers mailing list