initial version for repo.or.cz
authorNaitik Shah <[email protected]>
Tue, 12 Feb 2008 07:09:09 +0000 (11 23:09 -0800)
committerNaitik Shah <[email protected]>
Tue, 12 Feb 2008 07:09:09 +0000 (11 23:09 -0800)
README.html [new file with mode: 0644]
script_gem [new file with mode: 0755]

diff --git a/README.html b/README.html
new file mode 100644 (file)
index 0000000..a8f1e6a
--- /dev/null
@@ -0,0 +1,103 @@
+<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 &lt;naitik.shah [_a_t_] yahoo [_d_o_t] com&gt;
+</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>
diff --git a/script_gem b/script_gem
new file mode 100755 (executable)
index 0000000..6d161f4
--- /dev/null
@@ -0,0 +1,104 @@
+#!/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'