--- /dev/null
+<style type="text/css">
+code {
+ border: 0.1em solid #666;
+ border-left: 0.2em solid #666;
+ padding: 0.75em 1em 0.75em 2em;
+ display: block;
+}
+#script_gem_manual {
+ margin: 0;
+ padding: 0 1em;
+}
+#script_gem_manual li {
+ list-style: square;
+}
+</style>
+
+<h2>Summary</h2>
+<p>
+ script_gem allows you to setup isolated gem environments for your rails
+ application.
+</p>
+
+<p>
+ It will introduce a top level 'gems' directory which it will be used by
+ your application. This is a normal rubygems installation. All your gem
+ commands will work as normal, and you will be responsible for managing this
+ repository [the script will install rails for you]. The only change in your
+ normal `flow of things` is that you will use './script/gem' when you want
+ to deal with the application's gem environment instead of using a global
+ 'gem' command.
+</p>
+
+
+<h2>ChangeLog</h2>
+0.0 - no release yet, look at the commits on the repository for more info.
+
+
+<h2>Contact</h2>
+<p>
+ If you have suggestions or patches - or want to drop me a comment:
+</p>
+<p style="margin-left: 2em;">
+ Naitik Shah <naitik.shah [_a_t_] yahoo [_d_o_t] com>
+</p>
+
+
+<h2>Installation</h2>
+<p>
+ <em>TODO</em>: make a gem.
+</p>
+
+<p>
+ <em>Manually for now</em>
+ <code>
+ <ul id="script_gem_manual">
+ <li>[...copy script_gem somewhere in your path]</li>
+ <li>[...cd into your app directory]</li>
+ <li>script_gem bootstrap</li>
+ </ul>
+ </code>
+</p>
+
+
+<h2>Shared Cache</h2>
+<p>
+ One issue that arises when having isolated gem environments is that you
+ would have to keep downloading the gems over and over again. To solve this
+ issue, script gem will share the gem cache directory. This potentially
+ involves reusing your existing gem cache directory if its writable by the
+ current user. The fallback is to create a new shared cache directory as
+ $HOME/.script_gem/cache. If you want to force a the fallback, explicitly
+ create that directory (mkdir -p ~/.script_gem/cache) before running the
+ bootstrap.
+</p>
+
+
+<h2>Usage</h2>
+<p>
+ Ok, what now?
+</p>
+<p>
+ Go to your application RAILS_ROOT and run:
+</p>
+<code>
+ ./script/gem
+</code>
+
+
+<h2>FAQ</h2>
+<p>
+ Will this affect my existing gem installation?
+</p>
+<p style="margin-left: 2em;">
+ NO! Well, except for one tiny thing - its cache might be reused. Check the
+ 'Shared Cache' section for more info.
+</p>
+
+<p>
+ Will I have to keep downloading all the gems over and over?
+</p>
+<p style="margin-left: 2em;">
+ NO! Check the 'Shared Cache' section for more info.
+</p>
--- /dev/null
+#!/usr/bin/env ruby
+
+require 'fileutils'
+
+bootstrap = ARGV[0] == 'bootstrap'
+if bootstrap
+ ARGV.pop
+ RAILS_ROOT = FileUtils.pwd
+else
+ require 'pathname'
+ RAILS_ROOT = Pathname.new("#{File.dirname(__FILE__)}/..").realpath.to_s unless defined?(RAILS_ROOT)
+end
+abort 'are you in a rails app?' unless File.exists?("#{RAILS_ROOT}/config/boot.rb")
+
+FileUtils.ln_s(__FILE__, "#{RAILS_ROOT}/script/gem") if bootstrap
+
+unless File.exists?("#{RAILS_ROOT}/gems/bin/gem")
+ puts 'Bootstrapping local gem environment...'
+
+ require 'net/http'
+
+ #TODO how do i figure out the latest version?
+ #TODO use random mirror?
+ #TODO does rubyforge have a library to do all this?
+ origdir=FileUtils.pwd
+ mirror='rubyforge.iasi.roedu.net'
+ version='1.0.1'
+ filename="rubygems-#{version}.tgz"
+ uri="/files/rubygems/#{filename}"
+ tmpdir="#{RAILS_ROOT}/tmp/tmp-local-gems"
+ downdir="#{ENV['HOME']}/.script_gem/down"
+
+ # fetch and install rubygems
+ FileUtils.mkdir_p downdir
+ FileUtils.rm_rf tmpdir
+ FileUtils.mkdir tmpdir
+ #TODO should check md5 of existing file
+ #TODO is the md5 available somewhere?
+ unless File.exists?("#{downdir}/#{filename}")
+ Net::HTTP.start(mirror) do |http|
+ resp = http.get(uri)
+ open("#{downdir}/#{filename}", 'wb') { |f| f.write(resp.body) }
+ end
+ end
+ FileUtils.cd tmpdir
+
+ `
+ tar xzf #{downdir}/#{filename} &&
+ cd rubygems-#{version} &&
+ ruby setup.rb --prefix="#{RAILS_ROOT}/gems" --no-rdoc --no-ri
+ `
+ abort 'Could not install local version of rubygems.' if $?.exitstatus != 0
+
+ # reuse existing gem cache directory or create a new shared one
+ gemcache_source="#{ENV['HOME']}/.script_gem/cache"
+ unless File.exists?(gemcache_source)
+ current_gemdir=`gem environment gemdir`.strip
+ if $?.exitstatus == 0 && !current_gemdir.empty? && File.writable?("#{current_gemdir}/cache")
+ gemcache_source="#{current_gemdir}/cache"
+ else
+ FileUtils.mkdir_p gemcache_source
+ end
+ end
+ FileUtils.ln_s gemcache_source, "#{RAILS_ROOT}/gems/cache"
+
+ puts "Installing latest rails gem in local environment..."
+ `
+ export GEM_HOME="#{RAILS_ROOT}/gems"
+ export GEM_PATH="#{RAILS_ROOT}/gems"
+ #{RAILS_ROOT}/gems/bin/gem install rails --no-rdoc --no-ri
+ `
+ abort 'Could not install local version of rails.' if $?.exitstatus != 0
+
+ FileUtils.rm_rf "#{RAILS_ROOT}/tmp/tmp-local-gems"
+ FileUtils.cd origdir
+end
+
+# check to see if the environment variables are being set by boot
+require RAILS_ROOT + '/config/boot'
+if ENV['GEM_HOME'] != "#{RAILS_ROOT}/gems" || ENV['GEM_PATH'] != "#{RAILS_ROOT}/gems"
+ # if the app does not have a preinitializer.rb, create one silently
+ if !File.exists?("#{RAILS_ROOT}/config/preinitializer.rb")
+ out = File.new("#{RAILS_ROOT}/config/preinitializer.rb", 'w')
+ out << <<-EOS
+ENV['GEM_HOME'] = "\#{RAILS_ROOT}/gems"
+ENV['GEM_PATH'] = "\#{RAILS_ROOT}/gems"
+ EOS
+ out.close
+ else
+ warn <<-EOS
+
+Your application environment setup is not yet complete!
+Add these lines to config/preinitializer.rb:
+
+ENV['GEM_HOME'] = "\#{RAILS_ROOT}/gems"
+ENV['GEM_PATH'] = "\#{RAILS_ROOT}/gems"
+ EOS
+ end
+end
+
+# pass on to gem
+ENV['GEM_HOME'] = "#{RAILS_ROOT}/gems"
+ENV['GEM_PATH'] = "#{RAILS_ROOT}/gems"
+load RAILS_ROOT + '/gems/bin/gem'