[Rubygems-developers] [PATCH] config.rb

Grant Hollingworth grant at antiflux.org
Wed Mar 1 21:02:04 EST 2006


This patch introduces rubygems/config.rb, which contains an
rbconfig-style hash of the paths in setup.rb's .config.  The rest of
RubyGems then uses Gem::CONFIG rather than Config::CONFIG.  On Debian
systems, for instance, Ruby is /usr/bin/ruby, but sitedir is
/usr/local/lib/site_ruby.  The existing RubyGems doesn't deal well with
cases like that.

There is a new option for setup.rb: --gem-home.  $GEM_HOME still
overrides it.

I removed the OS X framework special cases.  Since the .pkg just copies
its files into place, config.rb will have to be generated before the
package is made.  It seemed a simpler solution than complicated require
logic or a dummy config.rb.  If a gembindir different than bindir is
needed, I can add that easily.

I've attached a CVS diff plus two new files.

metaconfig adds --gem-home and sets setup.rb's path defaults from
config.rb, if available.  gem update --system should work for installs
with --prefix or whatever.

pre-setup.rb generates config.rb.

The tests don't run without config.rb, but they don't work without an
installed copy of RubyGems, anyway.  (I tried running tests with only
the source directory, using RUBYLIB=lib rake test, but I have flexmock
and rake installed as gems.  Damn you, chicken.  Damn you, egg.)

I made a small patch to setup.rb so that metaconfig's set_config_default
actually does something.

One last thing: while testing, I noticed weird output from
post-install.rb, and eventually figured out that I had RUBYOPT=rubygems
set.  Despite the $:.unshift("lib"), the old RubyGems install was being
used.
-------------- next part --------------
? metaconfig
? lib/rubygems/pre-setup.rb
Index: Rakefile
===================================================================
RCS file: /var/cvs/rubygems/rubygems/Rakefile,v
retrieving revision 1.58
diff -u -r1.58 Rakefile
--- Rakefile	24 Feb 2006 00:54:18 -0000	1.58
+++ Rakefile	2 Mar 2006 01:18:40 -0000
@@ -38,6 +38,7 @@
   'html',
   'pkgs/sources/sources*.gem',
   '.config',
+  'lib/rubygems/config.rb',
   '**/debug.log',
   'logs'
   )
Index: post-install.rb
===================================================================
RCS file: /var/cvs/rubygems/rubygems/post-install.rb,v
retrieving revision 1.6
diff -u -r1.6 post-install.rb
--- post-install.rb	9 Jul 2005 23:18:32 -0000	1.6
+++ post-install.rb	2 Mar 2006 01:18:40 -0000
@@ -37,8 +37,8 @@
 end
 
 def install_windows_batch_files
-  bindir = Config::CONFIG['bindir']
-  ruby_install_name = Config::CONFIG['ruby_install_name']
+  bindir = Gem::CONFIG['bindir']
+  ruby_install_name = Gem::CONFIG['ruby_install_name']
   is_windows_platform = Config::CONFIG["arch"] =~ /dos|win32/i
   require 'find'
   Find.find('bin') do |f|
Index: setup.rb
===================================================================
RCS file: /var/cvs/rubygems/rubygems/setup.rb,v
retrieving revision 1.2
diff -u -r1.2 setup.rb
--- setup.rb	10 Jul 2005 04:07:20 -0000	1.2
+++ setup.rb	2 Mar 2006 01:18:41 -0000
@@ -69,7 +69,11 @@
   attr_reader :name
   attr_reader :description
 
-  attr_accessor :default
+  attr_reader :default
+  def default=(default)
+    @value = default if @value == @default
+    @default = default
+  end
   alias help_default default
 
   def help_opt
Index: lib/rubygems.rb
===================================================================
RCS file: /var/cvs/rubygems/rubygems/lib/rubygems.rb,v
retrieving revision 1.88
diff -u -r1.88 rubygems.rb
--- lib/rubygems.rb	3 Dec 2005 18:59:35 -0000	1.88
+++ lib/rubygems.rb	2 Mar 2006 01:18:41 -0000
@@ -1,4 +1,5 @@
 require 'rbconfig'
+require 'rubygems/config'
 
 module Gem
   class LoadError < ::LoadError
@@ -95,6 +96,19 @@
       set_home(ENV['GEM_HOME'] || default_dir) unless @gem_home
       @gem_home
     end
+
+    ##
+    # The directory path where Gem binaries are to be installed.
+    #
+    # return:: [String] The directory path
+    #
+    def bindir(install_dir=Gem.dir)
+      if(install_dir == Gem.default_dir)
+        Gem::CONFIG['bindir']
+      else
+        File.join(install_dir, "bin")
+      end
+    end
     
     ##
     # List of directory paths to search for Gems.
@@ -364,27 +378,7 @@
     # Default home directory path to be used if an alternate value is
     # not specified in the environment.
     def default_dir
-      ## rbconfig = Dir.glob("{#{($LOAD_PATH).join(',')}}/rbconfig.rb").first
-      ## if rbconfig
-      ##   module_eval File.read(rbconfig) unless const_defined?("Config")
-      ## else
-      ##   require 'rbconfig'
-      ## end
-      #
-      # Note on above code: we have an issue if a Config class is
-      # already defined and we load 'rbconfig'.  The above code is
-      # supposed to work around that but it's been commented out.  In
-      # any case, I moved "require 'rbconfig'" to the top of this
-      # file, because there was a circular dependency between this
-      # method and our custom require.  In any case, rbconfig is a
-      # fundamental RubyGems dependency, so it might as well be up the
-      # top.  -- Gavin Sinclair, 2004-12-12
-      #
-      if defined? RUBY_FRAMEWORK_VERSION
-        return File.join(File.dirname(Config::CONFIG["sitedir"]), "Gems")
-      else
-        File.join(Config::CONFIG['libdir'], 'ruby', 'gems', Config::CONFIG['ruby_version'])
-      end
+      CONFIG['gem-home']
     end
 
     private 
Index: lib/rubygems/deployment.rb
===================================================================
RCS file: /var/cvs/rubygems/rubygems/lib/rubygems/deployment.rb,v
retrieving revision 1.2
diff -u -r1.2 deployment.rb
--- lib/rubygems/deployment.rb	16 Mar 2005 03:09:29 -0000	1.2
+++ lib/rubygems/deployment.rb	2 Mar 2006 01:18:41 -0000
@@ -105,8 +105,8 @@
       
       def new_deployment(target_dir = nil)
         unless target_dir
-          require 'rbconfig'
-          target_dir = Config::CONFIG['sitelibdir']
+          require 'rubygems/config'
+          target_dir = CONFIG['siterubyver']
         end
         target_dir = File.expand_path(target_dir)
         deployment = self[target_dir]
Index: lib/rubygems/installer.rb
===================================================================
RCS file: /var/cvs/rubygems/rubygems/lib/rubygems/installer.rb,v
retrieving revision 1.106
diff -u -r1.106 installer.rb
--- lib/rubygems/installer.rb	26 Feb 2006 01:42:39 -0000	1.106
+++ lib/rubygems/installer.rb	2 Mar 2006 01:18:41 -0000
@@ -2,6 +2,7 @@
 
 require 'pathname'
 require 'rbconfig'
+require 'rubygems/config'
 require 'rubygems/format'
 require 'rubygems/dependency_list'
 
@@ -166,30 +167,10 @@
       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?
       
-      # If the user has asked for the gem to be installed in
-      # a directory that is the system gem directory, then
-      # use the system bin directory, else create (or use) a
-      # new bin dir under the install_dir.
-      bindir = bindir(install_dir)
+      bindir = Gem.bindir
 
       Dir.mkdir bindir unless File.exist? bindir
       raise Gem::FilePermissionError.new(bindir) unless File.writable?(bindir)
@@ -243,7 +224,7 @@
       path = File.join(install_dir, "gems", spec.full_name, spec.bindir, bin_file_name)
       File.open(path, "rb") do |file|
         first_line = file.readlines("\n").first 
-        path_to_ruby = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
+        path_to_ruby = Gem::CONFIG['rubypath']
         if first_line =~ /^#!/
           # Preserve extra words on shebang line, like "-w".  Thanks RPA.
           shebang = first_line.sub(/\A\#!\s*\S*ruby\S*/, "#!" + path_to_ruby)
@@ -408,9 +389,9 @@
     #
     def remove_executables(gemspec)
       return if gemspec.nil?
+      bindir = Gem.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
 	}
@@ -429,7 +410,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
-------------- next part --------------
require 'rbconfig'
add_path_config('gem-home', 
                File.join('$libdir', 'ruby', 'gems', 
                          Config::CONFIG['ruby_version']), 
                'the directory for Gems')
                
# load paths from previous install
begin
  require 'rubygems/config'
  Gem::CONFIG_UNEXPANDED.each {|key, val| set_config_default(key, val) }
rescue LoadError
  # older RubyGems or not installed
end
-------------- next part --------------
# copy .config file created by setup.rb to an rbconfig-style rubygems/config.rb
File.open('config.rb', 'w') do |f|
  f.print <<-END.gsub(/^    /, '')
    # This file is generated by the RubyGems setup.rb
    
    module Gem
      CONFIG = {}
  END
  File.foreach("#{srcdir_root}/.config") do |l|
    key, value = l.chomp.split(/=/)
    f.print %{  CONFIG["#{key}"] = "#{value}"\n}
  end
  f.print %q{
      def self.expand(val)
        val.gsub!(/\$\$|\$(\w+)|\$\(([^()]+)\)|\$\\\{([^{}]+)\\\}/) do |var|
          if !(v = $1 || $2 || $3)
            '$'
          elsif key = CONFIG[v]
            CONFIG[v] = false
            expand(key)
            CONFIG[v] = key
          else
            var
          end
        end
        val
      end
      CONFIG_UNEXPANDED = {}
      CONFIG.each {|k, v| CONFIG_UNEXPANDED[k] = v.dup }
      CONFIG.each_value {|v| expand(v) }
    end
  }.gsub(/^    /, '')
end 


More information about the Rubygems-developers mailing list