[Rubygems-developers] /usr/bin/ruby, but gems in /usr/local

Grant Hollingworth grant at antiflux.org
Sun Feb 19 14:32:15 EST 2006


I have RubyGems installed in /usr/local.  Ruby is /usr/bin/ruby,
from a Debian package.  I have write permission to /usr/local, so I
don't need to use sudo with gem commands.  Less typing, and I know that
nothing is getting installed outside of /usr/local.

RubyGems assumes I want all its directories to match Ruby's (via
rbconfig) but no, I really don't.  Now I have a big list of problems
that stem from that assumption.

1. --siteruby
  okcomputer$ ruby setup.rb install --prefix /usr/local \  --siteruby
/usr/local/lib/site_ruby
I needed to add the --siteruby because setup.rb assumes
$prefix/local/lib/site_ruby.  This is fixed in newer versions of 
setup.rb.

2. GEM_HOME
It's not the worst for just me, but I don't want every user to have to
set GEM_HOME.  Sure, I could put it in /etc/profile, but I'll still have
problems with limited environments (like SwitchTower using ssh).

How about setting a default gemhome at install time?  A
post-configure.rb in lib/rubygems could create an rbconfig-style
config.rb with the libdir, bindir, etc. as given to setup.rb.
Gem.default_dir and the other methods that use rbconfig could then use
the new Gem::CONFIG instead.

Maybe there should be a --gem-dir (--gem-home?) option added to
setup.rb.  The default would be like Gem.default_dir.  default_dir could
be removed, actually.  Its logic would have been shifted to configure
time.

If that sounds okay I'll write a patch.

3. uninstall with executables is broken
  okcomputer$ RUBYLIB= gem uninstall redcloth
  Attempting to uninstall gem 'redcloth'
  Successfully uninstalled RedCloth version 3.0.4
  ERROR:  While executing gem ... (Gem::FilePermissionError)
      You don't have write permissions into the /usr/bin directory.

remove_executables needs to use the bindir method instead of
Config.CONFIG['bindir].  I've attached a patch for that.  It's not the
cleanest change: bindir is in Gem::Installer and remove_executables is
in Gem::Uninstaller.  I moved bindir to a new module InstallerHelper and
mixed it in to both Installer and Uninstaller.  I don't know about
that... bindir probably doesn't need to be an instance method.
-------------- next part --------------
Index: installer.rb
===================================================================
RCS file: /var/cvs/rubygems/rubygems/lib/rubygems/installer.rb,v
retrieving revision 1.105
diff -u -r1.105 installer.rb
--- installer.rb	9 Feb 2006 03:47:08 -0000	1.105
+++ installer.rb	19 Feb 2006 19:18:49 -0000
@@ -9,6 +9,24 @@
 
   class DependencyRemovalException < Gem::Exception; end
 
+  module InstallerHelper
+    ##
+    # Determines the directory for binaries
+    #
+    def bindir(install_dir=Gem.dir)
+      if(install_dir == Gem.default_dir)
+        # mac framework support
+        if defined? RUBY_FRAMEWORK_VERSION
+          File.join(File.dirname(Config::CONFIG["sitedir"]), File.basename(Config::CONFIG["bindir"]))
+        else # generic install
+          Config::CONFIG['bindir']
+        end
+      else
+        File.join(install_dir, "bin")
+      end
+    end
+  end
+
   ##
   # The installer class processes RubyGem .gem files and installs the
   # files contained in the .gem into the Gem.path.
@@ -16,6 +34,7 @@
   class Installer
 
     include UserInteraction
+    include InstallerHelper
   
     ##
     # Constructs an Installer instance
@@ -166,22 +185,6 @@
       end
     end
 
-    ##
-    # Determines the directory for binaries
-    #
-    def bindir(install_dir=Gem.dir)
-      if(install_dir == Gem.default_dir)
-        # mac framework support
-        if defined? RUBY_FRAMEWORK_VERSION
-          File.join(File.dirname(Config::CONFIG["sitedir"]), File.basename(Config::CONFIG["bindir"]))
-        else # generic install
-          Config::CONFIG['bindir']
-        end
-      else
-        File.join(install_dir, "bin")
-      end
-    end
-
     def generate_bin(spec, install_dir=Gem.dir)
       return unless spec.executables && ! spec.executables.empty?
       
@@ -347,6 +350,7 @@
   class Uninstaller
   
     include UserInteraction
+    include InstallerHelper
   
     ##
     # Constructs an Uninstaller instance
@@ -409,9 +413,10 @@
     #
     def remove_executables(gemspec)
       return if gemspec.nil?
+      bindir = bindir()
       if(gemspec.executables.size > 0)
-        raise Gem::FilePermissionError.new(Config::CONFIG['bindir']) unless
-	  File.writable?(Config::CONFIG['bindir'])
+        raise Gem::FilePermissionError.new(bindir) unless
+	  File.writable?(bindir)
         list = Gem.source_index.search(gemspec.name).delete_if { |spec|
 	  spec.version == gemspec.version
 	}
@@ -430,7 +435,6 @@
           say "Executables and scripts will remain installed."
           return
         else
-          bindir = Config::CONFIG['bindir']
           gemspec.executables.each do |exe_name|
             say "Removing #{exe_name}"
             File.unlink(File.join(bindir, exe_name)) rescue nil


More information about the Rubygems-developers mailing list