summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlhuda <carlhuda@engineyard.com>2010-01-25 15:39:54 -0800
committerCarlhuda <carlhuda@engineyard.com>2010-01-25 15:39:54 -0800
commit63b636b9dd25bc9b63a9ffb6f4071cabccdf6ae5 (patch)
tree4eaf174379a8ab8492af97b915bb5df8dce3f607
parent50087020c54fe16be9d9b04146f247b2c1ab1e92 (diff)
downloadbundler-63b636b9dd25bc9b63a9ffb6f4071cabccdf6ae5.tar.gz
First pass at gemfile pack
-rw-r--r--lib/gemfile.rb5
-rw-r--r--lib/gemfile/cli.rb11
-rw-r--r--lib/gemfile/definition.rb11
-rw-r--r--lib/gemfile/environment.rb17
-rw-r--r--lib/gemfile/index.rb2
-rw-r--r--lib/gemfile/installer.rb17
-rw-r--r--lib/gemfile/source.rb40
-rw-r--r--spec/install/gems_spec.rb15
-rw-r--r--spec/pack/gems_spec.rb23
-rw-r--r--spec/pack/git_spec.rb0
-rw-r--r--spec/spec_helper.rb3
-rw-r--r--spec/support/builders.rb3
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