[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