diff options
-rw-r--r-- | bin/bundle | 2 | ||||
-rw-r--r-- | lib/bundler.rb | 1 | ||||
-rw-r--r-- | lib/bundler/dsl.rb | 26 | ||||
-rw-r--r-- | lib/bundler/environment.rb | 1 | ||||
-rw-r--r-- | lib/bundler/installer.rb | 18 | ||||
-rw-r--r-- | lib/bundler/source.rb | 41 | ||||
-rw-r--r-- | lib/bundler/ui.rb | 2 | ||||
-rw-r--r-- | spec/install/git_spec.rb | 9 | ||||
-rw-r--r-- | spec/other/check_spec.rb | 2 | ||||
-rw-r--r-- | spec/spec_helper.rb | 1 | ||||
-rw-r--r-- | spec/support/helpers.rb | 7 |
11 files changed, 73 insertions, 37 deletions
diff --git a/bin/bundle b/bin/bundle index d11614be86..ea45509380 100644 --- a/bin/bundle +++ b/bin/bundle @@ -3,6 +3,6 @@ require 'bundler/cli' begin Bundler::CLI.start rescue Bundler::BundlerError => e - puts e.message + Bundler.ui.error e.message exit e.status_code end
\ No newline at end of file diff --git a/lib/bundler.rb b/lib/bundler.rb index 200c8d9c0d..7a508ee632 100644 --- a/lib/bundler.rb +++ b/lib/bundler.rb @@ -34,6 +34,7 @@ module Bundler class GemNotFound < BundlerError; status_code(7) ; end class VersionConflict < BundlerError; status_code(6) ; end class GemfileError < BundlerError; status_code(4) ; end + class GitError < BundlerError; status_code(11) ; end class << self attr_writer :ui, :bundle_path diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index 1727f12ce0..f4f4b8a1e8 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -25,8 +25,8 @@ module Bundler def source(source, options = {}) source = case source - when :gemcutter, :rubygems, :rubyforge then Source::Rubygems.new(:uri => "http://gemcutter.org") - when String then Source::Rubygems.new(:uri => source) + when :gemcutter, :rubygems, :rubyforge then Source::Rubygems.new("uri" => "http://gemcutter.org") + when String then Source::Rubygems.new("uri" => source) else source end @@ -34,12 +34,12 @@ module Bundler source end - def path(path, options = {}) - source Source::Path.new(options.merge(:path => path)), options + def path(path, options = {}, source_options = {}) + source Source::Path.new(_normalize_hash(options).merge("path" => path)), source_options end - def git(uri, options = {}) - source Source::Git.new(options.merge(:uri => uri)), options + def git(uri, options = {}, source_options = {}) + source Source::Git.new(_normalize_hash(options).merge("uri" => uri)), source_options end def to_definition @@ -59,21 +59,29 @@ module Bundler version && Gem::Version.new(version) rescue false end - def _normalize_options(name, version, opts) + def _normalize_hash(opts) opts.each do |k, v| + next if String === k + opts.delete(k) opts[k.to_s] = v end + end - opts["group"] ||= @group + def _normalize_options(name, version, opts) + _normalize_hash(opts) + + group = opts.delete("group") || @group # Normalize git and path options ["git", "path"].each do |type| if param = opts[type] - source = send(type, param, opts.merge(:prepend => true)) + source = send(type, param, opts.dup, :prepend => true) source.default_spec name, version if _version?(version) opts["source"] = source end end + + opts["group"] = group end end end
\ No newline at end of file diff --git a/lib/bundler/environment.rb b/lib/bundler/environment.rb index 004b978fa6..b2719b1eed 100644 --- a/lib/bundler/environment.rb +++ b/lib/bundler/environment.rb @@ -81,6 +81,7 @@ module Bundler possibilities = Gem.path.map { |p| "#{p}/cache/#{spec.full_name}.gem" } cached_path = possibilities.find { |p| File.exist? p } Bundler.ui.info " * #{File.basename(cached_path)}" + next if File.expand_path(File.dirname(cached_path)) == File.expand_path(pack_path) FileUtils.cp(cached_path, pack_path) end end diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb index 7be43faa63..be712195c6 100644 --- a/lib/bundler/installer.rb +++ b/lib/bundler/installer.rb @@ -47,7 +47,7 @@ module Bundler def resolve_locally # Return unless all the dependencies have = version requirements - return unless dependencies.all? { |d| unambiguous?(d) } + return if dependencies.any? { |d| ambiguous?(d) } index = local_index sources.each do |source| @@ -68,6 +68,7 @@ module Bundler specs.length == dependencies.length && specs rescue Bundler::GemNotFound nil + raise if ENV["OMG"] end def resolve_remotely @@ -101,8 +102,8 @@ module Bundler end end - def unambiguous?(dep) - dep.version_requirements.requirements.all? { |op,_| op == '=' } + def ambiguous?(dep) + dep.version_requirements.requirements.any? { |op,_| op != '=' } end def index @@ -122,18 +123,23 @@ module Bundler def local_index @local_index ||= begin - index = Index.from_installed_gems.freeze + index = Index.new + + sources.each do |source| + next unless source.respond_to?(:local_specs) + index = source.local_specs.merge(index) + end if File.directory?("#{root}/vendor/cache") index = cache_source.specs.merge(index).freeze end - index + Index.from_installed_gems.merge(index) end end def cache_source - Source::GemCache.new(:path => "#{root}/vendor/cache") + Source::GemCache.new("path" => "#{root}/vendor/cache") end end diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb index ba1b1bcb86..4556322d5d 100644 --- a/lib/bundler/source.rb +++ b/lib/bundler/source.rb @@ -1,6 +1,7 @@ require "rubygems/remote_fetcher" require "rubygems/format" require "digest/sha1" +require "open3" module Bundler module Source @@ -9,7 +10,7 @@ module Bundler def initialize(options = {}) @options = options - @uri = options[:uri] + @uri = options["uri"] @uri = URI.parse(@uri) unless @uri.is_a?(URI) raise ArgumentError, "The source must be an absolute URI" unless @uri.absolute? end @@ -85,7 +86,7 @@ module Bundler class GemCache def initialize(options) - @path = options[:path] + @path = options["path"] end def specs @@ -119,8 +120,8 @@ module Bundler def initialize(options) @options = options - @glob = options[:glob] || "{,*/}*.gemspec" - @path = options[:path] + @glob = options["glob"] || "{,*/}*.gemspec" + @path = options["path"] @default_spec = nil end @@ -172,13 +173,13 @@ module Bundler def initialize(options) @options = options - @glob = options[:glob] || "{,*/}*.gemspec" - @uri = options[:uri] - @ref = options[:ref] || options[:branch] || 'master' + @glob = options["glob"] || "{,*/}*.gemspec" + @uri = options["uri"] + @ref = options["ref"] || options["branch"] || 'master' end def options - @options.merge(:ref => revision) + @options.merge("ref" => revision) end def path @@ -229,12 +230,12 @@ module Bundler FileUtils.mkdir_p(path) Dir.chdir(path) do unless File.exist?(".git") - %x(git clone --recursive --no-checkout #{cache_path} #{path}) + %x(git clone --no-checkout #{cache_path} #{path}) end - %x(git fetch --quiet) - %x(git reset --hard #{revision}) - %x(git submodule init) - %x(git submodule update) + git "fetch --quiet" + git "reset --hard #{revision}" + git "submodule init" + git "submodule update" end @installed = true end @@ -242,6 +243,14 @@ module Bundler private + def git(command) + out = %x{git #{command}} + if $? != 0 + raise GitError, "An error has occurred in git. Cannot complete bundling." + end + out + end + def base_name File.basename(uri, ".git") end @@ -257,17 +266,17 @@ module Bundler def cache if cache_path.exist? Bundler.ui.info "Source: Updating `#{uri}`... " - in_cache { `git fetch --quiet #{uri} master:master` } + in_cache { git "fetch --quiet #{uri} master:master" } else Bundler.ui.info "Source: Cloning `#{uri}`... " FileUtils.mkdir_p(cache_path.dirname) - `git clone #{uri} #{cache_path} --bare --no-hardlinks` + git "clone #{uri} #{cache_path} --bare --no-hardlinks" end Bundler.ui.info "Done." end def revision - @revision ||= in_cache { `git rev-parse #{ref}`.strip } + @revision ||= in_cache { git("rev-parse #{ref}").strip } end def in_cache(&blk) diff --git a/lib/bundler/ui.rb b/lib/bundler/ui.rb index 52b356ed02..21f05f10ae 100644 --- a/lib/bundler/ui.rb +++ b/lib/bundler/ui.rb @@ -30,7 +30,7 @@ module Bundler end def error(msg) - @shell.say(msg, :error) + @shell.say(msg, :red) end end diff --git a/spec/install/git_spec.rb b/spec/install/git_spec.rb index 00346e455e..580e389407 100644 --- a/spec/install/git_spec.rb +++ b/spec/install/git_spec.rb @@ -140,4 +140,13 @@ describe "gemfile install with git sources" do should_be_installed("foo 1.0") end + + it "catches git errors and spits out useful output" do + install_gemfile <<-G + gem "foo", "1.0", :git => "omgomg" + G + + out.should include("An error has occurred in git. Cannot complete bundling.") + err.should == "fatal: 'omgomg' does not appear to be a git repository\nfatal: The remote end hung up unexpectedly" + end end
\ No newline at end of file diff --git a/spec/other/check_spec.rb b/spec/other/check_spec.rb index c05aa88266..e91d2fe17f 100644 --- a/spec/other/check_spec.rb +++ b/spec/other/check_spec.rb @@ -58,6 +58,6 @@ describe "bundle check" do it "outputs an error when the default Gemspec is not found" do bundle :check - out.should == "The default Gemfile was not found" + out.should =~ /The default Gemfile was not found/ end end
\ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 776c8d8ec3..27066ca525 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,7 +4,6 @@ $:.unshift File.expand_path('../../lib', __FILE__) require 'fileutils' require 'rubygems' require 'bundler' -gem 'rspec', '~> 1.3.0' require 'spec' Dir["#{File.expand_path('../support', __FILE__)}/*.rb"].each do |file| diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb index 4f78173190..53e712d792 100644 --- a/spec/support/helpers.rb +++ b/spec/support/helpers.rb @@ -11,7 +11,7 @@ module Spec Gem.configuration.write end - attr_reader :out + attr_reader :out, :err def in_app_root(&blk) Dir.chdir(bundled_app, &blk) @@ -38,9 +38,12 @@ module Spec end def bundle(cmd, options = {}) + require "open3" args = options.map { |k,v| " --#{k} #{v}"}.join gemfile = File.expand_path('../../../bin/bundle', __FILE__) - @out = %x{#{Gem.ruby} -I#{lib} #{gemfile} #{cmd}#{args}}.strip + @in, @out, @err = Open3.popen3("#{Gem.ruby} -I#{lib} #{gemfile} #{cmd}#{args}") + @err = @err.read.strip + @out = @out.read.strip end def ruby(opts, ruby = nil) |