[DRE-commits] [bundler] 01/03: Imported Upstream version 1.7.2

zeha at debian.org zeha at debian.org
Mon Aug 25 17:32:40 UTC 2014


This is an automated email from the git hooks/post-receive script.

zeha pushed a commit to branch master
in repository bundler.

commit c817377919c273ff38e4e1143cd331168c6b5f63
Author: Christian Hofstaedtler <zeha at debian.org>
Date:   Mon Aug 25 19:14:36 2014 +0200

    Imported Upstream version 1.7.2
---
 .travis.yml                                        |   1 +
 CHANGELOG.md                                       |  47 +++
 Rakefile                                           |  10 +-
 bin/bundle                                         |   7 +-
 bin/bundler                                        |  23 +-
 bundler.gemspec                                    |   3 +-
 checksums.yaml.gz                                  | Bin 269 -> 268 bytes
 lib/bundler.rb                                     |   3 +-
 lib/bundler/cli.rb                                 |   3 +-
 lib/bundler/cli/binstubs.rb                        |   2 +
 lib/bundler/cli/cache.rb                           |   2 +-
 lib/bundler/cli/install.rb                         |  11 +-
 lib/bundler/cli/package.rb                         |   2 +-
 lib/bundler/definition.rb                          | 121 +++----
 lib/bundler/dsl.rb                                 |  85 ++---
 lib/bundler/fetcher.rb                             |  99 +++---
 lib/bundler/index.rb                               |  33 +-
 lib/bundler/installer.rb                           |  12 +-
 lib/bundler/lockfile_parser.rb                     |  27 +-
 lib/bundler/man/bundle                             |   2 +-
 lib/bundler/man/bundle-config                      |   2 +-
 lib/bundler/man/bundle-config.txt                  |   2 +-
 lib/bundler/man/bundle-exec                        |   2 +-
 lib/bundler/man/bundle-exec.txt                    |   2 +-
 lib/bundler/man/bundle-install                     |   8 +-
 lib/bundler/man/bundle-install.txt                 |  13 +-
 lib/bundler/man/bundle-package                     |   2 +-
 lib/bundler/man/bundle-package.txt                 |   2 +-
 lib/bundler/man/bundle-platform                    |   2 +-
 lib/bundler/man/bundle-platform.txt                |   2 +-
 lib/bundler/man/bundle-update                      |   2 +-
 lib/bundler/man/bundle-update.txt                  |   2 +-
 lib/bundler/man/bundle.txt                         |   2 +-
 lib/bundler/man/gemfile.5                          |  49 ++-
 lib/bundler/man/gemfile.5.txt                      | 147 +++++----
 lib/bundler/parallel_workers.rb                    |   2 +-
 lib/bundler/rubygems_integration.rb                |   4 +
 lib/bundler/runtime.rb                             |   2 +-
 lib/bundler/source.rb                              |   9 +
 lib/bundler/source/git.rb                          |   5 +-
 lib/bundler/source/path.rb                         |   2 +-
 lib/bundler/source/rubygems.rb                     | 106 +++---
 lib/bundler/source_list.rb                         |  80 +++++
 lib/bundler/templates/newgem/README.md.tt          |   4 +-
 lib/bundler/templates/newgem/gitignore.tt          |  26 +-
 lib/bundler/templates/newgem/newgem.gemspec.tt     |   2 +-
 lib/bundler/ui/shell.rb                            |   7 +-
 lib/bundler/vendored_persistent.rb                 |   8 +
 lib/bundler/version.rb                             |   2 +-
 man/bundle-install.ronn                            |   9 +-
 man/gemfile.5.ronn                                 |  58 +++-
 metadata.yml                                       |  37 ++-
 spec/bundler/definition_spec.rb                    |   3 +-
 .../{source_spec.rb => source/rubygems_spec.rb}    |   0
 spec/bundler/source_list_spec.rb                   | 361 +++++++++++++++++++++
 spec/commands/binstubs_spec.rb                     |  13 +
 spec/install/deploy_spec.rb                        |  12 +
 spec/install/gems/dependency_api_spec.rb           |   4 +-
 spec/install/gems/sources_spec.rb                  | 247 ++++++++++++++
 spec/lock/lockfile_spec.rb                         |  66 +++-
 spec/quality_spec.rb                               |   8 +-
 spec/runtime/setup_spec.rb                         |  23 +-
 spec/support/helpers.rb                            |  14 +
 spec/update/git_spec.rb                            |  47 +++
 spec/update/path_spec.rb                           |  18 +
 spec/update/source_spec.rb                         |  63 ----
 66 files changed, 1521 insertions(+), 453 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 06d8f95..a860fc6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,7 @@ before_script: travis_retry rake spec:travis:deps
 branches:
   only:
     - master
+    - 1-7-stable
     - 1-6-stable
     - 1-5-stable
     - 1-3-stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e2f0cb1..751baac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,50 @@
+## 1.7.2 (2014-08-23)
+
+Bugfixes:
+
+  - Revert gem source sorting in lock files (@indirect)
+
+## 1.7.1 (2014-08-20)
+
+Bugfixes:
+
+  - Install gems from one source needed by gems in another source (@indirect)
+  - Install the same gem versions even after some are installed (@tmoore)
+  - Download specs only when installing from servers (@indirect)
+
+## 1.7.0 (2014-08-13)
+
+Security:
+
+  - Fix for CVE-2013-0334, installing gems from an unexpected source (@tmoore)
+
+Features:
+
+  - Gemfile `source` calls now take a block containing gems from that source (@tmoore)
+  - added the `:source` option to `gem` to specify a source (@tmoore)
+
+Bugfixes:
+
+  - warn on ambiguous gems available from more than one source (@tmoore)
+
+## 1.6.5 (2014-07-23)
+
+Bugfixes:
+
+  - require openssl explicitly to fix rare HTTPS request failures (@indirect, #3107)
+
+## 1.6.4 (2014-07-17)
+
+Bugfixes:
+
+  - fix undefined constant error when can't find gem during binstubs (#3095, @jetaggart)
+  - work when installed git gems are not writable (#3092, @pmahoney)
+  - don't store configured source credentials in Gemfile.lock (#3045, @lhz)
+  - don't include config source credentials in the lockfile (Lars Haugseth)
+  - use threads for jobs on Rubinius (@YorickPeterse)
+  - skip dependencies from other platforms (@mvz)
+  - work when Rubygems was built without SSL (@andremedeiros)
+
 ## 1.6.3 (2014-06-16)
 
 Bugfixes:
diff --git a/Rakefile b/Rakefile
index 3177114..3775c3d 100644
--- a/Rakefile
+++ b/Rakefile
@@ -30,11 +30,10 @@ end
 namespace :spec do
   desc "Ensure spec dependencies are installed"
   task :deps do
-    deps = {
-      "rdiscount" => "~> 1.6",
-      "ronn" => "~> 0.7.3",
-      "rspec" => "~> 3.0.beta"
-    }
+    spec = Gem::Specification.load("bundler.gemspec")
+    deps = Hash[spec.development_dependencies.map do |d|
+      [d.name, d.requirement.to_s]
+    end]
 
     # JRuby can't build ronn or rdiscount, so we skip that
     if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
@@ -77,7 +76,6 @@ namespace :spec do
 end
 
 begin
-  # running the specs needs both rspec and ronn
   require 'rspec/core/rake_task'
 
   desc "Run specs"
diff --git a/bin/bundle b/bin/bundle
index 7bfdd3a..63285e9 100755
--- a/bin/bundle
+++ b/bin/bundle
@@ -14,7 +14,8 @@ $LOAD_PATH.each do |path|
   end
 end
 
-require 'bundler/cli'
-
 require 'bundler/friendly_errors'
-Bundler.with_friendly_errors { Bundler::CLI.start(ARGV, :debug => true) }
+Bundler.with_friendly_errors do
+  require 'bundler/cli'
+  Bundler::CLI.start(ARGV, :debug => true)
+end
diff --git a/bin/bundler b/bin/bundler
index 35941a2..63285e9 100755
--- a/bin/bundler
+++ b/bin/bundler
@@ -1,10 +1,21 @@
 #!/usr/bin/env ruby
 
-require 'bundler'
-require 'bundler/cli'
+# Exit cleanly from an early interrupt
+Signal.trap("INT") { exit 1 }
 
-ui = Bundler::UI::Shell.new
-ui.error "It's recommended to use Bundler through 'bundle' binary instead of 'bundler'"
+require 'bundler'
+# Check if an older version of bundler is installed
+$LOAD_PATH.each do |path|
+  if path =~ %r'/bundler-0.(\d+)' && $1.to_i < 9
+    err = "Looks like you have a version of bundler that's older than 0.9.\n"
+    err << "Please remove your old versions.\n"
+    err << "An easy way to do this is by running `gem cleanup bundler`."
+    abort(err)
+  end
+end
 
-bin = "#{File.dirname(__FILE__)}/bundle #{ARGV.join(" ")}"
-exec bin
+require 'bundler/friendly_errors'
+Bundler.with_friendly_errors do
+  require 'bundler/cli'
+  Bundler::CLI.start(ARGV, :debug => true)
+end
diff --git a/bundler.gemspec b/bundler.gemspec
index 17ed42f..dc8fbc8 100644
--- a/bundler.gemspec
+++ b/bundler.gemspec
@@ -16,8 +16,9 @@ Gem::Specification.new do |spec|
   spec.required_ruby_version     = '>= 1.8.7'
   spec.required_rubygems_version = '>= 1.3.6'
 
+  spec.add_development_dependency 'rdiscount', '~> 1.6'
   spec.add_development_dependency 'ronn', '~> 0.7.3'
-  spec.add_development_dependency 'rspec', '~> 2.99.0.beta1'
+  spec.add_development_dependency 'rspec', '~> 3.0'
 
   spec.files       = `git ls-files -z`.split("\x0")
   spec.files      += Dir.glob('lib/bundler/man/**/*') # man/ is ignored by git
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
index 8047b1f..efe0ebe 100644
Binary files a/checksums.yaml.gz and b/checksums.yaml.gz differ
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 620f2e6..1eaf194 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -41,6 +41,7 @@ module Bundler
   autoload :SharedHelpers,         'bundler/shared_helpers'
   autoload :SpecSet,               'bundler/spec_set'
   autoload :Source,                'bundler/source'
+  autoload :SourceList,            'bundler/source_list'
   autoload :Specification,         'bundler/shared_helpers'
   autoload :SystemRubyVersion,     'bundler/ruby_version'
   autoload :UI,                    'bundler/ui'
@@ -189,7 +190,7 @@ module Bundler
     end
 
     def root
-      default_gemfile.dirname.expand_path
+      @root ||= default_gemfile.dirname.expand_path
     end
 
     def app_config_path
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index df54c47..c3e5d8b 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -136,8 +136,7 @@ module Bundler
       "Run bundle clean automatically after install"
     method_option "trust-policy", :alias => "P", :type => :string, :banner =>
       "Gem trust policy (like gem install -P). Must be one of " +
-        Bundler.rubygems.security_policies.keys.join('|') unless
-        Bundler.rubygems.security_policies.empty?
+        Bundler.rubygems.security_policy_keys.join('|')
     method_option "jobs", :aliases => "-j", :type => :numeric, :banner =>
       "Specify the number of jobs to run in parallel"
 
diff --git a/lib/bundler/cli/binstubs.rb b/lib/bundler/cli/binstubs.rb
index 05cad4d..d5ff5b6 100644
--- a/lib/bundler/cli/binstubs.rb
+++ b/lib/bundler/cli/binstubs.rb
@@ -1,3 +1,5 @@
+require "bundler/cli/common"
+
 module Bundler
   class CLI::Binstubs
     attr_reader :options, :gems
diff --git a/lib/bundler/cli/cache.rb b/lib/bundler/cli/cache.rb
index d404676..653ead7 100644
--- a/lib/bundler/cli/cache.rb
+++ b/lib/bundler/cli/cache.rb
@@ -23,7 +23,7 @@ module Bundler
     def setup_cache_all
       Bundler.settings[:cache_all] = options[:all] if options.key?("all")
 
-      if Bundler.definition.sources.any? { |s| !s.is_a?(Source::Rubygems) } && !Bundler.settings[:cache_all]
+      if Bundler.definition.has_local_dependencies? && !Bundler.settings[:cache_all]
         Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want "    \
           "to package them as well, please pass the --all flag. This will be the default " \
           "on Bundler 2.0."
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb
index 2f5b490..9bb7f68 100644
--- a/lib/bundler/cli/install.rb
+++ b/lib/bundler/cli/install.rb
@@ -93,6 +93,15 @@ module Bundler
         Bundler.ui.confirm "Post-install message from #{name}:"
         Bundler.ui.info msg
       end
+      Installer.ambiguous_gems.to_a.each do |name, installed_from_uri, *also_found_in_uris|
+        Bundler.ui.error "Warning: the gem '#{name}' was found in multiple sources."
+        Bundler.ui.error "Installed from: #{installed_from_uri}"
+        Bundler.ui.error "Also found in:"
+        also_found_in_uris.each { |uri| Bundler.ui.error "  * #{uri}" }
+        Bundler.ui.error "You should add a source requirement to restrict this gem to your preferred source."
+        Bundler.ui.error "For example:"
+        Bundler.ui.error "    gem '#{name}', :source => '#{installed_from_uri}'"
+      end
 
       if Bundler.settings[:clean] && Bundler.settings[:path]
         require "bundler/cli/clean"
@@ -103,7 +112,7 @@ module Bundler
         Bundler.ui.warn "Some gems seem to be missing from your vendor/cache directory."
       end
 
-      if Bundler.definition.rubygems_remotes.empty?
+      unless Bundler.definition.has_rubygems_remotes?
         Bundler.ui.warn <<-WARN, :wrap => true
           Your Gemfile has no gem server sources. If you need gems that are \
           not already on your machine, add a line like this to your Gemfile:
diff --git a/lib/bundler/cli/package.rb b/lib/bundler/cli/package.rb
index 9f272a6..b294603 100644
--- a/lib/bundler/cli/package.rb
+++ b/lib/bundler/cli/package.rb
@@ -26,7 +26,7 @@ module Bundler
     def setup_cache_all
       Bundler.settings[:cache_all] = options[:all] if options.key?("all")
 
-      if Bundler.definition.sources.any? { |s| !s.is_a?(Source::Rubygems) } && !Bundler.settings[:cache_all]
+      if Bundler.definition.has_local_dependencies? && !Bundler.settings[:cache_all]
         Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want "    \
           "to package them as well, please pass the --all flag. This will be the default " \
           "on Bundler 2.0."
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index d843c00..0885394 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -5,8 +5,7 @@ module Bundler
   class Definition
     include GemHelpers
 
-    attr_reader :dependencies, :platforms, :sources, :ruby_version,
-      :locked_deps
+    attr_reader :dependencies, :platforms, :ruby_version, :locked_deps
 
     # Given a gemfile and lockfile creates a Bundler definition
     #
@@ -40,7 +39,7 @@ module Bundler
     #
     # @param lockfile [Pathname] Path to Gemfile.lock
     # @param dependencies [Array(Bundler::Dependency)] array of dependencies from Gemfile
-    # @param sources [Array(Bundler::Source::Rubygems)]
+    # @param sources [Bundler::SourceList]
     # @param unlock [Hash, Boolean, nil] Gems that have been requested
     #   to be updated or true if all gems should be updated
     # @param ruby_version [Bundler::RubyVersion, nil] Requested Ruby Version
@@ -111,14 +110,14 @@ module Bundler
 
     def resolve_with_cache!
       raise "Specs already loaded" if @specs
-      @sources.each { |s| s.cached! }
+      sources.cached!
       specs
     end
 
     def resolve_remotely!
       raise "Specs already loaded" if @specs
       @remote = true
-      @sources.each { |s| s.remote! }
+      sources.remote!
       specs
     end
 
@@ -190,15 +189,6 @@ module Bundler
         else
           last_resolve = converge_locked_specs
 
-          # Record the specs available in each gem's source, so that those
-          # specs will be available later when the resolver knows where to
-          # look for that gemspec (or its dependencies)
-          source_requirements = {}
-          dependencies.each do |dep|
-            next unless dep.source
-            source_requirements[dep.name] = dep.source.specs
-          end
-
           # Run a resolve against the locally available gems
           last_resolve.merge Resolver.resolve(expanded_dependencies, index, source_requirements, last_resolve)
         end
@@ -210,15 +200,10 @@ module Bundler
         dependency_names = @dependencies.dup || []
         dependency_names.map! {|d| d.name }
 
-        @sources.each do |s|
-          if s.is_a?(Bundler::Source::Rubygems)
-            s.dependency_names = dependency_names.uniq
-            idx.add_source s.specs
-          else
-            source_index = s.specs
-            dependency_names += source_index.unmet_dependency_names
-            idx.add_source source_index
-          end
+        sources.all_sources.each do |s|
+          s.dependency_names = dependency_names
+          idx.add_source s.specs
+          dependency_names.push(*s.unmet_deps).uniq!
         end
       end
     end
@@ -227,13 +212,22 @@ module Bundler
     # spec, even if (say) a git gem is not checked out.
     def rubygems_index
       @rubygems_index ||= Index.build do |idx|
-        rubygems = @sources.find{|s| s.is_a?(Source::Rubygems) }
-        idx.add_source rubygems.specs
+        sources.rubygems_sources.each do |rubygems|
+          idx.add_source rubygems.specs
+        end
       end
     end
 
-    def rubygems_remotes
-      @sources.select{|s| s.is_a?(Source::Rubygems) }.map{|s| s.remotes }.flatten
+    def has_rubygems_remotes?
+      sources.rubygems_sources.any? {|s| s.remotes.any? }
+    end
+
+    def has_local_dependencies?
+      !sources.path_sources.empty? || !sources.git_sources.empty?
+    end
+
+    def spec_git_paths
+      sources.git_sources.map {|s| s.path.to_s }
     end
 
     def groups
@@ -265,12 +259,12 @@ module Bundler
     def to_lock
       out = ""
 
-      sorted_sources.each do |source|
+      sources.lock_sources.each do |source|
         # Add the source header
         out << source.to_lock
         # Find all specs for this source
         resolve.
-          select  { |s| s.source == source }.
+          select { |s| source.can_lock?(s) }.
           # This needs to be sorted by full name so that
           # gems with the same name, but different platform
           # are ordered consistently
@@ -319,9 +313,10 @@ module Bundler
       deleted = []
       changed = []
 
-      if @locked_sources != @sources
-        new_sources = @sources - @locked_sources
-        deleted_sources = @locked_sources - @sources
+      gemfile_sources = sources.all_sources
+      if @locked_sources != gemfile_sources
+        new_sources = gemfile_sources - @locked_sources
+        deleted_sources = @locked_sources - gemfile_sources
 
         if new_sources.any?
           added.concat new_sources.map { |source| "* source: #{source}" }
@@ -393,6 +388,8 @@ module Bundler
 
   private
 
+    attr_reader :sources
+
     def nothing_changed?
       !@source_changes && !@dependency_changes && !@new_platform && !@path_changes && !@local_changes
     end
@@ -441,8 +438,7 @@ module Bundler
     end
 
     def converge_paths
-      @sources.any? do |source|
-        next unless source.instance_of?(Source::Path)
+      sources.path_sources.any? do |source|
         specs_changed?(source) do |ls|
           ls.class == source.class && ls.path == source.path
         end
@@ -452,27 +448,28 @@ module Bundler
     def converge_sources
       changes = false
 
-      # Get the Rubygems source from the Gemfile.lock
-      locked_gem = @locked_sources.find { |s| s.kind_of?(Source::Rubygems) }
-
-      # Get the Rubygems source from the Gemfile
-      actual_gem = @sources.find { |s| s.kind_of?(Source::Rubygems) }
+      # Get the Rubygems sources from the Gemfile.lock
+      locked_gem_sources = @locked_sources.select { |s| s.kind_of?(Source::Rubygems) }
+      # Get the Rubygems sources from the Gemfile
+      actual_gem_sources = @sources.rubygems_sources
 
       # If there is a Rubygems source in both
-      if locked_gem && actual_gem
-        # Merge the remotes from the Gemfile into the Gemfile.lock
-        changes = changes | locked_gem.replace_remotes(actual_gem)
+      unless locked_gem_sources.empty? && actual_gem_sources.empty?
+        actual_remotes = actual_gem_sources.map(&:remotes).flatten.uniq
+        locked_gem_sources.each do |locked_gem|
+          # Merge the remotes from the Gemfile into the Gemfile.lock
+          changes = changes | locked_gem.replace_remotes(actual_remotes)
+        end
       end
 
       # Replace the sources from the Gemfile with the sources from the Gemfile.lock,
       # if they exist in the Gemfile.lock and are `==`. If you can't find an equivalent
       # source in the Gemfile.lock, use the one from the Gemfile.
-      @sources.map! do |source|
-        @locked_sources.find { |s| s == source } || source
-      end
-      changes = changes | (Set.new(@sources) != Set.new(@locked_sources))
+      sources.replace_sources!(@locked_sources)
+      gemfile_sources = sources.all_sources
+      changes = changes | (Set.new(gemfile_sources) != Set.new(@locked_sources))
 
-      @sources.each do |source|
+      gemfile_sources.each do |source|
         # If the source is unlockable and the current command allows an unlock of
         # the source (for example, you are doing a `bundle update <foo>` of a git-pinned
         # gem), unlock it. For git sources, this means to unlock the revision, which
@@ -490,7 +487,7 @@ module Bundler
     def converge_dependencies
       (@dependencies + @locked_deps).each do |dep|
         if dep.source
-          dep.source = @sources.find { |s| dep.source == s }
+          dep.source = sources.get(dep.source)
         end
       end
       Set.new(@dependencies) != Set.new(@locked_deps)
@@ -524,7 +521,7 @@ module Bundler
 
       converged = []
       @locked_specs.each do |s|
-        s.source = @sources.find { |src| s.source == src }
+        s.source = sources.get(s.source)
 
         # Don't add a spec to the list if its source is expired. For example,
         # if you change a Git gem to Rubygems.
@@ -553,7 +550,7 @@ module Bundler
       diff    = @locked_specs.to_a - resolve.to_a
 
       # Now, we unlock any sources that do not have anymore gems pinned to it
-      @sources.each do |source|
+      sources.all_sources.each do |source|
         next unless source.respond_to?(:unlock!)
 
         unless resolve.any? { |s| s.source == source }
@@ -580,6 +577,7 @@ module Bundler
       deps = []
       dependencies.each do |dep|
         dep = Dependency.new(dep, ">= 0") unless dep.respond_to?(:name)
+        next unless remote || dep.current_platform?
         dep.gem_platforms(@platforms).each do |p|
           deps << DepProxy.new(dep, p) if remote || p == generic(Gem::Platform.local)
         end
@@ -587,17 +585,26 @@ module Bundler
       deps
     end
 
-    def sorted_sources
-      @sources.sort_by do |s|
-        # Place GEM at the top
-        [ s.is_a?(Source::Rubygems) ? 1 : 0, s.to_s ]
-      end
-    end
-
     def requested_dependencies
       groups = self.groups - Bundler.settings.without
       groups.map! { |g| g.to_sym }
       dependencies.reject { |d| !d.should_include? || (d.groups & groups).empty? }
     end
+
+    def source_requirements
+      # Load all specs from remote sources
+      index
+
+      # Record the specs available in each gem's source, so that those
+      # specs will be available later when the resolver knows where to
+      # look for that gemspec (or its dependencies)
+      source_requirements = {}
+      dependencies.each do |dep|
+        next unless dep.source
+        source_requirements[dep.name] = dep.source.specs
+      end
+      source_requirements
+    end
+
   end
 end
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 5a985a6..ef5c6fb 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -17,7 +17,7 @@ module Bundler
 
     def initialize
       @source          = nil
-      @sources         = []
+      @sources         = SourceList.new
       @git_sources     = {}
       @dependencies    = []
       @groups          = []
@@ -27,10 +27,6 @@ module Bundler
       add_github_sources
     end
 
-    def rubygems_source
-      @rubygems_source ||= Source::Rubygems.new
-    end
-
     def eval_gemfile(gemfile, contents = nil)
       contents ||= Bundler.read_file(gemfile.to_s)
       instance_eval(contents, gemfile.to_s, 1)
@@ -70,12 +66,8 @@ module Bundler
     end
 
     def gem(name, *args)
-      if name.is_a?(Symbol)
-        raise GemfileError, %{You need to specify gem names as Strings. Use 'gem "#{name.to_s}"' instead.}
-      end
-
       options = args.last.is_a?(Hash) ? args.pop.dup : {}
-      version = args
+      version = args || [">= 0"]
 
       normalize_options(name, version, options)
 
@@ -115,30 +107,13 @@ module Bundler
       @dependencies << dep
     end
 
-    def source(source, options = {})
-      case source
-      when :gemcutter, :rubygems, :rubyforge then
-        Bundler.ui.warn "The source :#{source} is deprecated because HTTP " \
-          "requests are insecure.\nPlease change your source to 'https://" \
-          "rubygems.org' if possible, or 'http://rubygems.org' if not."
-        rubygems_source.add_remote "http://rubygems.org"
-        return
-      when String
-        rubygems_source.add_remote source
-        return
+    def source(source, &blk)
+      source = normalize_source(source)
+      if block_given?
+        with_source(@sources.add_rubygems_source("remotes" => source), &blk)
       else
-        @source = source
-        if options[:prepend]
-          @sources = [@source] | @sources
-        else
-          @sources = @sources | [@source]
-        end
-
-        yield if block_given?
-        return @source
+        @sources.add_rubygems_remote(source)
       end
-    ensure
-      @source = nil
     end
 
     def git_source(name, &block)
@@ -154,11 +129,11 @@ module Bundler
       @git_sources[name.to_s] = block
     end
 
-    def path(path, options = {}, source_options = {}, &blk)
-      source Source::Path.new(normalize_hash(options).merge("path" => Pathname.new(path))), source_options, &blk
+    def path(path, options = {}, &blk)
+      with_source(@sources.add_path_source(normalize_hash(options).merge("path" => Pathname.new(path))), &blk)
     end
 
-    def git(uri, options = {}, source_options = {}, &blk)
+    def git(uri, options = {}, &blk)
       unless block_given?
         msg = "You can no longer specify a git source by itself. Instead, \n" \
               "either use the :git option on a gem, or specify the gems that \n" \
@@ -170,11 +145,10 @@ module Bundler
         raise DeprecatedError, msg
       end
 
-      source Source::Git.new(normalize_hash(options).merge("uri" => uri)), source_options, &blk
+      with_source(@sources.add_git_source(normalize_hash(options).merge("uri" => uri)), &blk)
     end
 
     def to_definition(lockfile, unlock)
-      @sources << rubygems_source unless @sources.include?(rubygems_source)
       Definition.new(lockfile, @dependencies, @sources, unlock, @ruby_version)
     end
 
@@ -217,6 +191,16 @@ module Bundler
       git_source(:gist){ |repo_name| "https://gist.github.com/#{repo_name}.git" }
     end
 
+    def with_source(source)
+      if block_given?
+        @source = source
+        yield
+      end
+      source
+    ensure
+      @source = nil
+    end
+
     def normalize_hash(opts)
       opts.keys.each do |k|
         opts[k.to_s] = opts.delete(k) unless k.is_a?(String)
@@ -225,10 +209,14 @@ module Bundler
     end
 
     def valid_keys
-      @valid_keys ||= %w(group groups git path name branch ref tag require submodules platform platforms type)
+      @valid_keys ||= %w(group groups git path name branch ref tag require submodules platform platforms type source)
     end
 
     def normalize_options(name, version, opts)
+      if name.is_a?(Symbol)
+        raise GemfileError, %{You need to specify gem names as Strings. Use 'gem "#{name.to_s}"' instead.}
+      end
+
       normalize_hash(opts)
 
       git_names = @git_sources.keys.map(&:to_s)
@@ -260,6 +248,12 @@ module Bundler
         raise GemfileError, "`#{p}` is not a valid platform. The available options are: #{VALID_PLATFORMS.inspect}"
       end
 
+      # Save sources passed in a key
+      if opts.has_key?("source")
+        source = normalize_source(opts["source"])
+        opts["source"] = @sources.add_rubygems_source("remotes" => source)
+      end
+
       git_name = (git_names & opts.keys).last
       if @git_sources[git_name]
         opts["git"] = @git_sources[git_name].call(opts[git_name])
@@ -272,7 +266,7 @@ module Bundler
           else
             options = opts.dup
           end
-          source = send(type, param, options, :prepend => true) {}
+          source = send(type, param, options) {}
           opts["source"] = source
         end
       end
@@ -283,5 +277,18 @@ module Bundler
       opts["group"]     = groups
     end
 
+    def normalize_source(source)
+      case source
+      when :gemcutter, :rubygems, :rubyforge
+        Bundler.ui.warn "The source :#{source} is deprecated because HTTP " \
+          "requests are insecure.\nPlease change your source to 'https://" \
+          "rubygems.org' if possible, or 'http://rubygems.org' if not."
+        "http://rubygems.org"
+      when String
+        source
+      else
+        raise GemfileError, "Unknown source '#{source}'"
+      end
+    end
   end
 end
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb
index e503fa2..8c8c868 100644
--- a/lib/bundler/fetcher.rb
+++ b/lib/bundler/fetcher.rb
@@ -91,47 +91,43 @@ module Bundler
     end
 
     def initialize(remote_uri)
-
-      # How many redirects to allew in one request
-      @redirect_limit = 5
-      # How long to wait for each gemcutter API call
-      @api_timeout = 10
-      # How many retries for the gemcutter API call
-      @max_retries = 3
+      @redirect_limit = 5  # How many redirects to allow in one request
+      @api_timeout    = 10 # How long to wait for each API call
+      @max_retries    = 3  # How many retries for the API call
 
       @remote_uri = Bundler::Source.mirror_for(remote_uri)
       @public_uri = @remote_uri.dup
       @public_uri.user, @public_uri.password = nil, nil # don't print these
 
       Socket.do_not_reverse_lookup = true
+      connection # create persistent connection
     end
 
     def connection
-      return @connection if @connection
-
-      needs_ssl = @remote_uri.scheme == "https" ||
-        Bundler.settings[:ssl_verify_mode] ||
-        Bundler.settings[:ssl_client_cert]
-      raise SSLError if needs_ssl && !defined?(OpenSSL)
-
-      @connection = Net::HTTP::Persistent.new 'bundler', :ENV
+      @connection ||= begin
+        needs_ssl = @remote_uri.scheme == "https" ||
+          Bundler.settings[:ssl_verify_mode] ||
+          Bundler.settings[:ssl_client_cert]
+        raise SSLError if needs_ssl && !defined?(OpenSSL::SSL)
+
+        con = Net::HTTP::Persistent.new 'bundler', :ENV
+
+        if @remote_uri.scheme == "https"
+          con.verify_mode = (Bundler.settings[:ssl_verify_mode] ||
+            OpenSSL::SSL::VERIFY_PEER)
+          con.cert_store = bundler_cert_store
+        end
 
-      if @remote_uri.scheme == "https"
-        @connection.verify_mode = (Bundler.settings[:ssl_verify_mode] ||
-          OpenSSL::SSL::VERIFY_PEER)
-        @connection.cert_store = bundler_cert_store
-      end
+        if Bundler.settings[:ssl_client_cert]
+          pem = File.read(Bundler.settings[:ssl_client_cert])
+          con.cert = OpenSSL::X509::Certificate.new(pem)
+          con.key  = OpenSSL::PKey::RSA.new(pem)
+        end
 
-      if Bundler.settings[:ssl_client_cert]
-        pem = File.read(Bundler.settings[:ssl_client_cert])
-        @connection.cert = OpenSSL::X509::Certificate.new(pem)
-        @connection.key  = OpenSSL::PKey::RSA.new(pem)
+        con.read_timeout = @api_timeout
+        con.override_headers["User-Agent"] = self.class.user_agent
+        con
       end
-
-      @connection.read_timeout = @api_timeout
-      @connection.override_headers["User-Agent"] = self.class.user_agent
-
-      @connection
     end
 
     def uri
@@ -165,6 +161,7 @@ module Bundler
 
     # return the specs in the bundler format as an index
     def specs(gem_names, source)
+      old = Bundler.rubygems.sources
       index = Index.new
 
       if gem_names && use_api
@@ -197,6 +194,8 @@ module Bundler
     rescue CertificateFailureError => e
       Bundler.ui.info "" if gem_names && use_api # newline after dots
       raise e
+    ensure
+      Bundler.rubygems.sources = old
     end
 
     # fetch index
@@ -255,9 +254,10 @@ module Bundler
       raise HTTPError, "Too many redirects" if counter >= @redirect_limit
 
       response = request(uri)
+      Bundler.ui.debug("HTTP #{response.code} #{response.message}")
+
       case response
       when Net::HTTPRedirection
-        Bundler.ui.debug("HTTP Redirection")
         new_uri = URI.parse(response["location"])
         if new_uri.host == uri.host
           new_uri.user = uri.user
@@ -265,7 +265,6 @@ module Bundler
         end
         fetch(new_uri, counter + 1)
       when Net::HTTPSuccess
-        Bundler.ui.debug("HTTP Success")
         response.body
       when Net::HTTPRequestEntityTooLarge
         raise FallbackError, response.body
@@ -275,7 +274,7 @@ module Bundler
     end
 
     def request(uri)
-      Bundler.ui.debug "Fetching from: #{uri}"
+      Bundler.ui.debug "HTTP GET #{uri}"
       req = Net::HTTP::Get.new uri.request_uri
       if uri.user
         user = CGI.unescape(uri.user)
@@ -287,14 +286,15 @@ module Bundler
       retry_with_auth { request(uri) }
     rescue OpenSSL::SSL::SSLError
       raise CertificateFailureError.new(uri)
-    rescue *HTTP_ERRORS
+    rescue *HTTP_ERRORS => e
+      Bundler.ui.trace e
       raise HTTPError, "Network error while fetching #{uri}"
     end
 
     def dependency_api_uri(gem_names = [])
-      url = "#{redirected_uri}api/v1/dependencies"
-      url << "?gems=#{URI.encode(gem_names.join(","))}" if gem_names.any?
-      URI.parse(url)
+      uri = fetch_uri + "api/v1/dependencies"
+      uri.query = "gems=#{URI.encode(gem_names.join(","))}" if gem_names.any?
+      uri
     end
 
     # fetch from Gemcutter Dependency Endpoint API
@@ -319,7 +319,8 @@ module Bundler
 
     # fetch from modern index: specs.4.8.gz
     def fetch_all_remote_specs
-      Bundler.rubygems.sources = ["#{@remote_uri}"]
+      old_sources = Bundler.rubygems.sources
+      Bundler.rubygems.sources = [@remote_uri.to_s]
       Bundler.rubygems.fetch_all_remote_specs
     rescue Gem::RemoteFetcher::FetchError, OpenSSL::SSL::SSLError => e
       case e.message
@@ -333,6 +334,8 @@ module Bundler
         Bundler.ui.trace e
         raise HTTPError, "Could not fetch specs from #{uri}"
       end
+    ensure
+      Bundler.rubygems.sources = old_sources
     end
 
     def well_formed_dependency(name, *requirements)
@@ -378,18 +381,18 @@ module Bundler
       yield
     end
 
-    private
-    def redirected_uri
-      return bundler_uri if rubygems?
-      return @remote_uri
-    end
-
-    def rubygems?
-      @remote_uri.host == "rubygems.org"
-    end
+  private
 
-    def bundler_uri
-      URI.parse("#{@remote_uri.scheme}://bundler.#{@remote_uri.host}/")
+    def fetch_uri
+      @fetch_uri ||= begin
+        if @remote_uri.host == "rubygems.org"
+          uri = @remote_uri.dup
+          uri.host = "bundler.rubygems.org"
+          uri
+        else
+          @remote_uri
+        end
+      end
     end
 
   end
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index 493ac8f..104bf44 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -10,13 +10,14 @@ module Bundler
       i
     end
 
-    attr_reader :specs, :sources
-    protected   :specs
+    attr_reader :specs, :all_specs, :sources
+    protected   :specs, :all_specs
 
     def initialize
       @sources = []
       @cache = {}
       @specs = Hash.new { |h,k| h[k] = [] }
+      @all_specs = Hash.new { |h,k| h[k] = [] }
     end
 
     def initialize_copy(o)
@@ -24,10 +25,14 @@ module Bundler
       @sources = @sources.dup
       @cache = {}
       @specs = Hash.new { |h,k| h[k] = [] }
+      @all_specs = Hash.new { |h,k| h[k] = [] }
 
       o.specs.each do |name, array|
         @specs[name] = array.dup
       end
+      o.all_specs.each do |name, array|
+        @all_specs[name] = array.dup
+      end
     end
 
     def inspect
@@ -39,6 +44,14 @@ module Bundler
       true
     end
 
+    def search_all(name)
+      all_matches = @all_specs[name] + local_search(name)
+      @sources.each do |source|
+        all_matches.concat(source.search_all(name))
+      end
+      all_matches
+    end
+
     # Search this index's specs, and any source indexes that this index knows
     # about, returning all of the results.
     def search(query, base = nil)
@@ -55,7 +68,7 @@ module Bundler
         end
       end
 
-      results
+      results.sort_by {|s| [s.version, s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s] }
     end
 
     def local_search(query, base = nil)
@@ -93,18 +106,18 @@ module Bundler
 
     # returns a list of the dependencies
     def unmet_dependency_names
-      dependency_names = specs.values.map do |array_of_s|
-        array_of_s.map do |s|
-          s.dependencies.map{|d| d.name }
-        end
-      end.flatten.uniq
-      dependency_names.select{|name| name != 'bundler' && specs_by_name(name).empty? }
+      names = []
+      each{|s| names.push *s.dependencies.map{|d| d.name } }
+      names.uniq!
+      names.delete_if{|n| n == "bundler" }
+      names.select{|n| search(n).empty? }
     end
 
     def use(other, override_dupes = false)
       return unless other
       other.each do |s|
         if (dupes = search_by_spec(s)) && dupes.any?
+          @all_specs[s.name] = [s] + dupes
           next unless override_dupes
           @specs[s.name] -= dupes
         end
@@ -160,7 +173,7 @@ module Bundler
           found.reject! { |spec| spec.version.prerelease? }
         end
 
-        found.sort_by {|s| [s.version, s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s] }
+        found
       end
     end
 
diff --git a/lib/bundler/installer.rb b/lib/bundler/installer.rb
index fe03b61..a4747c6 100644
--- a/lib/bundler/installer.rb
+++ b/lib/bundler/installer.rb
@@ -5,7 +5,10 @@ require 'bundler/parallel_workers'
 module Bundler
   class Installer < Environment
     class << self
-      attr_accessor :post_install_messages
+      attr_accessor :post_install_messages, :ambiguous_gems
+
+      Installer.post_install_messages = {}
+      Installer.ambiguous_gems = []
     end
 
     # Begins the installation process for Bundler.
@@ -75,10 +78,6 @@ module Bundler
       unless local
         options["local"] ? @definition.resolve_with_cache! : @definition.resolve_remotely!
       end
-      # Must install gems in the order that the resolver provides
-      # as dependencies might actually affect the installation of
-      # the gem.
-      Installer.post_install_messages = {}
 
       # the order that the resolver provides is significant, since
       # dependencies might actually affect the installation of a gem.
@@ -119,6 +118,9 @@ module Bundler
       end
 
       post_install_message
+    rescue Errno::ENOSPC
+      raise Bundler::InstallError, "Your disk is out of space. Free some " \
+        "space to be able to install your bundle."
     rescue Exception => e
       # if install hook failed or gem signature is bad, just die
       raise e if e.is_a?(Bundler::InstallHookError) || e.is_a?(Bundler::SecurityError)
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index 01fa863..32eb43a 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -29,6 +29,8 @@ module Bundler
       @state        = :source
       @specs        = {}
 
+      @rubygems_aggregate = Source::Rubygems.new
+
       if lockfile.match(/<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|/)
         raise LockfileError, "Your Gemfile.lock contains merge conflicts.\n" \
           "Run `git checkout HEAD -- Gemfile.lock` first to get a clean lock."
@@ -43,6 +45,7 @@ module Bundler
           send("parse_#{@state}", line)
         end
       end
+      @sources << @rubygems_aggregate
       @specs = @specs.values
     end
 
@@ -60,14 +63,24 @@ module Bundler
         @current_source = nil
         @opts, @type = {}, line
       when SPECS
-        @current_source = TYPES[@type].from_lock(@opts)
-
-        # Strip out duplicate GIT sections
-        if @sources.include?(@current_source) && @current_source.is_a?(Bundler::Source::Git)
-          @current_source = @sources.find { |s| s == @current_source }
+        case @type
+        when "PATH"
+          @current_source = TYPES[@type].from_lock(@opts)
+          @sources << @current_source
+        when "GIT"
+          @current_source = TYPES[@type].from_lock(@opts)
+          # Strip out duplicate GIT sections
+          if @type == "GIT" && @sources.include?(@current_source)
+            @current_source = @sources.find { |s| s == @current_source }
+          else
+            @sources << @current_source
+          end
+        when "GEM"
+          Array(@opts["remote"]).each do |url|
+            @rubygems_aggregate.add_remote(url)
+          end
+          @current_source = @rubygems_aggregate
         end
-
-        @sources << @current_source
       when OPTIONS
         value = $2
         value = true if value == "true"
diff --git a/lib/bundler/man/bundle b/lib/bundler/man/bundle
index f90637c..e38502c 100644
--- a/lib/bundler/man/bundle
+++ b/lib/bundler/man/bundle
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE" "1" "December 2013" "" ""
+.TH "BUNDLE" "1" "July 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\fR \- Ruby Dependency Management
diff --git a/lib/bundler/man/bundle-config b/lib/bundler/man/bundle-config
index d385df7..4006f39 100644
--- a/lib/bundler/man/bundle-config
+++ b/lib/bundler/man/bundle-config
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE\-CONFIG" "1" "June 2014" "" ""
+.TH "BUNDLE\-CONFIG" "1" "August 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\-config\fR \- Set bundler configuration options
diff --git a/lib/bundler/man/bundle-config.txt b/lib/bundler/man/bundle-config.txt
index f422efe..080fcf8 100644
--- a/lib/bundler/man/bundle-config.txt
+++ b/lib/bundler/man/bundle-config.txt
@@ -186,4 +186,4 @@ MIRRORS OF GEM REPOSITORIES
 
 
 
-				   June 2014		      BUNDLE-CONFIG(1)
+				  August 2014		      BUNDLE-CONFIG(1)
diff --git a/lib/bundler/man/bundle-exec b/lib/bundler/man/bundle-exec
index db6f347..41a8e5c 100644
--- a/lib/bundler/man/bundle-exec
+++ b/lib/bundler/man/bundle-exec
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE\-EXEC" "1" "December 2013" "" ""
+.TH "BUNDLE\-EXEC" "1" "July 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\-exec\fR \- Execute a command in the context of the bundle
diff --git a/lib/bundler/man/bundle-exec.txt b/lib/bundler/man/bundle-exec.txt
index 4cfc0eb..6fb3533 100644
--- a/lib/bundler/man/bundle-exec.txt
+++ b/lib/bundler/man/bundle-exec.txt
@@ -160,4 +160,4 @@ RUBYGEMS PLUGINS
 
 
 
-				 December 2013			BUNDLE-EXEC(1)
+				   July 2014			BUNDLE-EXEC(1)
diff --git a/lib/bundler/man/bundle-install b/lib/bundler/man/bundle-install
index 818e1dd..f6bafdf 100644
--- a/lib/bundler/man/bundle-install
+++ b/lib/bundler/man/bundle-install
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE\-INSTALL" "1" "June 2014" "" ""
+.TH "BUNDLE\-INSTALL" "1" "July 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\-install\fR \- Install the dependencies specified in your Gemfile
@@ -81,7 +81,7 @@ Make a bundle that can work without Ruby Gems or Bundler at runtime\. It takes a
 .
 .TP
 \fB\-\-trust\-policy=[<policy>]\fR
-Apply the Rubygems security policy named \fIpolicy\fR, where policy is one of HighSecurity, MediumSecurity, LowSecurity, or NoSecurity\. For more detail, see the Rubygems signing documentation, linked below in \fISEE ALSO\fR\.
+Apply the Rubygems security policy named \fIpolicy\fR, where policy is one of HighSecurity, MediumSecurity, LowSecurity, AlmostNoSecurity, or NoSecurity\. For more detail, see the Rubygems signing documentation, linked below in \fISEE ALSO\fR\.
 .
 .TP
 \fB\-\-jobs=[<size>]\fR
@@ -334,10 +334,10 @@ To explicitly update \fBactionpack\fR, including its dependencies which other ge
 .SH "SEE ALSO"
 .
 .IP "\(bu" 4
-Gem install docs: http://docs\.rubygems\.org/read/chapter/2
+Gem install docs: http://guides\.rubygems\.org/rubygems\-basics/#installing\-gems
 .
 .IP "\(bu" 4
-Rubygems signing docs: http://docs\.rubygems\.org/read/chapter/21
+Rubygems signing docs: http://guides\.rubygems\.org/security/
 .
 .IP "" 0
 
diff --git a/lib/bundler/man/bundle-install.txt b/lib/bundler/man/bundle-install.txt
index fc3e2e6..735d965 100644
--- a/lib/bundler/man/bundle-install.txt
+++ b/lib/bundler/man/bundle-install.txt
@@ -98,9 +98,9 @@ OPTIONS
 
        --trust-policy=[<policy>]
 	      Apply the Rubygems security policy named policy, where policy is
-	      one of HighSecurity, MediumSecurity, LowSecurity, or NoSecurity.
-	      For  more detail, see the Rubygems signing documentation, linked
-	      below in SEE ALSO.
+	      one of HighSecurity, MediumSecurity, LowSecurity,  AlmostNoSecu-
+	      rity,  or  NoSecurity. For more detail, see the Rubygems signing
+	      documentation, linked below in SEE ALSO.
 
        --jobs=[<size>]
 	      Install gems parallely by starting size number of parallel work-
@@ -387,13 +387,14 @@ CONSERVATIVE UPDATING
        not work, run bundle update(1) bundle-update.1.html.
 
 SEE ALSO
-       o   Gem install docs: http://docs.rubygems.org/read/chapter/2
+       o   Gem				install 			 docs:
+	   http://guides.rubygems.org/rubygems-basics/#installing-gems
 
-       o   Rubygems signing docs: http://docs.rubygems.org/read/chapter/21
+       o   Rubygems signing docs: http://guides.rubygems.org/security/
 
 
 
 
 
 
-				   June 2014		     BUNDLE-INSTALL(1)
+				   July 2014		     BUNDLE-INSTALL(1)
diff --git a/lib/bundler/man/bundle-package b/lib/bundler/man/bundle-package
index fdff21f..f84a266 100644
--- a/lib/bundler/man/bundle-package
+++ b/lib/bundler/man/bundle-package
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE\-PACKAGE" "1" "November 2013" "" ""
+.TH "BUNDLE\-PACKAGE" "1" "July 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\-package\fR \- Package your needed \fB\.gem\fR files into your application
diff --git a/lib/bundler/man/bundle-package.txt b/lib/bundler/man/bundle-package.txt
index b716edb..f33d6a6 100644
--- a/lib/bundler/man/bundle-package.txt
+++ b/lib/bundler/man/bundle-package.txt
@@ -64,4 +64,4 @@ REMOTE FETCHING
 
 
 
-				 November 2013		     BUNDLE-PACKAGE(1)
+				   July 2014		     BUNDLE-PACKAGE(1)
diff --git a/lib/bundler/man/bundle-platform b/lib/bundler/man/bundle-platform
index f909b5e..a42b782 100644
--- a/lib/bundler/man/bundle-platform
+++ b/lib/bundler/man/bundle-platform
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE\-PLATFORM" "1" "November 2013" "" ""
+.TH "BUNDLE\-PLATFORM" "1" "July 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\-platform\fR \- Displays platform compatibility information
diff --git a/lib/bundler/man/bundle-platform.txt b/lib/bundler/man/bundle-platform.txt
index 850bb40..9fd289b 100644
--- a/lib/bundler/man/bundle-platform.txt
+++ b/lib/bundler/man/bundle-platform.txt
@@ -54,4 +54,4 @@ OPTIONS
 
 
 
-				 November 2013		    BUNDLE-PLATFORM(1)
+				   July 2014		    BUNDLE-PLATFORM(1)
diff --git a/lib/bundler/man/bundle-update b/lib/bundler/man/bundle-update
index e74e5b0..ee87020 100644
--- a/lib/bundler/man/bundle-update
+++ b/lib/bundler/man/bundle-update
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "BUNDLE\-UPDATE" "1" "April 2014" "" ""
+.TH "BUNDLE\-UPDATE" "1" "July 2014" "" ""
 .
 .SH "NAME"
 \fBbundle\-update\fR \- Update your gems to the latest available versions
diff --git a/lib/bundler/man/bundle-update.txt b/lib/bundler/man/bundle-update.txt
index 1a3c680..66384b0 100644
--- a/lib/bundler/man/bundle-update.txt
+++ b/lib/bundler/man/bundle-update.txt
@@ -208,4 +208,4 @@ RECOMMENDED WORKFLOW
 
 
 
-				  April 2014		      BUNDLE-UPDATE(1)
+				   July 2014		      BUNDLE-UPDATE(1)
diff --git a/lib/bundler/man/bundle.txt b/lib/bundler/man/bundle.txt
index c9772af..0285d21 100644
--- a/lib/bundler/man/bundle.txt
+++ b/lib/bundler/man/bundle.txt
@@ -94,4 +94,4 @@ OBSOLETE
 
 
 
-				 December 2013			     BUNDLE(1)
+				   July 2014			     BUNDLE(1)
diff --git a/lib/bundler/man/gemfile.5 b/lib/bundler/man/gemfile.5
index 7b1dc03..e12a08d 100644
--- a/lib/bundler/man/gemfile.5
+++ b/lib/bundler/man/gemfile.5
@@ -1,7 +1,7 @@
 .\" generated with Ronn/v0.7.3
 .\" http://github.com/rtomayko/ronn/tree/0.7.3
 .
-.TH "GEMFILE" "5" "June 2014" "" ""
+.TH "GEMFILE" "5" "August 2014" "" ""
 .
 .SH "NAME"
 \fBGemfile\fR \- A format for describing gem dependencies for Ruby programs
@@ -15,22 +15,24 @@ Place the \fBGemfile\fR in the root of the directory containing the associated c
 .SH "SYNTAX"
 A \fBGemfile\fR is evaluated as Ruby code, in a context which makes available a number of methods used to describe the gem requirements\.
 .
-.SH "SOURCES (#source)"
-At the top of the \fBGemfile\fR, add one line for each \fBRubygems\fR source that might contain the gems listed in the \fBGemfile\fR\.
+.SH "GLOBAL SOURCES (#source)"
+At the top of the \fBGemfile\fR, add a line for the \fBRubygems\fR source that contains the gems listed in the \fBGemfile\fR\.
 .
 .IP "" 4
 .
 .nf
 
 source "https://rubygems\.org"
-source "http://gems\.github\.com"
 .
 .fi
 .
 .IP "" 0
 .
 .P
-Each of these _source_s \fBMUST\fR be a valid Rubygems repository\. Sources are checked for gems following the heuristics described in \fISOURCE PRIORITY\fR\.
+It is possible, but not recommended as of Bundler 1\.7, to add multiple global \fBsource\fR lines\. Each of these \fBsource\fRs \fBMUST\fR be a valid Rubygems repository\.
+.
+.P
+Sources are checked for gems following the heuristics described in \fISOURCE PRIORITY\fR\. If a gem is found in more than one global source, Bundler will print a warning after installing the gem indicating which source was used, and listing the other sources where the gem is available\. A specific source can be selected for gems that need to use a non\-standard repository, suppressing this warning, by using the \fI\fB:source\fR option\fR or a \fI\fBsource\fR block\fR\.
 .
 .SH "RUBY (#ruby)"
 If your application requires a specific Ruby version or engine, specify your requirements using the \fBruby\fR method, with the following arguments\. All parameters are \fBOPTIONAL\fR unless otherwise specified\.
@@ -306,6 +308,28 @@ gem "nokogiri",   :platforms => [:mri_18, :jruby]
 .P
 All operations involving groups (\fBbundle install\fR, \fBBundler\.setup\fR, \fBBundler\.require\fR) behave exactly the same as if any groups not matching the current platform were explicitly excluded\.
 .
+.SS "SOURCE (:source)"
+You can select an alternate Rubygems repository for a gem using the \':source\' option\.
+.
+.IP "" 4
+.
+.nf
+
+gem "some_internal_gem", :source => "https://gems\.example\.com"
+.
+.fi
+.
+.IP "" 0
+.
+.P
+This forces the gem to be loaded from this source and ignores any global sources declared at the top level of the file\. If the gem does not exist in this source, it will not be installed\.
+.
+.P
+Bundler will search for child dependencies of this gem by first looking in the source selected for the parent, but if they are not found there, it will fall back on global sources using the ordering described in \fISOURCE PRIORITY\fR\.
+.
+.P
+Selecting a specific source repository this way also suppresses the ambiguous gem warning described above in \fIGLOBAL SOURCES (#source)\fR\.
+.
 .SS "GIT (:git)"
 If necessary, you can specify that a gem is located at a particular git repository\. The repository can be public (\fBhttp://github\.com/rails/rails\.git\fR) or private (\fBgit at github\.com:rails/rails\.git\fR)\. If the repository is private, the user that you use to run \fBbundle install\fR \fBMUST\fR have the appropriate keys available in their \fB$HOME/\.ssh\fR\.
 .
@@ -438,13 +462,18 @@ gem "rails", :path => "vendor/rails"
 .
 .IP "" 0
 .
-.SH "BLOCK FORM OF GIT, PATH, GROUP and PLATFORMS"
-The \fB:git\fR, \fB:path\fR, \fB:group\fR, and \fB:platforms\fR options may be applied to a group of gems by using block form\.
+.SH "BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS"
+The \fB:source\fR, \fB:git\fR, \fB:path\fR, \fB:group\fR, and \fB:platforms\fR options may be applied to a group of gems by using block form\.
 .
 .IP "" 4
 .
 .nf
 
+source "https://gems\.example\.com" do
+  gem "some_internal_gem"
+  gem "another_internal_gem"
+end
+
 git "git://github\.com/rails/rails\.git" do
   gem "activesupport"
   gem "actionpack"
@@ -480,13 +509,13 @@ The \fBgemspec\fR method supports optional \fB:path\fR, \fB:name\fR, and \fB:dev
 When attempting to locate a gem to satisfy a gem requirement, bundler uses the following priority order:
 .
 .IP "1." 4
-The source explicitly attached to the gem (using \fB:path\fR or \fB:git\fR)
+The source explicitly attached to the gem (using \fB:source\fR, \fB:path\fR, or \fB:git\fR)
 .
 .IP "2." 4
-For implicit gems (dependencies of explicit gems), any git or path repository otherwise declared\. This results in bundler prioritizing the ActiveSupport gem from the Rails git repository over ones from \fBrubygems\.org\fR
+For implicit gems (dependencies of explicit gems), any source, git, or path repository declared on the parent\. This results in bundler prioritizing the ActiveSupport gem from the Rails git repository over ones from \fBrubygems\.org\fR
 .
 .IP "3." 4
-The sources specified via \fBsource\fR, searching each source in your \fBGemfile\fR from last added to first added\.
+The sources specified via global \fBsource\fR lines, searching each source in your \fBGemfile\fR from last added to first added\.
 .
 .IP "" 0
 
diff --git a/lib/bundler/man/gemfile.5.txt b/lib/bundler/man/gemfile.5.txt
index 2a936f7..169ea61 100644
--- a/lib/bundler/man/gemfile.5.txt
+++ b/lib/bundler/man/gemfile.5.txt
@@ -17,20 +17,27 @@ SYNTAX
        A Gemfile is evaluated as Ruby code, in a context which makes available
        a number of methods used to describe the gem requirements.
 
-SOURCES (#source)
-       At  the	top of the Gemfile, add one line for each Rubygems source that
-       might contain the gems listed in the Gemfile.
+GLOBAL SOURCES (#source)
+       At the top of the Gemfile, add a line for the Rubygems source that con-
+       tains the gems listed in the Gemfile.
 
 
 
 	   source "https://rubygems.org"
-	   source "http://gems.github.com"
 
 
 
-       Each of these _source_s MUST be a valid	Rubygems  repository.  Sources
-       are  checked for gems following the heuristics described in SOURCE PRI-
-       ORITY.
+       It is possible, but not recommended as of Bundler 1.7, to add  multiple
+       global  source  lines.  Each  of these sources MUST be a valid Rubygems
+       repository.
+
+       Sources are checked for gems  following	the  heuristics  described  in
+       SOURCE  PRIORITY.  If  a  gem  is found in more than one global source,
+       Bundler will print a warning after installing the gem indicating  which
+       source  was used, and listing the other sources where the gem is avail-
+       able. A specific source can be selected for gems that  need  to	use  a
+       non-standard repository, suppressing this warning, by using the :source
+       option or a source block.
 
 RUBY (#ruby)
        If your application requires a specific Ruby version or engine, specify
@@ -254,16 +261,38 @@ GEMS (#gem)
        Bundler.require)  behave exactly the same as if any groups not matching
        the current platform were explicitly excluded.
 
+   SOURCE (:source)
+       You can select an alternate Rubygems repository for  a  gem  using  the
+       ':source' option.
+
+
+
+	   gem "some_internal_gem", :source => "https://gems.example.com"
+
+
+
+       This  forces  the  gem  to  be  loaded from this source and ignores any
+       global sources declared at the top level of the file. If the  gem  does
+       not exist in this source, it will not be installed.
+
+       Bundler will search for child dependencies of this gem by first looking
+       in the source selected for the parent, but if they are not found there,
+       it  will  fall  back  on global sources using the ordering described in
+       SOURCE PRIORITY.
+
+       Selecting a specific source repository this  way  also  suppresses  the
+       ambiguous gem warning described above in GLOBAL SOURCES (#source).
+
    GIT (:git)
        If necessary, you can specify that a gem is located at a particular git
-       repository.	  The	    repository	     can       be	public
-       (http://github.com/rails/rails.git)	       or	       private
-       (git at github.com:rails/rails.git).  If  the  repository  is private, the
-       user that you use to run bundle install MUST have the appropriate  keys
+       repository.	 The	   repository	    can       be	public
+       (http://github.com/rails/rails.git)		or	       private
+       (git at github.com:rails/rails.git). If the  repository  is  private,  the
+       user  that you use to run bundle install MUST have the appropriate keys
        available in their $HOME/.ssh.
 
-       Git  repositories  are  specified  using the :git parameter. The group,
-       platforms, and require options are available  and  behave  exactly  the
+       Git repositories are specified using the  :git  parameter.  The	group,
+       platforms,  and	require  options  are available and behave exactly the
        same as they would for a normal gem.
 
 
@@ -272,19 +301,19 @@ GEMS (#gem)
 
 
 
-       A  git  repository  SHOULD  have  at least one file, at the root of the
-       directory containing the gem, with the extension  .gemspec.  This  file
-       MUST  contain  a  valid gem specification, as expected by the gem build
+       A git repository SHOULD have at least one file,	at  the  root  of  the
+       directory  containing  the  gem, with the extension .gemspec. This file
+       MUST contain a valid gem specification, as expected by  the  gem  build
        command.
 
-       If a git repository does not have a .gemspec, bundler will  attempt  to
+       If  a  git repository does not have a .gemspec, bundler will attempt to
        create one, but it will not contain any dependencies, executables, or C
-       extension compilation instructions. As a result, it may fail  to  prop-
+       extension  compilation  instructions. As a result, it may fail to prop-
        erly integrate into your application.
 
-       If  a  git  repository does have a .gemspec for the gem you attached it
-       to, a version specifier, if provided, means that the git repository  is
-       only  valid  if	the  .gemspec specifies a version matching the version
+       If a git repository does have a .gemspec for the gem  you  attached  it
+       to,  a version specifier, if provided, means that the git repository is
+       only valid if the .gemspec specifies a  version	matching  the  version
        specifier. If not, bundler will print a warning.
 
 
@@ -295,22 +324,22 @@ GEMS (#gem)
 
 
 
-       If a git repository does not have a .gemspec for the gem  you  attached
+       If  a  git repository does not have a .gemspec for the gem you attached
        it to, a version specifier MUST be provided. Bundler will use this ver-
        sion in the simple .gemspec it creates.
 
        Git repositories support a number of additional options.
 
        branch, tag, and ref
-	      You MUST only specify at most one of these options. The  default
+	      You  MUST only specify at most one of these options. The default
 	      is :branch => "master"
 
        submodules
-	      Specify  :submodules => true to cause bundler to expand any sub-
+	      Specify :submodules => true to cause bundler to expand any  sub-
 	      modules included in the git repository
 
-       If a git repository contains multiple .gemspecs, each  .gemspec	repre-
-       sents  a  gem located at the same place in the file system as the .gem-
+       If  a  git repository contains multiple .gemspecs, each .gemspec repre-
+       sents a gem located at the same place in the file system as  the  .gem-
        spec.
 
 
@@ -325,17 +354,17 @@ GEMS (#gem)
 
 
 
-       To install a gem located in a git repository, bundler  changes  to  the
-       directory  containing the gemspec, runs gem build name.gemspec and then
+       To  install  a  gem located in a git repository, bundler changes to the
+       directory containing the gemspec, runs gem build name.gemspec and  then
        installs the resulting gem. The gem build command, which comes standard
-       with  Rubygems,	evaluates the .gemspec in the context of the directory
+       with Rubygems, evaluates the .gemspec in the context of	the  directory
        in which it is located.
 
    GITHUB (:github)
-       If the git repository you want to use is hosted on GitHub and  is  pub-
+       If  the	git repository you want to use is hosted on GitHub and is pub-
        lic, you can use the :github shorthand to specify just the github user-
-       name and repository name (without the trailing ".git"), separated by  a
-       slash.  If  both the username and repository name are the same, you can
+       name  and repository name (without the trailing ".git"), separated by a
+       slash. If both the username and repository name are the same,  you  can
        omit one.
 
 
@@ -362,15 +391,15 @@ GEMS (#gem)
 
 
    PATH (:path)
-       You can specify that a gem is located in a particular location  on  the
+       You  can  specify that a gem is located in a particular location on the
        file system. Relative paths are resolved relative to the directory con-
        taining the Gemfile.
 
-       Similar to the semantics of the :git option, the :path option  requires
-       that  the directory in question either contains a .gemspec for the gem,
+       Similar	to the semantics of the :git option, the :path option requires
+       that the directory in question either contains a .gemspec for the  gem,
        or that you specify an explicit version that bundler should use.
 
-       Unlike :git, bundler does not compile C extensions for  gems  specified
+       Unlike  :git,  bundler does not compile C extensions for gems specified
        as paths.
 
 
@@ -379,11 +408,16 @@ GEMS (#gem)
 
 
 
-BLOCK FORM OF GIT, PATH, GROUP and PLATFORMS
-       The  :git,  :path,  :group,  and :platforms options may be applied to a
-       group of gems by using block form.
+BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS
+       The :source, :git, :path, :group, and :platforms options may be applied
+       to a group of gems by using block form.
+
 
 
+	   source "https://gems.example.com" do
+	     gem "some_internal_gem"
+	     gem "another_internal_gem"
+	   end
 
 	   git "git://github.com/rails/rails.git" do
 	     gem "activesupport"
@@ -402,45 +436,46 @@ BLOCK FORM OF GIT, PATH, GROUP and PLATFORMS
 
 
 
-       In the case of the git block form, the :ref, :branch, :tag,  and  :sub-
-       modules	options  may  be passed to the git method, and all gems in the
+       In  the	case of the git block form, the :ref, :branch, :tag, and :sub-
+       modules options may be passed to the git method, and all  gems  in  the
        block will inherit those options.
 
 GEMSPEC (#gemspec)
        If you wish to use Bundler to help install dependencies for a gem while
-       it  is being developed, use the gemspec method to pull in the dependen-
+       it is being developed, use the gemspec method to pull in the  dependen-
        cies listed in the .gemspec file.
 
        The gemspec method adds any runtime dependencies as gem requirements in
-       the  default  group.  It  also  adds  development  dependencies	as gem
-       requirements in the development group. Finally, it adds a gem  require-
+       the default  group.  It	also  adds  development  dependencies  as  gem
+       requirements  in the development group. Finally, it adds a gem require-
        ment on your project (:path => '.'). In conjunction with Bundler.setup,
        this allows you to require project files in your test code as you would
-       if  the	project  were  installed as a gem; you need not manipulate the
+       if the project were installed as a gem; you  need  not  manipulate  the
        load path manually or require project files via relative paths.
 
-       The gemspec  method  supports  optional	:path,	:name,	and  :develop-
+       The  gemspec  method  supports  optional  :path,  :name,  and :develop-
        ment_group options, which control where bundler looks for the .gemspec,
-       what named .gemspec it uses (if more than one is  present),  and  which
+       what  named  .gemspec  it uses (if more than one is present), and which
        group development dependencies are included in.
 
 SOURCE PRIORITY
-       When  attempting  to locate a gem to satisfy a gem requirement, bundler
+       When attempting to locate a gem to satisfy a gem  requirement,  bundler
        uses the following priority order:
 
-       1.  The source explicitly attached to the gem (using :path or :git)
+       1.  The source explicitly attached to the gem (using :source, :path, or
+	   :git)
 
-       2.  For implicit gems (dependencies of explicit gems), any git or  path
-	   repository otherwise declared. This results in bundler prioritizing
-	   the ActiveSupport gem from the Rails git repository over ones  from
-	   rubygems.org
+       2.  For implicit gems (dependencies of explicit gems), any source, git,
+	   or  path repository declared on the parent. This results in bundler
+	   prioritizing the ActiveSupport gem from the	Rails  git  repository
+	   over ones from rubygems.org
 
-       3.  The	sources  specified  via  source, searching each source in your
-	   Gemfile from last added to first added.
+       3.  The	sources  specified  via  global  source  lines, searching each
+	   source in your Gemfile from last added to first added.
 
 
 
 
 
 
-				   June 2014			    GEMFILE(5)
+				  August 2014			    GEMFILE(5)
diff --git a/lib/bundler/parallel_workers.rb b/lib/bundler/parallel_workers.rb
index 3071b49..b28f630 100644
--- a/lib/bundler/parallel_workers.rb
+++ b/lib/bundler/parallel_workers.rb
@@ -8,7 +8,7 @@ module Bundler
     autoload :ThreadWorker, "bundler/parallel_workers/thread_worker"
 
     def self.worker_pool(size, job)
-      if Bundler.current_ruby.mswin? || Bundler.current_ruby.jruby?
+      if Bundler.current_ruby.mswin? || Bundler.current_ruby.jruby? || Bundler.current_ruby.rbx?
         ThreadWorker.new(size, job)
       else
         UnixWorker.new(size, job)
diff --git a/lib/bundler/rubygems_integration.rb b/lib/bundler/rubygems_integration.rb
index b994f2b..e73c202 100644
--- a/lib/bundler/rubygems_integration.rb
+++ b/lib/bundler/rubygems_integration.rb
@@ -202,6 +202,10 @@ module Bundler
       fetcher.download(spec, uri, path)
     end
 
+    def security_policy_keys
+      %w{High Medium Low AlmostNo No}.map { |level| "#{level}Security" }
+    end
+
     def security_policies
       @security_policies ||= begin
         require 'rubygems/security'
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index b386271..b09a881 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -139,7 +139,7 @@ module Bundler
       gemspec_files        = Dir["#{Gem.dir}/specifications/*.gemspec"]
       spec_gem_paths       = []
       # need to keep git sources around
-      spec_git_paths       = @definition.sources.select {|s| s.is_a?(Bundler::Source::Git) }.map {|s| s.path.to_s }
+      spec_git_paths       = @definition.spec_git_paths
       spec_git_cache_dirs  = []
       spec_gem_executables = []
       spec_cache_paths     = []
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index a42bfde..04643b4 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -14,6 +14,12 @@ module Bundler
       mirrors[normalized_key] || uri
     end
 
+    attr_accessor :dependency_names
+
+    def unmet_deps
+      specs.unmet_dependency_names
+    end
+
     def version_message(spec)
       locked_spec = Bundler.locked_gems.specs.find { |s| s.name == spec.name } if Bundler.locked_gems
       locked_spec_version = locked_spec.version if locked_spec
@@ -24,5 +30,8 @@ module Bundler
       message
     end
 
+    def can_lock?(spec)
+      spec.source == self
+    end
   end
 end
diff --git a/lib/bundler/source/git.rb b/lib/bundler/source/git.rb
index ee435b8..1f720f5 100644
--- a/lib/bundler/source/git.rb
+++ b/lib/bundler/source/git.rb
@@ -79,11 +79,12 @@ module Bundler
       def install_path
         @install_path ||= begin
           git_scope = "#{base_name}-#{shortref_for_path(revision)}"
+          path = Bundler.install_path.join(git_scope)
 
-          if Bundler.requires_sudo?
+          if !path.exist? && Bundler.requires_sudo?
             Bundler.user_bundle_path.join(Bundler.ruby_scope).join(git_scope)
           else
-            Bundler.install_path.join(git_scope)
+            path
           end
         end
       end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index c80ac61..398ed60 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -103,7 +103,7 @@ module Bundler
         name
       end
 
-      private
+    private
 
       def expand(somepath)
         somepath.expand_path(Bundler.root)
diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb
index 5ca35c8..f3b8b7c 100644
--- a/lib/bundler/source/rubygems.rb
+++ b/lib/bundler/source/rubygems.rb
@@ -8,16 +8,16 @@ module Bundler
       API_REQUEST_LIMIT = 100 # threshold for switching back to the modern index instead of fetching every spec
 
       attr_reader :remotes, :caches
-      attr_accessor :dependency_names
 
       def initialize(options = {})
         @options = options
-        @remotes = (options["remotes"] || []).map { |r| normalize_uri(r) }
-        @fetchers = {}
+        @remotes = []
         @dependency_names = []
         @allow_remote = false
         @allow_cached = false
         @caches = [Bundler.app_cache, *Bundler.rubygems.gem_cache]
+
+        Array(options["remotes"] || []).reverse_each{|r| add_remote(r) }
       end
 
       def remote!
@@ -29,28 +29,32 @@ module Bundler
       end
 
       def hash
-        Rubygems.hash
+        @remotes.hash
       end
 
       def eql?(o)
-        o.is_a?(Rubygems)
+        o.is_a?(Rubygems) && remotes_equal?(o.remotes)
       end
 
       alias == eql?
 
+      def can_lock?(spec)
+        spec.source.is_a?(Rubygems)
+      end
+
       def options
         { "remotes" => @remotes.map { |r| r.to_s } }
       end
 
       def self.from_lock(options)
-        s = new(options)
-        Array(options["remote"]).each { |r| s.add_remote(r) }
-        s
+        new(options)
       end
 
       def to_lock
         out = "GEM\n"
-        out << remotes.map {|r| "  remote: #{r}\n" }.join
+        out << remotes.map { |remote|
+          "  remote: #{suppress_configured_credentials remote}\n"
+        }.join
         out << "  specs:\n"
       end
 
@@ -61,7 +65,15 @@ module Bundler
       alias_method :name, :to_s
 
       def specs
-        @specs ||= fetch_specs
+        @specs ||= begin
+          # remote_specs usually generates a way larger Index than the other
+          # sources, and large_idx.use small_idx is way faster than
+          # small_idx.use large_idx.
+          idx = @allow_remote ? remote_specs.dup : Index.new
+          idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
+          idx.use(installed_specs, :override_dupes)
+          idx
+        end
       end
 
       def install(spec)
@@ -70,6 +82,13 @@ module Bundler
         # Download the gem to get the spec, because some specs that are returned
         # by rubygems.org are broken and wrong.
         if spec.source_uri
+          # Check for this spec from other sources
+          uris = [spec.source_uri]
+          uris += source_uris_for_spec(spec)
+          uris.compact!
+          uris.uniq!
+          Installer.ambiguous_gems << [spec.name, *uris] if uris.length > 1
+
           s = Bundler.rubygems.spec_from_gem(fetch_gem(spec), Bundler.settings["trust-policy"])
           spec.__swap__(s)
         end
@@ -146,18 +165,31 @@ module Bundler
       end
 
       def add_remote(source)
-        @remotes << normalize_uri(source)
+        uri = normalize_uri(source)
+        @remotes.unshift(uri) unless @remotes.include?(uri)
       end
 
-      def replace_remotes(source)
-        return false if source.remotes == @remotes
+      def replace_remotes(other_remotes)
+        return false if other_remotes == @remotes
 
         @remotes = []
-        source.remotes.each do |r|
+        other_remotes.reverse_each do |r|
           add_remote r.to_s
         end
+      end
+
+      def unmet_deps
+        if @allow_remote && api_fetchers.any?
+          remote_specs.unmet_dependency_names
+        else
+          []
+        end
+      end
+
+    protected
 
-        true
+      def source_uris_for_spec(spec)
+        specs.search_all(spec.name).map{|s| s.source_uri }
       end
 
     private
@@ -183,18 +215,13 @@ module Bundler
         uri
       end
 
-      def fetch_specs
-        # remote_specs usually generates a way larger Index than the other
-        # sources, and large_idx.use small_idx is way faster than
-        # small_idx.use large_idx.
-        if @allow_remote
-          idx = remote_specs.dup
+      def suppress_configured_credentials(remote)
+        remote_nouser = remote.dup.tap { |uri| uri.user = uri.password = nil }.to_s
+        if remote.userinfo && remote.userinfo == Bundler.settings[remote_nouser]
+          remote_nouser
         else
-          idx = Index.new
+          remote
         end
-        idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote
-        idx.use(installed_specs, :override_dupes)
-        idx
       end
 
       def installed_specs
@@ -243,13 +270,18 @@ module Bundler
         idx
       end
 
-      def remote_specs
-        @remote_specs ||= begin
-          old = Bundler.rubygems.sources
-          idx = Index.new
+      def fetchers
+        @fetchers ||= remotes.map do |url|
+          Bundler::Fetcher.new(url)
+        end
+      end
 
-          fetchers       = remotes.map { |uri| Bundler::Fetcher.new(uri) }
-          api_fetchers   = fetchers.select { |f| f.use_api }
+      def api_fetchers
+        fetchers.select{|f| f.use_api }
+      end
+
+      def remote_specs
+        @remote_specs ||= Index.build do |idx|
           index_fetchers = fetchers - api_fetchers
 
           # gather lists from non-api sites
@@ -257,7 +289,6 @@ module Bundler
             Bundler.ui.info "Fetching source index from #{f.uri}"
             idx.use f.specs(nil, self)
           end
-          return idx if api_fetchers.empty?
 
           # because ensuring we have all the gems we need involves downloading
           # the gemspecs of those gems, if the non-api sites contain more than
@@ -271,7 +302,7 @@ module Bundler
               Bundler.ui.info "" if !Bundler.ui.debug? # new line now that the dots are over
             end
 
-            if api_fetchers.all?{|f| f.use_api }
+            if api_fetchers.any? && api_fetchers.all?{|f| f.use_api }
               # it's possible that gems from one source depend on gems from some
               # other source, so now we download gemspecs and iterate over those
               # dependencies, looking for gems we don't have info on yet.
@@ -294,10 +325,6 @@ module Bundler
               idx.use f.specs(nil, self)
             end
           end
-
-          return idx
-        ensure
-          Bundler.rubygems.sources = old
         end
       end
 
@@ -313,6 +340,11 @@ module Bundler
         # Ruby 2.0, where gemspecs are stored in specifications/default/
         spec.loaded_from && spec.loaded_from.include?("specifications/default/")
       end
+
+      def remotes_equal?(other_remotes)
+        remotes.map(&method(:suppress_configured_credentials)) == other_remotes.map(&method(:suppress_configured_credentials))
+      end
+
     end
   end
 end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
new file mode 100644
index 0000000..0d9fb51
--- /dev/null
+++ b/lib/bundler/source_list.rb
@@ -0,0 +1,80 @@
+module Bundler
+  class SourceList
+    attr_reader :path_sources,
+                :git_sources,
+                :rubygems_sources
+
+    def initialize
+      @path_sources       = []
+      @git_sources        = []
+      @rubygems_aggregate = Source::Rubygems.new
+      @rubygems_sources   = [@rubygems_aggregate]
+    end
+
+    def add_path_source(options = {})
+      add_source_to_list Source::Path.new(options), path_sources
+    end
+
+    def add_git_source(options = {})
+      add_source_to_list Source::Git.new(options), git_sources
+    end
+
+    def add_rubygems_source(options = {})
+      add_source_to_list Source::Rubygems.new(options), @rubygems_sources
+    end
+
+    def add_rubygems_remote(uri)
+      @rubygems_aggregate.add_remote(uri)
+      @rubygems_aggregate
+    end
+
+    def all_sources
+      path_sources + git_sources + rubygems_sources
+    end
+
+    def get(source)
+      source_list_for(source).find { |s| source == s }
+    end
+
+    def lock_sources
+      lock_sources = (path_sources + git_sources).sort_by(&:to_s)
+      lock_sources << combine_rubygems_sources
+    end
+
+    def replace_sources!(replacement_sources)
+      [path_sources, git_sources, rubygems_sources].each do |source_list|
+        source_list.map! do |source|
+          replacement_sources.find { |s| s == source } || source
+        end
+      end
+    end
+
+    def cached!
+      all_sources.each(&:cached!)
+    end
+
+    def remote!
+      all_sources.each(&:remote!)
+    end
+
+  private
+
+    def add_source_to_list(source, list)
+      list.unshift(source).uniq!
+      source
+    end
+
+    def source_list_for(source)
+      case source
+      when Source::Git      then git_sources
+      when Source::Path     then path_sources
+      when Source::Rubygems then rubygems_sources
+      else raise ArgumentError, "Invalid source: #{source.inspect}"
+      end
+    end
+
+    def combine_rubygems_sources
+      Source::Rubygems.new("remotes" => rubygems_sources.map(&:remotes).flatten.uniq.reverse)
+    end
+  end
+end
diff --git a/lib/bundler/templates/newgem/README.md.tt b/lib/bundler/templates/newgem/README.md.tt
index 65ee3fe..8a65988 100644
--- a/lib/bundler/templates/newgem/README.md.tt
+++ b/lib/bundler/templates/newgem/README.md.tt
@@ -6,7 +6,9 @@ TODO: Write a gem description
 
 Add this line to your application's Gemfile:
 
-    gem '<%=config[:name]%>'
+```ruby
+gem '<%=config[:name]%>'
+```
 
 And then execute:
 
diff --git a/lib/bundler/templates/newgem/gitignore.tt b/lib/bundler/templates/newgem/gitignore.tt
index 31cafb5..ae3fdc2 100644
--- a/lib/bundler/templates/newgem/gitignore.tt
+++ b/lib/bundler/templates/newgem/gitignore.tt
@@ -1,20 +1,12 @@
-*.gem
-*.rbc
-.bundle
-.config
-.yardoc
-Gemfile.lock
-InstalledFiles
-_yardoc
-coverage
-doc/
-lib/bundler/man
-pkg
-rdoc
-spec/reports
-test/tmp
-test/version_tmp
-tmp
+/.bundle/
+/.yardoc
+/Gemfile.lock
+/_yardoc/
+/coverage/
+/doc/
+/pkg/
+/spec/reports/
+/tmp/
 *.bundle
 *.so
 *.o
diff --git a/lib/bundler/templates/newgem/newgem.gemspec.tt b/lib/bundler/templates/newgem/newgem.gemspec.tt
index cc5109b..74d253e 100644
--- a/lib/bundler/templates/newgem/newgem.gemspec.tt
+++ b/lib/bundler/templates/newgem/newgem.gemspec.tt
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
   spec.require_paths = ["lib"]
 
   spec.add_development_dependency "bundler", "~> <%= Bundler::VERSION.split(".")[0..1].join(".") %>"
-  spec.add_development_dependency "rake"
+  spec.add_development_dependency "rake", "~> 10.0"
 <% if config[:ext] -%>
   spec.add_development_dependency "rake-compiler"
 <% end -%>
diff --git a/lib/bundler/ui/shell.rb b/lib/bundler/ui/shell.rb
index d2c0052..c7054e4 100644
--- a/lib/bundler/ui/shell.rb
+++ b/lib/bundler/ui/shell.rb
@@ -56,12 +56,9 @@ module Bundler
       end
 
       def trace(e, newline = nil)
+        return unless debug?
         msg = ["#{e.class}: #{e.message}", *e.backtrace].join("\n")
-        if debug?
-          tell_me(msg, nil, newline)
-        elsif @trace
-          STDERR.puts "#{msg}#{newline}"
-        end
+        tell_me(msg, nil, newline)
       end
 
       def silence
diff --git a/lib/bundler/vendored_persistent.rb b/lib/bundler/vendored_persistent.rb
index bfc69de..8ed4ce8 100644
--- a/lib/bundler/vendored_persistent.rb
+++ b/lib/bundler/vendored_persistent.rb
@@ -1,3 +1,11 @@
+# We forcibly require OpenSSL, because net/http/persistent will only autoload
+# it. On some Rubies, autoload fails but explicit require succeeds.
+begin
+  require 'openssl'
+rescue LoadError
+  # some Ruby builds don't have OpenSSL
+end
+
 vendor = File.expand_path('../vendor', __FILE__)
 $:.unshift(vendor) unless $:.include?(vendor)
 require 'net/http/persistent'
diff --git a/lib/bundler/version.rb b/lib/bundler/version.rb
index 398a662..8374d41 100644
--- a/lib/bundler/version.rb
+++ b/lib/bundler/version.rb
@@ -2,5 +2,5 @@ module Bundler
   # We're doing this because we might write tests that deal
   # with other versions of bundler and we are unsure how to
   # handle this better.
-  VERSION = "1.6.3" unless defined?(::Bundler::VERSION)
+  VERSION = "1.7.2" unless defined?(::Bundler::VERSION)
 end
diff --git a/man/bundle-install.ronn b/man/bundle-install.ronn
index 87a4d66..a444833 100644
--- a/man/bundle-install.ronn
+++ b/man/bundle-install.ronn
@@ -91,8 +91,9 @@ update process below under [CONSERVATIVE UPDATING][].
 
 * `--trust-policy=[<policy>]`:
   Apply the Rubygems security policy named <policy>, where policy is one of
-  HighSecurity, MediumSecurity, LowSecurity, or NoSecurity. For more detail,
-  see the Rubygems signing documentation, linked below in [SEE ALSO][].
+  HighSecurity, MediumSecurity, LowSecurity, AlmostNoSecurity, or NoSecurity.
+  For more detail, see the Rubygems signing documentation, linked below in
+  [SEE ALSO][].
 
 * `--jobs=[<size>]`:
   Install gems parallely by starting <size> number of parallel workers.
@@ -367,5 +368,5 @@ does not work, run [bundle update(1)][bundle-update].
 
 ## SEE ALSO
 
-* Gem install docs: http://docs.rubygems.org/read/chapter/2
-* Rubygems signing docs: http://docs.rubygems.org/read/chapter/21
+* Gem install docs: http://guides.rubygems.org/rubygems-basics/#installing-gems
+* Rubygems signing docs: http://guides.rubygems.org/security/
diff --git a/man/gemfile.5.ronn b/man/gemfile.5.ronn
index a024da7..f94273a 100644
--- a/man/gemfile.5.ronn
+++ b/man/gemfile.5.ronn
@@ -15,16 +15,23 @@ directory as the `Rakefile`.
 A `Gemfile` is evaluated as Ruby code, in a context which makes available
 a number of methods used to describe the gem requirements.
 
-## SOURCES (#source)
+## GLOBAL SOURCES (#source)
 
-At the top of the `Gemfile`, add one line for each `Rubygems` source that
-might contain the gems listed in the `Gemfile`.
+At the top of the `Gemfile`, add a line for the `Rubygems` source that contains
+the gems listed in the `Gemfile`.
 
     source "https://rubygems.org"
-    source "http://gems.github.com"
 
-Each of these _source_s `MUST` be a valid Rubygems repository. Sources are
-checked for gems following the heuristics described in [SOURCE PRIORITY][].
+It is possible, but not recommended as of Bundler 1.7, to add multiple global
+`source` lines. Each of these `source`s `MUST` be a valid Rubygems repository.
+
+Sources are checked for gems following the heuristics described in
+[SOURCE PRIORITY][]. If a gem is found in more than one global source, Bundler
+will print a warning after installing the gem indicating which source was used,
+and listing the other sources where the gem is available. A specific source can
+be selected for gems that need to use a non-standard repository, suppressing
+this warning, by using the [`:source` option](#SOURCE-source-) or a
+[`source` block](#BLOCK-FORM-OF-SOURCE-GIT-PATH-GROUP-and-PLATFORMS).
 
 ## RUBY (#ruby)
 
@@ -200,6 +207,25 @@ All operations involving groups (`bundle install`, `Bundler.setup`,
 `Bundler.require`) behave exactly the same as if any groups not
 matching the current platform were explicitly excluded.
 
+### SOURCE (:source)
+
+You can select an alternate Rubygems repository for a gem using the ':source'
+option.
+
+    gem "some_internal_gem", :source => "https://gems.example.com"
+
+This forces the gem to be loaded from this source and ignores any global sources
+declared at the top level of the file. If the gem does not exist in this source,
+it will not be installed.
+
+Bundler will search for child dependencies of this gem by first looking in the
+source selected for the parent, but if they are not found there, it will fall
+back on global sources using the ordering described in [SOURCE PRIORITY][].
+
+Selecting a specific source repository this way also suppresses the ambiguous
+gem warning described above in
+[GLOBAL SOURCES (#source)](#GLOBAL-SOURCES-source-).
+
 ### GIT (:git)
 
 If necessary, you can specify that a gem is located at a particular
@@ -298,11 +324,16 @@ gems specified as paths.
 
     gem "rails", :path => "vendor/rails"
 
-## BLOCK FORM OF GIT, PATH, GROUP and PLATFORMS
+## BLOCK FORM OF SOURCE, GIT, PATH, GROUP and PLATFORMS
 
-The `:git`, `:path`, `:group`, and `:platforms` options may be
+The `:source`, `:git`, `:path`, `:group`, and `:platforms` options may be
 applied to a group of gems by using block form.
 
+    source "https://gems.example.com" do
+      gem "some_internal_gem"
+      gem "another_internal_gem"
+    end
+
     git "git://github.com/rails/rails.git" do
       gem "activesupport"
       gem "actionpack"
@@ -346,10 +377,11 @@ dependencies are included in.
 When attempting to locate a gem to satisfy a gem requirement,
 bundler uses the following priority order:
 
-  1. The source explicitly attached to the gem (using `:path` or `:git`)
-  2. For implicit gems (dependencies of explicit gems), any git or path
-     repository otherwise declared. This results in bundler prioritizing the
+  1. The source explicitly attached to the gem (using `:source`, `:path`, or
+     `:git`)
+  2. For implicit gems (dependencies of explicit gems), any source, git, or path
+     repository declared on the parent. This results in bundler prioritizing the
      ActiveSupport gem from the Rails git repository over ones from
      `rubygems.org`
-  3. The sources specified via `source`, searching each source in your `Gemfile`
-     from last added to first added.
+  3. The sources specified via global `source` lines, searching each source in
+     your `Gemfile` from last added to first added.
diff --git a/metadata.yml b/metadata.yml
index 6c7ab8b..7669edc 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: bundler
 version: !ruby/object:Gem::Version
-  version: 1.6.3
+  version: 1.7.2
 platform: ruby
 authors:
 - André Arko
@@ -11,9 +11,23 @@ authors:
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2014-06-16 00:00:00.000000000 Z
+date: 2014-08-24 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
+  name: rdiscount
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '1.6'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '1.6'
+- !ruby/object:Gem::Dependency
   name: ronn
   requirement: !ruby/object:Gem::Requirement
     requirements:
@@ -33,14 +47,14 @@ dependencies:
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: 2.99.0.beta1
+        version: '3.0'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
     requirements:
     - - "~>"
       - !ruby/object:Gem::Version
-        version: 2.99.0.beta1
+        version: '3.0'
 description: Bundler manages an application's dependencies through its entire life,
   across many machines, systematically and repeatably
 email:
@@ -152,6 +166,7 @@ files:
 - lib/bundler/source/path.rb
 - lib/bundler/source/path/installer.rb
 - lib/bundler/source/rubygems.rb
+- lib/bundler/source_list.rb
 - lib/bundler/spec_set.rb
 - lib/bundler/ssl_certs/.document
 - lib/bundler/ssl_certs/Class3PublicPrimaryCertificationAuthority.pem
@@ -242,7 +257,8 @@ files:
 - spec/bundler/psyched_yaml_spec.rb
 - spec/bundler/retry_spec.rb
 - spec/bundler/settings_spec.rb
-- spec/bundler/source_spec.rb
+- spec/bundler/source/rubygems_spec.rb
+- spec/bundler/source_list_spec.rb
 - spec/cache/gems_spec.rb
 - spec/cache/git_spec.rb
 - spec/cache/path_spec.rb
@@ -279,6 +295,7 @@ files:
 - spec/install/gems/post_install_spec.rb
 - spec/install/gems/resolving_spec.rb
 - spec/install/gems/simple_case_spec.rb
+- spec/install/gems/sources_spec.rb
 - spec/install/gems/standalone_spec.rb
 - spec/install/gems/sudo_spec.rb
 - spec/install/gems/win32_spec.rb
@@ -338,7 +355,7 @@ files:
 - spec/support/sudo.rb
 - spec/update/gems_spec.rb
 - spec/update/git_spec.rb
-- spec/update/source_spec.rb
+- spec/update/path_spec.rb
 homepage: http://bundler.io
 licenses:
 - MIT
@@ -359,7 +376,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
       version: 1.3.6
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.2.2
+rubygems_version: 2.4.1
 signing_key: 
 specification_version: 4
 summary: The best way to manage your application's dependencies
@@ -373,7 +390,8 @@ test_files:
 - spec/bundler/psyched_yaml_spec.rb
 - spec/bundler/retry_spec.rb
 - spec/bundler/settings_spec.rb
-- spec/bundler/source_spec.rb
+- spec/bundler/source/rubygems_spec.rb
+- spec/bundler/source_list_spec.rb
 - spec/cache/gems_spec.rb
 - spec/cache/git_spec.rb
 - spec/cache/path_spec.rb
@@ -410,6 +428,7 @@ test_files:
 - spec/install/gems/post_install_spec.rb
 - spec/install/gems/resolving_spec.rb
 - spec/install/gems/simple_case_spec.rb
+- spec/install/gems/sources_spec.rb
 - spec/install/gems/standalone_spec.rb
 - spec/install/gems/sudo_spec.rb
 - spec/install/gems/win32_spec.rb
@@ -469,4 +488,4 @@ test_files:
 - spec/support/sudo.rb
 - spec/update/gems_spec.rb
 - spec/update/git_spec.rb
-- spec/update/source_spec.rb
+- spec/update/path_spec.rb
diff --git a/spec/bundler/definition_spec.rb b/spec/bundler/definition_spec.rb
index ad02861..0f18416 100644
--- a/spec/bundler/definition_spec.rb
+++ b/spec/bundler/definition_spec.rb
@@ -4,11 +4,12 @@ require 'bundler/definition'
 describe Bundler::Definition do
   before do
     allow(Bundler).to receive(:settings){ Bundler::Settings.new(".") }
+    allow(Bundler).to receive(:default_gemfile){ Pathname.new("Gemfile") }
   end
 
   describe "#lock" do
     context "when it's not possible to write to the file" do
-      subject{ Bundler::Definition.new(nil, [], [], []) }
+      subject{ Bundler::Definition.new(nil, [], Bundler::SourceList.new, []) }
 
       it "raises an InstallError with explanation" do
         expect(File).to receive(:open).with("Gemfile.lock", "wb").
diff --git a/spec/bundler/source_spec.rb b/spec/bundler/source/rubygems_spec.rb
similarity index 100%
rename from spec/bundler/source_spec.rb
rename to spec/bundler/source/rubygems_spec.rb
diff --git a/spec/bundler/source_list_spec.rb b/spec/bundler/source_list_spec.rb
new file mode 100644
index 0000000..67d4ef6
--- /dev/null
+++ b/spec/bundler/source_list_spec.rb
@@ -0,0 +1,361 @@
+require 'spec_helper'
+
+describe Bundler::SourceList do
+  before do
+    allow(Bundler).to receive(:root) { Pathname.new '/' }
+  end
+
+  subject(:source_list) { Bundler::SourceList.new }
+
+  let(:rubygems_aggregate) { Bundler::Source::Rubygems.new }
+
+  describe "adding sources" do
+    before do
+      source_list.add_path_source('path' => '/existing/path/to/gem')
+      source_list.add_git_source('uri' => 'git://existing-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://existing-rubygems.org'])
+    end
+
+    describe "#add_path_source" do
+      before do
+        @duplicate = source_list.add_path_source('path' => '/path/to/gem')
+        @new_source = source_list.add_path_source('path' => '/path/to/gem')
+      end
+
+      it "returns the new path source" do
+        expect(@new_source).to be_instance_of(Bundler::Source::Path)
+      end
+
+      it "passes the provided options to the new source" do
+        expect(@new_source.options).to eq('path' => '/path/to/gem')
+      end
+
+      it "adds the source to the beginning of path_sources" do
+        expect(source_list.path_sources.first).to equal(@new_source)
+      end
+
+      it "removes existing duplicates" do
+        expect(source_list.path_sources).not_to include equal(@duplicate)
+      end
+    end
+
+    describe "#add_git_source" do
+      before do
+        @duplicate = source_list.add_git_source('uri' => 'git://host/path.git')
+        @new_source = source_list.add_git_source('uri' => 'git://host/path.git')
+      end
+
+      it "returns the new git source" do
+        expect(@new_source).to be_instance_of(Bundler::Source::Git)
+      end
+
+      it "passes the provided options to the new source" do
+        expect(@new_source.options).to eq('uri' => 'git://host/path.git')
+      end
+
+      it "adds the source to the beginning of git_sources" do
+        expect(source_list.git_sources.first).to equal(@new_source)
+      end
+
+      it "removes existing duplicates" do
+        expect(source_list.git_sources).not_to include equal(@duplicate)
+      end
+    end
+
+    describe "#add_rubygems_source" do
+      before do
+        @duplicate = source_list.add_rubygems_source('remotes' => ['https://rubygems.org/'])
+        @new_source = source_list.add_rubygems_source('remotes' => ['https://rubygems.org/'])
+      end
+
+      it "returns the new rubygems source" do
+        expect(@new_source).to be_instance_of(Bundler::Source::Rubygems)
+      end
+
+      it "passes the provided options to the new source" do
+        expect(@new_source.options).to eq('remotes' => ['https://rubygems.org/'])
+      end
+
+      it "adds the source to the beginning of rubygems_sources" do
+        expect(source_list.rubygems_sources.first).to equal(@new_source)
+      end
+
+      it "removes duplicates" do
+        expect(source_list.rubygems_sources).not_to include equal(@duplicate)
+      end
+    end
+
+    describe "#add_rubygems_remote" do
+      before do
+        @returned_source = source_list.add_rubygems_remote('https://rubygems.org/')
+      end
+
+      it "returns the aggregate rubygems source" do
+        expect(@returned_source).to be_instance_of(Bundler::Source::Rubygems)
+      end
+
+      it "adds the provided remote to the beginning of the aggregate source" do
+        source_list.add_rubygems_remote('https://othersource.org')
+        expect(@returned_source.remotes.first).to eq(URI('https://othersource.org/'))
+      end
+    end
+  end
+
+  describe "#all_sources" do
+    it "includes the aggregate rubygems source when rubygems sources have been added" do
+      source_list.add_git_source('uri' => 'git://host/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://rubygems.org'])
+      source_list.add_path_source('path' => '/path/to/gem')
+
+      expect(source_list.all_sources).to include rubygems_aggregate
+    end
+
+    it "includes the aggregate rubygems source when no rubygems sources have been added" do
+      source_list.add_git_source('uri' => 'git://host/path.git')
+      source_list.add_path_source('path' => '/path/to/gem')
+
+      expect(source_list.all_sources).to include rubygems_aggregate
+    end
+
+    it "returns path sources before git sources before rubygems sources before the aggregate" do
+      source_list.add_git_source('uri' => 'git://host/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://rubygems.org'])
+      source_list.add_path_source('path' => '/path/to/gem')
+
+      expect(source_list.all_sources).to eq [
+        Bundler::Source::Path.new('path' => '/path/to/gem'),
+        Bundler::Source::Git.new('uri' => 'git://host/path.git'),
+        Bundler::Source::Rubygems.new('remotes' => ['https://rubygems.org']),
+        rubygems_aggregate,
+      ]
+    end
+
+    it "returns sources of the same type in the reverse order that they were added" do
+      source_list.add_git_source('uri' => 'git://third-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://fifth-rubygems.org'])
+      source_list.add_path_source('path' => '/third/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://fourth-rubygems.org'])
+      source_list.add_path_source('path' => '/second/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://third-rubygems.org'])
+      source_list.add_git_source('uri' => 'git://second-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://second-rubygems.org'])
+      source_list.add_path_source('path' => '/first/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://first-rubygems.org'])
+      source_list.add_git_source('uri' => 'git://first-git.org/path.git')
+
+      expect(source_list.all_sources).to eq [
+        Bundler::Source::Path.new('path' => '/first/path/to/gem'),
+        Bundler::Source::Path.new('path' => '/second/path/to/gem'),
+        Bundler::Source::Path.new('path' => '/third/path/to/gem'),
+        Bundler::Source::Git.new('uri' => 'git://first-git.org/path.git'),
+        Bundler::Source::Git.new('uri' => 'git://second-git.org/path.git'),
+        Bundler::Source::Git.new('uri' => 'git://third-git.org/path.git'),
+        Bundler::Source::Rubygems.new('remotes' => ['https://first-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://second-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://third-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://fourth-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://fifth-rubygems.org']),
+        rubygems_aggregate,
+      ]
+    end
+  end
+
+  describe "#path_sources" do
+    it "returns an empty array when no path sources have been added" do
+      source_list.add_rubygems_remote('https://rubygems.org')
+      source_list.add_git_source('uri' => 'git://host/path.git')
+      expect(source_list.path_sources).to be_empty
+    end
+
+    it "returns path sources in the reverse order that they were added" do
+      source_list.add_git_source('uri' => 'git://third-git.org/path.git')
+      source_list.add_rubygems_remote('https://fifth-rubygems.org')
+      source_list.add_path_source('path' => '/third/path/to/gem')
+      source_list.add_rubygems_remote('https://fourth-rubygems.org')
+      source_list.add_path_source('path' => '/second/path/to/gem')
+      source_list.add_rubygems_remote('https://third-rubygems.org')
+      source_list.add_git_source('uri' => 'git://second-git.org/path.git')
+      source_list.add_rubygems_remote('https://second-rubygems.org')
+      source_list.add_path_source('path' => '/first/path/to/gem')
+      source_list.add_rubygems_remote('https://first-rubygems.org')
+      source_list.add_git_source('uri' => 'git://first-git.org/path.git')
+
+      expect(source_list.path_sources).to eq [
+        Bundler::Source::Path.new('path' => '/first/path/to/gem'),
+        Bundler::Source::Path.new('path' => '/second/path/to/gem'),
+        Bundler::Source::Path.new('path' => '/third/path/to/gem'),
+      ]
+    end
+  end
+
+  describe "#git_sources" do
+    it "returns an empty array when no git sources have been added" do
+      source_list.add_rubygems_remote('https://rubygems.org')
+      source_list.add_path_source('path' => '/path/to/gem')
+
+      expect(source_list.git_sources).to be_empty
+    end
+
+    it "returns git sources in the reverse order that they were added" do
+      source_list.add_git_source('uri' => 'git://third-git.org/path.git')
+      source_list.add_rubygems_remote('https://fifth-rubygems.org')
+      source_list.add_path_source('path' => '/third/path/to/gem')
+      source_list.add_rubygems_remote('https://fourth-rubygems.org')
+      source_list.add_path_source('path' => '/second/path/to/gem')
+      source_list.add_rubygems_remote('https://third-rubygems.org')
+      source_list.add_git_source('uri' => 'git://second-git.org/path.git')
+      source_list.add_rubygems_remote('https://second-rubygems.org')
+      source_list.add_path_source('path' => '/first/path/to/gem')
+      source_list.add_rubygems_remote('https://first-rubygems.org')
+      source_list.add_git_source('uri' => 'git://first-git.org/path.git')
+
+      expect(source_list.git_sources).to eq [
+        Bundler::Source::Git.new('uri' => 'git://first-git.org/path.git'),
+        Bundler::Source::Git.new('uri' => 'git://second-git.org/path.git'),
+        Bundler::Source::Git.new('uri' => 'git://third-git.org/path.git'),
+      ]
+    end
+  end
+
+  describe "#rubygems_sources" do
+    it "includes the aggregate rubygems source when rubygems sources have been added" do
+      source_list.add_git_source('uri' => 'git://host/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://rubygems.org'])
+      source_list.add_path_source('path' => '/path/to/gem')
+
+      expect(source_list.rubygems_sources).to include rubygems_aggregate
+    end
+
+    it "returns only the aggregate rubygems source when no rubygems sources have been added" do
+      source_list.add_git_source('uri' => 'git://host/path.git')
+      source_list.add_path_source('path' => '/path/to/gem')
+
+      expect(source_list.rubygems_sources).to eq [rubygems_aggregate]
+    end
+
+    it "returns rubygems sources in the reverse order that they were added" do
+      source_list.add_git_source('uri' => 'git://third-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://fifth-rubygems.org'])
+      source_list.add_path_source('path' => '/third/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://fourth-rubygems.org'])
+      source_list.add_path_source('path' => '/second/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://third-rubygems.org'])
+      source_list.add_git_source('uri' => 'git://second-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://second-rubygems.org'])
+      source_list.add_path_source('path' => '/first/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://first-rubygems.org'])
+      source_list.add_git_source('uri' => 'git://first-git.org/path.git')
+
+      expect(source_list.rubygems_sources).to eq [
+        Bundler::Source::Rubygems.new('remotes' => ['https://first-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://second-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://third-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://fourth-rubygems.org']),
+        Bundler::Source::Rubygems.new('remotes' => ['https://fifth-rubygems.org']),
+        rubygems_aggregate,
+      ]
+    end
+  end
+
+  describe "#get" do
+    context "when it includes an equal source" do
+      let(:rubygems_source) { Bundler::Source::Rubygems.new('remotes' => ['https://rubygems.org']) }
+      before { @equal_source = source_list.add_rubygems_remote('https://rubygems.org') }
+
+      it "returns the equal source" do
+        expect(source_list.get(rubygems_source)).to be @equal_source
+      end
+    end
+
+    context "when it does not include an equal source" do
+      let(:path_source) { Bundler::Source::Path.new('path' => '/path/to/gem') }
+
+      it "returns nil" do
+        expect(source_list.get(path_source)).to be_nil
+      end
+    end
+  end
+
+  describe "#lock_sources" do
+    it "combines the rubygems sources into a single instance, removing duplicate remotes from the front" do
+      source_list.add_git_source('uri' => 'git://third-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://fourth-rubygems.org']) # intentional duplicate
+      source_list.add_path_source('path' => '/third/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://first-rubygems.org'])
+      source_list.add_path_source('path' => '/second/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://second-rubygems.org'])
+      source_list.add_git_source('uri' => 'git://second-git.org/path.git')
+      source_list.add_rubygems_source('remotes' => ['https://third-rubygems.org'])
+      source_list.add_path_source('path' => '/first/path/to/gem')
+      source_list.add_rubygems_source('remotes' => ['https://fourth-rubygems.org'])
+      source_list.add_git_source('uri' => 'git://first-git.org/path.git')
+
+      expect(source_list.lock_sources).to eq [
+        Bundler::Source::Git.new('uri' => 'git://first-git.org/path.git'),
+        Bundler::Source::Git.new('uri' => 'git://second-git.org/path.git'),
+        Bundler::Source::Git.new('uri' => 'git://third-git.org/path.git'),
+        Bundler::Source::Path.new('path' => '/first/path/to/gem'),
+        Bundler::Source::Path.new('path' => '/second/path/to/gem'),
+        Bundler::Source::Path.new('path' => '/third/path/to/gem'),
+        Bundler::Source::Rubygems.new('remotes' => [
+          'https://first-rubygems.org',
+          'https://second-rubygems.org',
+          'https://third-rubygems.org',
+          'https://fourth-rubygems.org',
+        ]),
+      ]
+    end
+  end
+
+  describe "replace_sources!" do
+    let(:existing_locked_source) { Bundler::Source::Path.new('path' => '/existing/path') }
+    let(:removed_locked_source)  { Bundler::Source::Path.new('path' => '/removed/path') }
+
+    let(:locked_sources) { [existing_locked_source, removed_locked_source] }
+
+    before do
+      @existing_source = source_list.add_path_source('path' => '/existing/path')
+      @new_source = source_list.add_path_source('path' => '/new/path')
+      source_list.replace_sources!(locked_sources)
+    end
+
+    it "maintains the order and number of sources" do
+      expect(source_list.path_sources).to eq [@new_source, @existing_source]
+    end
+
+    it "retains the same instance of the new source" do
+      expect(source_list.path_sources[0]).to be @new_source
+    end
+
+    it "replaces the instance of the existing source" do
+      expect(source_list.path_sources[1]).to be existing_locked_source
+    end
+  end
+
+  describe "#cached!" do
+    let(:rubygems_source) { source_list.add_rubygems_remote('https://rubygems.org') }
+    let(:git_source)      { source_list.add_git_source('uri' => 'git://host/path.git') }
+    let(:path_source)     { source_list.add_path_source('path' => '/path/to/gem') }
+
+    it "calls #cached! on all the sources" do
+      expect(rubygems_source).to receive(:cached!)
+      expect(git_source).to receive(:cached!)
+      expect(path_source).to receive(:cached!)
+      source_list.cached!
+    end
+  end
+
+  describe "#remote!" do
+    let(:rubygems_source) { source_list.add_rubygems_remote('https://rubygems.org') }
+    let(:git_source)      { source_list.add_git_source('uri' => 'git://host/path.git') }
+    let(:path_source)     { source_list.add_path_source('path' => '/path/to/gem') }
+
+    it "calls #remote! on all the sources" do
+      expect(rubygems_source).to receive(:remote!)
+      expect(git_source).to receive(:remote!)
+      expect(path_source).to receive(:remote!)
+      source_list.remote!
+    end
+  end
+
+end
diff --git a/spec/commands/binstubs_spec.rb b/spec/commands/binstubs_spec.rb
index 0f04ad4..e307539 100644
--- a/spec/commands/binstubs_spec.rb
+++ b/spec/commands/binstubs_spec.rb
@@ -105,6 +105,19 @@ describe "bundle binstubs <gem>" do
     end
   end
 
+  context "when the gem doesn't exist" do
+    it "displays an error with correct status" do
+      install_gemfile <<-G
+        source "file://#{gem_repo1}"
+      G
+
+      bundle "binstubs doesnt_exist", :exitstatus => true
+
+      expect(exitstatus).to eq(7)
+      expect(out).to eq("Could not find gem 'doesnt_exist'.")
+    end
+  end
+
   context "--path" do
     it "sets the binstubs dir" do
       install_gemfile <<-G
diff --git a/spec/install/deploy_spec.rb b/spec/install/deploy_spec.rb
index fdfe64b..c3ba321 100644
--- a/spec/install/deploy_spec.rb
+++ b/spec/install/deploy_spec.rb
@@ -67,6 +67,18 @@ describe "install with --deployment or --frozen" do
     expect(exitstatus).to eq(0)
   end
 
+  it "works when there are credentials in the source URL" do
+    install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
+      source "http://user:pass@localgemserver.test/"
+
+      gem "rack-obama", ">= 1.0"
+    G
+
+    bundle "install --deployment", :exitstatus => true, :artifice => "endpoint_strict_basic_authentication"
+
+    expect(exitstatus).to eq(0)
+  end
+
   describe "with an existing lockfile" do
     before do
       bundle "install"
diff --git a/spec/install/gems/dependency_api_spec.rb b/spec/install/gems/dependency_api_spec.rb
index a01c894..b3e5edf 100644
--- a/spec/install/gems/dependency_api_spec.rb
+++ b/spec/install/gems/dependency_api_spec.rb
@@ -157,8 +157,8 @@ describe "gemcutter's dependency API" do
       gem "rack"
     G
 
-    bundle :install, :artifice => "endpoint_marshal_fail"
-    expect(out).to include("Fetching source index from #{source_uri}")
+    bundle :install, :verbose => true, :artifice => "endpoint_marshal_fail"
+    expect(out).to include("could not fetch from the dependency API, trying the full index")
     should_be_installed "rack 1.0.0"
   end
 
diff --git a/spec/install/gems/sources_spec.rb b/spec/install/gems/sources_spec.rb
new file mode 100644
index 0000000..d45e25c
--- /dev/null
+++ b/spec/install/gems/sources_spec.rb
@@ -0,0 +1,247 @@
+require "spec_helper"
+
+describe "bundle install with gems on multiple sources" do
+  # repo1 is built automatically before all of the specs run
+  # it contains rack-obama 1.0.0 and rack 0.9.1 & 1.0.0 amongst other gems
+
+  context "without source affinity" do
+    before do
+      # Oh no! Someone evil is trying to hijack rack :(
+      # need this to be broken to check for correct source ordering
+      build_repo gem_repo3 do
+        build_gem "rack", repo3_rack_version do |s|
+          s.write "lib/rack.rb", "RACK = 'FAIL'"
+        end
+      end
+    end
+
+    context "when the same version of the same gem is in multiple sources" do
+      let(:repo3_rack_version) { "1.0.0" }
+
+      before do
+        gemfile <<-G
+          source "file://#{gem_repo3}"
+          source "file://#{gem_repo1}"
+          gem "rack-obama"
+          gem "rack"
+        G
+      end
+
+      it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first" do
+        bundle :install
+
+        expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
+        expect(out).to include("Installed from: file:#{gem_repo1}")
+        should_be_installed("rack-obama 1.0.0", "rack 1.0.0")
+      end
+    end
+
+    context "when different versions of the same gem are in multiple sources" do
+      let(:repo3_rack_version) { "1.2" }
+
+      before do
+        gemfile <<-G
+          source "file://#{gem_repo3}"
+          source "file://#{gem_repo1}"
+          gem "rack-obama"
+          gem "rack", "1.0.0" # force it to install the working version in repo1
+        G
+      end
+
+      it "warns about ambiguous gems, but installs anyway" do
+        bundle :install
+
+        expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
+        expect(out).to include("Installed from: file:#{gem_repo1}")
+        should_be_installed("rack-obama 1.0.0", "rack 1.0.0")
+      end
+    end
+  end
+
+  context "with source affinity" do
+    context "with sources given by a block" do
+      before do
+        # Oh no! Someone evil is trying to hijack rack :(
+        # need this to be broken to check for correct source ordering
+        build_repo gem_repo3 do
+          build_gem "rack", "1.0.0" do |s|
+            s.write "lib/rack.rb", "RACK = 'FAIL'"
+          end
+        end
+
+        gemfile <<-G
+          source "file://#{gem_repo3}"
+          source "file://#{gem_repo1}" do
+            gem "rack"
+          end
+          gem "rack-obama" # shoud come from repo3!
+        G
+      end
+
+      it "installs the gems without any warning" do
+        bundle :install
+        expect(out).not_to include("Warning")
+        should_be_installed("rack-obama 1.0.0", "rack 1.0.0")
+      end
+    end
+
+    context "with sources set by an option" do
+      before do
+        # Oh no! Someone evil is trying to hijack rack :(
+        # need this to be broken to check for correct source ordering
+        build_repo gem_repo3 do
+          build_gem "rack", "1.0.0" do |s|
+            s.write "lib/rack.rb", "RACK = 'FAIL'"
+          end
+        end
+
+        gemfile <<-G
+          source "file://#{gem_repo3}"
+          gem "rack-obama" # should come from repo3!
+          gem "rack", :source => "file://#{gem_repo1}"
+        G
+      end
+
+      it "installs the gems without any warning" do
+        bundle :install
+        expect(out).not_to include("Warning")
+        should_be_installed("rack-obama 1.0.0", "rack 1.0.0")
+      end
+    end
+
+    context "with an indirect dependency" do
+      before do
+        build_repo gem_repo3 do
+          build_gem "depends_on_rack", "1.0.1" do |s|
+            s.add_dependency "rack"
+          end
+        end
+      end
+
+      context "when the indirect dependency is in the pinned source" do
+        before do
+          # we need a working rack gem in repo3
+          update_repo gem_repo3 do
+            build_gem "rack", "1.0.0"
+          end
+
+          gemfile <<-G
+            source "file://#{gem_repo2}"
+            source "file://#{gem_repo3}" do
+              gem "depends_on_rack"
+            end
+          G
+        end
+
+        context "and not in any other sources" do
+          before do
+            build_repo(gem_repo2) {}
+          end
+
+          it "installs from the same source without any warning" do
+            bundle :install
+            expect(out).not_to include("Warning")
+            should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0")
+          end
+        end
+
+        context "and in another source" do
+          before do
+            # need this to be broken to check for correct source ordering
+            build_repo gem_repo2 do
+              build_gem "rack", "1.0.0" do |s|
+                s.write "lib/rack.rb", "RACK = 'FAIL'"
+              end
+            end
+          end
+
+          it "installs from the same source without any warning" do
+            bundle :install
+            expect(out).not_to include("Warning")
+            should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0")
+          end
+        end
+      end
+
+      context "when the indirect dependency is in a different source" do
+        before do
+          # In these tests, we need a working rack gem in repo2 and not repo3
+          build_repo gem_repo2 do
+            build_gem "rack", "1.0.0"
+          end
+        end
+
+        context "and not in any other sources" do
+          before do
+            gemfile <<-G
+              source "file://#{gem_repo2}"
+              source "file://#{gem_repo3}" do
+                gem "depends_on_rack"
+              end
+            G
+          end
+
+          it "installs from the other source without any warning" do
+            bundle :install
+            expect(out).not_to include("Warning")
+            should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0")
+          end
+        end
+
+        context "and in yet another source" do
+          before do
+            gemfile <<-G
+              source "file://#{gem_repo1}"
+              source "file://#{gem_repo2}"
+              source "file://#{gem_repo3}" do
+                gem "depends_on_rack"
+              end
+            G
+          end
+
+          it "installs from the other source and warns about ambiguous gems" do
+            bundle :install
+            expect(out).to include("Warning: the gem 'rack' was found in multiple sources.")
+            expect(out).to include("Installed from: file:#{gem_repo2}")
+            should_be_installed("depends_on_rack 1.0.1", "rack 1.0.0")
+          end
+        end
+      end
+    end
+
+    context "with a gem that is only found in the wrong source" do
+      before do
+        build_repo gem_repo3 do
+          build_gem "not_in_repo1", "1.0.0"
+        end
+
+        gemfile <<-G
+          source "file://#{gem_repo3}"
+          gem "not_in_repo1", :source => "file://#{gem_repo1}"
+        G
+      end
+
+      it "does not install the gem" do
+        bundle :install
+        expect(out).to include("Could not find gem 'not_in_repo1 (>= 0) ruby'")
+      end
+    end
+  end
+
+  context "when an older version of the same gem also ships with Ruby" do
+    before do
+      system_gems "rack-0.9.1"
+
+      gemfile <<-G
+        source "file://#{gem_repo1}"
+        gem "rack" # shoud come from repo1!
+      G
+    end
+
+    it "installs the gems without any warning" do
+      bundle :install
+      expect(out).not_to include("Warning")
+      should_be_installed("rack 1.0.0")
+    end
+  end
+end
diff --git a/spec/lock/lockfile_spec.rb b/spec/lock/lockfile_spec.rb
index 779fd1c..588d643 100644
--- a/spec/lock/lockfile_spec.rb
+++ b/spec/lock/lockfile_spec.rb
@@ -70,6 +70,31 @@ describe "the lockfile format" do
     G
   end
 
+  it "generates a lockfile wihout credentials for a configured source" do
+    bundle "config http://localgemserver.test/ user:pass"
+
+    install_gemfile(<<-G, :artifice => "endpoint_strict_basic_authentication", :quiet => true)
+      source "http://localgemserver.test/"
+
+      gem "rack-obama", ">= 1.0"
+    G
+
+    lockfile_should_be <<-G
+      GEM
+        remote: http://localgemserver.test/
+        specs:
+          rack (1.0.0)
+          rack-obama (1.0)
+            rack
+
+      PLATFORMS
+        #{generic(Gem::Platform.local)}
+
+      DEPENDENCIES
+        rack-obama (>= 1.0)
+    G
+  end
+
   it "generates lockfiles with multiple requirements" do
     install_gemfile <<-G
       source "file://#{gem_repo1}"
@@ -119,7 +144,7 @@ describe "the lockfile format" do
     G
   end
 
-  it "does not assplode when a platform specific dependency is present and the Gemfile has not been resolved on that platform" do
+  it "does not asplode when a platform specific dependency is present and the Gemfile has not been resolved on that platform" do
     build_lib "omg", :path => lib_path('omg')
 
     gemfile <<-G
@@ -260,6 +285,45 @@ describe "the lockfile format" do
     G
   end
 
+  it "sorts serialized sources by type" do
+    build_lib "foo"
+    bar = build_git "bar"
+
+    install_gemfile <<-G
+      source "file://#{gem_repo1}"
+
+      gem "rack"
+      gem "foo", :path => "#{lib_path("foo-1.0")}"
+      gem "bar", :git => "#{lib_path("bar-1.0")}"
+    G
+
+    lockfile_should_be <<-G
+      GIT
+        remote: #{lib_path("bar-1.0")}
+        revision: #{bar.ref_for('master')}
+        specs:
+          bar (1.0)
+
+      PATH
+        remote: #{lib_path("foo-1.0")}
+        specs:
+          foo (1.0)
+
+      GEM
+        remote: file:#{gem_repo1}/
+        specs:
+          rack (1.0.0)
+
+      PLATFORMS
+        #{generic(Gem::Platform.local)}
+
+      DEPENDENCIES
+        bar!
+        foo!
+        rack
+    G
+  end
+
   it "lists gems alphabetically" do
     install_gemfile <<-G
       source "file://#{gem_repo1}"
diff --git a/spec/quality_spec.rb b/spec/quality_spec.rb
index 345fe46..59a8520 100644
--- a/spec/quality_spec.rb
+++ b/spec/quality_spec.rb
@@ -42,13 +42,13 @@ describe "The library itself" do
   end
 
   RSpec::Matchers.define :be_well_formed do
-    failure_message do |actual|
-      actual.join("\n")
-    end
-
     match do |actual|
       actual.empty?
     end
+
+    failure_message do |actual|
+      actual.join("\n")
+    end
   end
 
   it "has no malformed whitespace" do
diff --git a/spec/runtime/setup_spec.rb b/spec/runtime/setup_spec.rb
index 2d355a3..02ce0de 100644
--- a/spec/runtime/setup_spec.rb
+++ b/spec/runtime/setup_spec.rb
@@ -368,21 +368,18 @@ describe "Bundler.setup" do
     end
 
     it "does not randomly change the path when specifying --path and the bundle directory becomes read only" do
-      begin
-        bundle "install --path vendor/bundle"
+      bundle "install --path vendor/bundle"
 
-        Dir["**/*"].each do |f|
-          File.directory?(f) ?
-            File.chmod(0555, f) :
-            File.chmod(0444, f)
-        end
+      with_read_only("**/*") do
+        should_be_installed "rack 1.0.0"
+      end
+    end
+
+    it "finds git gem when default bundle path becomes read only" do
+      bundle "install"
+
+      with_read_only("#{Bundler.bundle_path}/**/*") do
         should_be_installed "rack 1.0.0"
-      ensure
-        Dir["**/*"].each do |f|
-          File.directory?(f) ?
-            File.chmod(0755, f) :
-            File.chmod(0644, f)
-        end
       end
     end
   end
diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb
index 9c15783..db1a785 100644
--- a/spec/support/helpers.rb
+++ b/spec/support/helpers.rb
@@ -341,5 +341,19 @@ module Spec
     ensure
       $stdout = actual_stdout
     end
+
+    def with_read_only(pattern)
+      chmod = lambda do |dirmode, filemode|
+        lambda do |f|
+          mode = File.directory?(f) ? dirmode : filemode
+          File.chmod(mode, f)
+        end
+      end
+
+      Dir[pattern].each(&chmod[0555, 0444])
+      yield
+    ensure
+      Dir[pattern].each(&chmod[0755, 0644])
+    end
   end
 end
diff --git a/spec/update/git_spec.rb b/spec/update/git_spec.rb
index 4d3a570..2452636 100644
--- a/spec/update/git_spec.rb
+++ b/spec/update/git_spec.rb
@@ -233,4 +233,51 @@ describe "bundle update" do
       expect(out).to include("Using rails 3.0 (was 2.3.2) from #{lib_path('rails')} (at master)")
     end
   end
+
+  describe "with --source flag" do
+    before :each do
+      build_repo2
+      @git = build_git "foo", :path => lib_path("foo") do |s|
+        s.executables = "foobar"
+      end
+
+      install_gemfile <<-G
+        source "file://#{gem_repo2}"
+        git "#{lib_path('foo')}" do
+          gem 'foo'
+        end
+        gem 'rack'
+      G
+    end
+
+    it "updates the source" do
+      update_git "foo", :path => @git.path
+
+      bundle "update --source foo"
+
+      in_app_root do
+        run <<-RUBY
+          require 'foo'
+          puts "WIN" if defined?(FOO_PREV_REF)
+        RUBY
+
+        expect(out).to eq("WIN")
+      end
+    end
+
+    it "unlocks gems that were originally pulled in by the source" do
+      update_git "foo", "2.0", :path => @git.path
+
+      bundle "update --source foo"
+      should_be_installed "foo 2.0"
+    end
+
+    it "leaves all other gems frozen" do
+      update_repo2
+      update_git "foo", :path => @git.path
+
+      bundle "update --source foo"
+      should_be_installed "rack 1.0"
+    end
+  end
 end
diff --git a/spec/update/path_spec.rb b/spec/update/path_spec.rb
new file mode 100644
index 0000000..fdc4615
--- /dev/null
+++ b/spec/update/path_spec.rb
@@ -0,0 +1,18 @@
+require "spec_helper"
+
+describe "path sources" do
+  describe "bundle update --source" do
+    it "shows the previous version of the gem when updated from path source" do
+      build_lib "activesupport", "2.3.5", :path => lib_path("rails/activesupport")
+
+      install_gemfile <<-G
+      gem "activesupport", :path => "#{lib_path('rails/activesupport')}"
+      G
+
+      build_lib "activesupport", "3.0", :path => lib_path("rails/activesupport")
+
+      bundle "update --source activesupport"
+      expect(out).to include("Using activesupport 3.0 (was 2.3.5) from source at #{lib_path('rails/activesupport')}")
+    end
+  end
+end
diff --git a/spec/update/source_spec.rb b/spec/update/source_spec.rb
deleted file mode 100644
index c9fe7c6..0000000
--- a/spec/update/source_spec.rb
+++ /dev/null
@@ -1,63 +0,0 @@
-require "spec_helper"
-
-describe "bundle update --source" do
-  describe "git sources" do
-    before :each do
-      build_repo2
-      @git = build_git "foo", :path => lib_path("foo") do |s|
-        s.executables = "foobar"
-      end
-
-      install_gemfile <<-G
-        source "file://#{gem_repo2}"
-        git "#{lib_path('foo')}" do
-          gem 'foo'
-        end
-        gem 'rack'
-      G
-    end
-
-    it "updates the source" do
-      update_git "foo", :path => @git.path
-
-      bundle "update --source foo"
-
-      in_app_root do
-        run <<-RUBY
-          require 'foo'
-          puts "WIN" if defined?(FOO_PREV_REF)
-        RUBY
-
-        expect(out).to eq("WIN")
-      end
-    end
-
-    it "unlocks gems that were originally pulled in by the source" do
-      update_git "foo", "2.0", :path => @git.path
-
-      bundle "update --source foo"
-      should_be_installed "foo 2.0"
-    end
-
-    it "leaves all other gems frozen" do
-      update_repo2
-      update_git "foo", :path => @git.path
-
-      bundle "update --source foo"
-      should_be_installed "rack 1.0"
-    end
-
-    it "shows the previous version of the gem when updated from path source" do
-      build_lib "activesupport", "2.3.5", :path => lib_path("rails/activesupport")
-
-      install_gemfile <<-G
-      gem "activesupport", :path => "#{lib_path('rails/activesupport')}"
-      G
-
-      build_lib "activesupport", "3.0", :path => lib_path("rails/activesupport")
-
-      bundle "update --source activesupport"
-      expect(out).to include("Using activesupport 3.0 (was 2.3.5) from source at #{lib_path('rails/activesupport')}")
-    end
-  end
-end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/bundler.git



More information about the Pkg-ruby-extras-commits mailing list