hi, I am one of the maintainer of the Ruby project in the openSUSE Build Service [1].
One of the goals was of course providing as many ruby libraries as possible. As gem is getting more and more popular for distributing ruby libraries, I was looking for a way to provide rpms of gems on the one hand, but keeping interoperability with gem. For building rpms i wanted to avoid building as root. That makes it impossible to use the normal prefixes for the gems. For normal C programs you have the "make install DESTDIR=%{buildroot}" to provide a temporary installation root. Python has a "python setup.py install --root %{buildroot}" for the same purpose. The attached adds a --build-root parameter to achieve the same. With a downloaded gem file you can do: gem install --build-root %{buildroot} /path/to/some.gem that makes it rather easy to build packages from gems. In the longterm i will now work on a gem2pkg script. At first only rpm, but in the longerm support for deb or other binary distros could be added. I already build 49 rpms from gem with that patch. :) Known bugs: "gem install --build-root $PWD/inst -r somegem" fails with [[[ ERROR: While executing gem ... (Errno::EACCES) Permission denied - /usr/lib/ruby/gems/1.8/cache/sparklines-0.2.7.gem ]]] Do you consider that bug important? As my build environments never have network, that use case would never matter for me. Furthermore this option is only interesting for packagers, and they always have a local copy of the file. Thanks for your comments. darix [1] http://en.opensuse.org/Ruby -- openSUSE - SUSE Linux is my linux openSUSE is good for you www.opensuse.org
Index: lib/rubygems/gem_commands.rb =================================================================== --- lib/rubygems/gem_commands.rb.orig +++ lib/rubygems/gem_commands.rb @@ -59,6 +59,10 @@ add_option('-i', '--install-dir DIR', '') do |value, options| options[:install_dir] = value end + add_option('-B', '--build-root DIR', 'Temporary installation root. Useful for building packages.') do |value, options| + options[:build_root] = File.expand_path(value) + end + add_option('-d', '--[no-]rdoc', 'Generate RDoc documentation for the gem on install') do |value, options| options[:generate_rdoc] = value end Index: lib/rubygems/installer.rb =================================================================== --- lib/rubygems/installer.rb.orig +++ lib/rubygems/installer.rb @@ -69,7 +69,15 @@ end end end - + + if @options[:build_root] + build_root = @options[:build_root] + FileUtils.mkdir_p build_root + raise Gem::FilePermissionError.new(build_root) unless File.writable?(build_root) + install_dir = build_root + install_dir + FileUtils.mkdir_p install_dir + end + raise Gem::FilePermissionError.new(install_dir) unless File.writable?(install_dir) # Build spec dir. @@ -167,16 +175,25 @@ # Determines the directory for binaries # def bindir(install_dir=Gem.dir) - if(install_dir == Gem.default_dir) + if @options[:build_root] + build_root = @options[:build_root] + gem_default_dir = File.join(build_root, Gem.default_dir) + else + gem_default_dir = Gem.default_dir + build_root = "" + end + + 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"])) + bin_dir = File.join(File.dirname(Config::CONFIG["sitedir"]), File.basename(Config::CONFIG["bindir"])) else # generic install - Config::CONFIG['bindir'] + bin_dir = Config::CONFIG['bindir'] end else - File.join(install_dir, "bin") + bin_dir = File.join(install_dir, "bin") end + bin_dir = File.join(build_root, bin_dir) end def generate_bin(spec, install_dir=Gem.dir)
Index: lib/rubygems/gem_commands.rb =================================================================== --- lib/rubygems/gem_commands.rb.orig +++ lib/rubygems/gem_commands.rb @@ -97,6 +97,12 @@ options[:install_dir] = File.expand_path(value) end + add_option('-B', '--build-root DIR', + 'Temporary installation root. Useful for building packages.') do + |value, options| + options[:build_root] = File.expand_path(value) + end + add_option('-d', '--[no-]rdoc', 'Generate RDoc documentation for the gem on install') do |value, options| Index: lib/rubygems/installer.rb =================================================================== --- lib/rubygems/installer.rb.orig +++ lib/rubygems/installer.rb @@ -74,7 +74,15 @@ end end end - + + if @options[:build_root] + build_root = @options[:build_root] + FileUtils.mkdir_p build_root + raise Gem::FilePermissionError.new(build_root) unless File.writable?(build_root) + install_dir = build_root + install_dir + FileUtils.mkdir_p install_dir + end + raise Gem::FilePermissionError.new(install_dir) unless File.writable?(install_dir) # Build spec dir. @@ -175,16 +183,25 @@ # Determines the directory for binaries # def bindir(install_dir=Gem.dir) - if(install_dir == Gem.default_dir) + if @options[:build_root] + build_root = @options[:build_root] + gem_default_dir = File.join(build_root, Gem.default_dir) + else + gem_default_dir = Gem.default_dir + build_root = "" + end + + 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"])) + bin_dir = File.join(File.dirname(Config::CONFIG["sitedir"]), File.basename(Config::CONFIG["bindir"])) else # generic install - Config::CONFIG['bindir'] + bin_dir = Config::CONFIG['bindir'] end else - File.join(install_dir, "bin") + bin_dir = File.join(install_dir, "bin") end + bin_dir = File.join(build_root, bin_dir) end def generate_bin(spec, install_dir=Gem.dir)
_______________________________________________ Rubygems-developers mailing list Rubygems-developers@rubyforge.org http://rubyforge.org/mailman/listinfo/rubygems-developers