diff options
author | Carlhuda <carlhuda@engineyard.com> | 2010-01-25 15:39:54 -0800 |
---|---|---|
committer | Carlhuda <carlhuda@engineyard.com> | 2010-01-25 15:39:54 -0800 |
commit | 63b636b9dd25bc9b63a9ffb6f4071cabccdf6ae5 (patch) | |
tree | 4eaf174379a8ab8492af97b915bb5df8dce3f607 | |
parent | 50087020c54fe16be9d9b04146f247b2c1ab1e92 (diff) | |
download | bundler-63b636b9dd25bc9b63a9ffb6f4071cabccdf6ae5.tar.gz |
First pass at gemfile pack
-rw-r--r-- | lib/gemfile.rb | 5 | ||||
-rw-r--r-- | lib/gemfile/cli.rb | 11 | ||||
-rw-r--r-- | lib/gemfile/definition.rb | 11 | ||||
-rw-r--r-- | lib/gemfile/environment.rb | 17 | ||||
-rw-r--r-- | lib/gemfile/index.rb | 2 | ||||
-rw-r--r-- | lib/gemfile/installer.rb | 17 | ||||
-rw-r--r-- | lib/gemfile/source.rb | 40 | ||||
-rw-r--r-- | spec/install/gems_spec.rb | 15 | ||||
-rw-r--r-- | spec/pack/gems_spec.rb | 23 | ||||
-rw-r--r-- | spec/pack/git_spec.rb | 0 | ||||
-rw-r--r-- | spec/spec_helper.rb | 3 | ||||
-rw-r--r-- | spec/support/builders.rb | 3 |
12 files changed, 117 insertions, 30 deletions
diff --git a/lib/gemfile.rb b/lib/gemfile.rb index 9ece2d51a8..a3225bdb24 100644 --- a/lib/gemfile.rb +++ b/lib/gemfile.rb @@ -1,3 +1,4 @@ +require 'fileutils' require 'pathname' require 'yaml' require 'gemfile/rubygems' @@ -52,6 +53,10 @@ module Gemfile home.join("cache") end + def self.root + default_gemfile.dirname + end + private def self.default_gemfile diff --git a/lib/gemfile/cli.rb b/lib/gemfile/cli.rb index 9f57ed9811..21bd12f197 100644 --- a/lib/gemfile/cli.rb +++ b/lib/gemfile/cli.rb @@ -44,12 +44,19 @@ module Gemfile desc "install", "Install the current environment to the system" def install - Installer.install(Gemfile.definition) + Installer.install(Gemfile.root, Gemfile.definition) end desc "lock", "Locks a resolve" def lock - Gemfile.load.lock + environment = Gemfile.load + environment.lock + end + + desc "pack", "Packs all the gems to vendor/cache" + def pack + environment = Gemfile.load + environment.pack end private diff --git a/lib/gemfile/definition.rb b/lib/gemfile/definition.rb index 42b6e4d35c..f3503c564f 100644 --- a/lib/gemfile/definition.rb +++ b/lib/gemfile/definition.rb @@ -26,6 +26,17 @@ module Gemfile @sources = sources end + def local_index + @local_index ||= begin + index = Index.from_installed_gems + + sources.reverse_each do |source| + index.merge! source.local_specs if source.respond_to?(:local_specs) + end + index + end + end + # def equivalent?(other) # self.matches?(other) && other.matches?(self) # # other.matches?(self) diff --git a/lib/gemfile/environment.rb b/lib/gemfile/environment.rb index 299eb4439c..356a28b8da 100644 --- a/lib/gemfile/environment.rb +++ b/lib/gemfile/environment.rb @@ -34,12 +34,17 @@ module Gemfile end def index - @index ||= begin - index = Index.new - sources.reverse_each do |source| - index.merge! source.local_specs - end - index + @definition.local_index + end + + def pack + pack_path = "#{root}/vendor/cache/" + FileUtils.mkdir_p(pack_path) + + specs.each do |spec| + possibilities = Gem.path.map { |p| "#{p}/cache/#{spec.full_name}.gem" } + cached_path = possibilities.find { |p| File.exist? p } + FileUtils.cp(cached_path, pack_path) end end diff --git a/lib/gemfile/index.rb b/lib/gemfile/index.rb index 131142fc03..78200347fe 100644 --- a/lib/gemfile/index.rb +++ b/lib/gemfile/index.rb @@ -1,7 +1,7 @@ module Gemfile class Index def self.from_installed_gems - from_gem_index(Gem::SourceIndex.from_installed_gems) + @from_installed_gems ||= from_gem_index(Gem::SourceIndex.from_installed_gems) end def self.from_gem_index(gem_index) diff --git a/lib/gemfile/installer.rb b/lib/gemfile/installer.rb index f4fb7e2e4e..0c9c62a8ca 100644 --- a/lib/gemfile/installer.rb +++ b/lib/gemfile/installer.rb @@ -2,17 +2,21 @@ require 'rubygems/dependency_installer' module Gemfile class Installer - def self.install(definition) - new(definition).run + def self.install(root, definition) + new(root, definition).run end - def initialize(definition) + attr_reader :root + + def initialize(root, definition) + @root = root @definition = definition end def run specs.each do |spec| - spec.source.install spec + next unless spec.source.respond_to?(:install) + spec.source.install(spec) end end @@ -35,6 +39,11 @@ module Gemfile def index @index ||= begin index = Index.new + + if File.directory?("#{root}/vendor/cache") + index.merge! Source::GemCache.new(:path => "#{root}/vendor/cache").specs + end + sources.reverse_each do |source| index.merge!(source.specs) end diff --git a/lib/gemfile/source.rb b/lib/gemfile/source.rb index 3320066d63..041f4cb7c9 100644 --- a/lib/gemfile/source.rb +++ b/lib/gemfile/source.rb @@ -1,4 +1,5 @@ require "rubygems/remote_fetcher" +require "rubygems/format" require "digest/sha1" module Gemfile @@ -17,12 +18,8 @@ module Gemfile @specs ||= fetch_specs end - def local_specs - @local_specs ||= Index.from_installed_gems - end - def install(spec) - return if local_specs[spec].any? + return if Index.from_installed_gems[spec].any? destination = Gem.dir @@ -60,6 +57,36 @@ module Gemfile end end + class GemCache + def initialize(options) + @path = options[:path] + end + + def specs + @specs ||= begin + index = Index.new + + Dir["#{@path}/*.gem"].each do |gemfile| + spec = Gem::Format.from_file_by_path(gemfile).spec + spec.source = self + index << spec + end + + index + end + end + + def install(spec) + destination = Gem.dir + + installer = Gem::Installer.new "#{@path}/#{spec.full_name}.gem", + :install_dir => Gem.dir, + :ignore_dependencies => true + + installer.install + end + end + class Path attr_reader :path, :options @@ -87,9 +114,6 @@ module Gemfile end alias local_specs specs - - def install(spec) - end end class Git < Path diff --git a/spec/install/gems_spec.rb b/spec/install/gems_spec.rb index ab59402b79..60f3fad4c3 100644 --- a/spec/install/gems_spec.rb +++ b/spec/install/gems_spec.rb @@ -58,14 +58,9 @@ describe "gemfile install with gem sources" do end it "does not reinstall any gem that is already available locally" do - build_repo2 + system_gems "activesupport-2.3.2" - install_gemfile <<-G - source "file://#{gem_repo2}" - gem "activesupport", "2.3.2" - G - - update_repo gem_repo2 do + build_repo2 do build_gem "activesupport", "2.3.2" do |s| s.write "lib/activesupport.rb", "ACTIVESUPPORT = 'fail'" end @@ -79,6 +74,12 @@ describe "gemfile install with gem sources" do should_be_installed "activesupport 2.3.2" end + it "does not hit the remote source if the gemfile can be satisfied locally" do + # system_gems "activesupport-2.3.2" + + pending + end + describe "with extra sources" do it "finds gems in multiple sources" do diff --git a/spec/pack/gems_spec.rb b/spec/pack/gems_spec.rb new file mode 100644 index 0000000000..32f593200b --- /dev/null +++ b/spec/pack/gems_spec.rb @@ -0,0 +1,23 @@ +require File.expand_path('../../spec_helper', __FILE__) + +describe "gemfile pack with gems" do + before :each do + gemfile <<-G + gem 'rack' + G + + system_gems "rack-1.0.0" + bbl :pack + end + + it "copies the .gem file to vendor/cache" do + bundled_app("vendor/cache/rack-1.0.0.gem").should exist + end + + it "uses the pack as a source when installing gems" do + system_gems [] + bbl :install + + should_be_installed("rack 1.0.0") + end +end
\ No newline at end of file diff --git a/spec/pack/git_spec.rb b/spec/pack/git_spec.rb new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/spec/pack/git_spec.rb diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 129f690f1d..58d505f727 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -28,7 +28,8 @@ Spec::Runner.configure do |config| config.before :each do reset! - system_gems + system_gems [] + in_app_root end config.after :each do diff --git a/spec/support/builders.rb b/spec/support/builders.rb index 99099d9bc6..83a47f0997 100644 --- a/spec/support/builders.rb +++ b/spec/support/builders.rb @@ -95,9 +95,10 @@ module Spec end end - def build_repo2 + def build_repo2(&blk) FileUtils.rm_rf gem_repo2 FileUtils.cp_r gem_repo1, gem_repo2 + update_repo2(&blk) if block_given? end def update_repo2 |