From f329d586cde5a924f1b8e170117e5b6cb96ed9ee Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Fri, 29 Jan 2010 15:14:04 -0800 Subject: Add first round of source pinning support --- lib/bundler.rb | 2 +- lib/bundler/cli.rb | 9 ++++++++- lib/bundler/dependency.rb | 5 ++--- lib/bundler/dsl.rb | 9 ++++++--- lib/bundler/index.rb | 10 +++++++++- lib/bundler/installer.rb | 11 ++++------- lib/bundler/resolver.rb | 7 ++++--- lib/bundler/rubygems.rb | 2 +- lib/bundler/source.rb | 12 ++++++++---- spec/install/git_spec.rb | 13 +++++++++++++ 10 files changed, 56 insertions(+), 24 deletions(-) diff --git a/lib/bundler.rb b/lib/bundler.rb index 8e47d6f582..c3047fdbf5 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -52,7 +52,7 @@ module Bundler end def self.home - Pathname.new(Gem.dir).join("gemfile") + Pathname.new(Gem.dir).join("bundler") end def self.install_path diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb index d700caa0ad..5dd27ca677 100644 --- a/lib/bundler/cli.rb +++ b/lib/bundler/cli.rb @@ -51,7 +51,14 @@ module Bundler desc "install", "Install the current environment to the system" method_option :without, :type => :array, :banner => "Exclude gems thar are part of the specified named group" def install - Installer.install(Bundler.root, Bundler.definition, options) + opts = options.dup + opts[:without] ||= [] + opts[:without].map! { |g| g.to_sym } + + Installer.install(Bundler.root, Bundler.definition, opts) + rescue Bundler::GemNotFound => e + puts e.message + exit 1 end desc "lock", "Locks a resolve" diff --git a/lib/bundler/dependency.rb b/lib/bundler/dependency.rb index c5a685ec1b..a9bee54672 100644 --- a/lib/bundler/dependency.rb +++ b/lib/bundler/dependency.rb @@ -2,12 +2,11 @@ require 'rubygems/dependency' module Bundler class Dependency < Gem::Dependency - attr_accessor :source - def initialize(name, version, options = {}, &blk) super(name, version) - @group = options["group"] || :default + @group = options["group"] || :default + @source = options["source"] end end end \ No newline at end of file diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index feedfda8f9..d81b7a2dce 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -11,8 +11,6 @@ module Bundler def initialize @sources = [] # Gem.sources.map { |s| Source::Rubygems.new(:uri => s) } @dependencies = [] - @git = nil - @git_sources = {} @group = nil end @@ -25,9 +23,13 @@ module Bundler options[k.to_s] = v end - # Set defaults + # Set options options["group"] ||= @group + if options["git"] + options["source"] = git(options["git"]) + end + @dependencies << Dependency.new(name, version, options) end @@ -39,6 +41,7 @@ module Bundler end @sources << source + source end def path(path, options = {}) diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index 013bf14042..79cbb10fc8 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -19,7 +19,8 @@ module Bundler def initialize_copy(o) super @cache = {} - @specs = @specs.dup + @specs = Hash.new { |h,k| h[k] = [] } + merge!(o) end def search(query) @@ -60,6 +61,13 @@ module Bundler dup.merge!(other) end + def freeze + @specs.each do |k,v| + v.freeze + end + super + end + private def search_by_spec(spec) diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 452577fe29..900630eb7e 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -19,11 +19,9 @@ module Bundler return end - without = options[:without] ? options[:without].map {|w| w.to_sym } : [] - specs.each do |spec| next unless spec.source.respond_to?(:install) - next if (spec.groups & without).any? + next if (spec.groups & options[:without]).any? spec.source.install(spec) end @@ -91,9 +89,8 @@ module Bundler index = local_index sources.each do |source| - specs = source.specs Bundler.ui.info "Source: Processing index... " - index = specs.merge(index) + index = source.specs.merge(index).freeze Bundler.ui.info "Done." end @@ -103,10 +100,10 @@ module Bundler def local_index @local_index ||= begin - index = Index.from_installed_gems + index = Index.from_installed_gems.freeze if File.directory?("#{root}/vendor/cache") - index = cache_source.specs.merge(index) + index = cache_source.specs.merge(index).freeze end index diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb index 3b46014b23..86b3d4a8dd 100644 --- a/lib/bundler/resolver.rb +++ b/lib/bundler/resolver.rb @@ -149,7 +149,7 @@ module Bundler if matching_versions.empty? if current.required_by.empty? - location = "any of the sources" + location = current.source ? current.source.to_s : "any of the sources" raise GemNotFound, "Could not find gem '#{current}' in #{location}" else @errors[current.name] = [nil, current] @@ -213,8 +213,9 @@ module Bundler retval end - def search(dependency) - @index.search(dependency) + def search(dep) + index = dep.source ? dep.source.specs : @index + index.search(dep) end end end diff --git a/lib/bundler/rubygems.rb b/lib/bundler/rubygems.rb index 55c9af23de..e462a503b3 100644 --- a/lib/bundler/rubygems.rb +++ b/lib/bundler/rubygems.rb @@ -17,6 +17,6 @@ module Gem end class Dependency - attr_accessor :group + attr_accessor :source, :group end end \ No newline at end of file diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb index ab6ff52b14..702decbfa1 100644 --- a/lib/bundler/source.rb +++ b/lib/bundler/source.rb @@ -48,7 +48,7 @@ module Bundler index << spec end Bundler.ui.info "done." - index + index.freeze end def main_specs @@ -80,7 +80,7 @@ module Bundler index << spec end - index + index.freeze end end @@ -117,7 +117,7 @@ module Bundler index << spec end end - index + index.freeze end end @@ -142,6 +142,10 @@ module Bundler Bundler.install_path.join("#{base_name}-#{uri_hash}-#{ref}") end + def to_s + @uri + end + def specs @specs ||= begin index = Index.new @@ -165,7 +169,7 @@ module Bundler end end end - index + index.freeze end end diff --git a/spec/install/git_spec.rb b/spec/install/git_spec.rb index 36a704c32e..55a4a209f8 100644 --- a/spec/install/git_spec.rb +++ b/spec/install/git_spec.rb @@ -66,4 +66,17 @@ describe "gemfile install with git sources" do out.should == "WIN" end end + + describe "pinning" do + it "installs from git even if a newer gem is available elsewhere" do + build_git "rack", "0.8" + + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack", :git => "#{lib_path('rack-0.8')}" + G + + should_be_installed "rack 0.8" + end + end end \ No newline at end of file -- cgit v1.2.1