summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler.rb4
-rw-r--r--lib/bundler/definition.rb51
-rw-r--r--lib/bundler/dsl.rb26
-rw-r--r--lib/bundler/index.rb10
-rw-r--r--lib/bundler/lazy_specification.rb10
-rw-r--r--lib/bundler/lockfile_parser.rb6
-rw-r--r--lib/bundler/source/gemspec.rb4
-rw-r--r--lib/bundler/source/path.rb4
-rw-r--r--spec/commands/package_spec.rb2
-rw-r--r--spec/install/gemfile/gemspec_spec.rb146
-rw-r--r--spec/install/gemfile/path_spec.rb2
-rw-r--r--spec/support/builders.rb2
-rw-r--r--spec/support/helpers.rb1
13 files changed, 230 insertions, 38 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index c73c07af3a..98f8123466 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -131,7 +131,9 @@ module Bundler
def locked_gems
@locked_gems ||=
- if Bundler.default_lockfile.exist?
+ if defined?(@definition) && @definition
+ definition.locked_gems
+ elsif Bundler.default_lockfile.exist?
lock = Bundler.read_file(Bundler.default_lockfile)
LockfileParser.new(lock)
end
diff --git a/lib/bundler/definition.rb b/lib/bundler/definition.rb
index 10e8e517f9..36bb9f2ef8 100644
--- a/lib/bundler/definition.rb
+++ b/lib/bundler/definition.rb
@@ -7,7 +7,15 @@ module Bundler
class Definition
include GemHelpers
- attr_reader :dependencies, :platforms, :ruby_version, :locked_deps, :gem_version_promoter, :requires
+ attr_reader(
+ :dependencies,
+ :gem_version_promoter,
+ :locked_deps,
+ :locked_gems,
+ :platforms,
+ :requires,
+ :ruby_version
+ )
# Given a gemfile and lockfile creates a Bundler definition
#
@@ -60,15 +68,15 @@ module Bundler
if lockfile && File.exist?(lockfile)
@lockfile_contents = Bundler.read_file(lockfile)
- locked = LockfileParser.new(@lockfile_contents)
- @platforms = locked.platforms
- @locked_bundler_version = locked.bundler_version
- @locked_ruby_version = locked.ruby_version
+ @locked_gems = LockfileParser.new(@lockfile_contents)
+ @platforms = @locked_gems.platforms
+ @locked_bundler_version = @locked_gems.bundler_version
+ @locked_ruby_version = @locked_gems.ruby_version
if unlock != true
- @locked_deps = locked.dependencies
- @locked_specs = SpecSet.new(locked.specs)
- @locked_sources = locked.sources
+ @locked_deps = @locked_gems.dependencies
+ @locked_specs = SpecSet.new(@locked_gems.specs)
+ @locked_sources = @locked_gems.sources
else
@unlock = {}
@locked_deps = []
@@ -78,6 +86,7 @@ module Bundler
else
@unlock = {}
@platforms = []
+ @locked_gems = nil
@locked_deps = []
@locked_specs = SpecSet.new([])
@locked_sources = []
@@ -512,14 +521,14 @@ module Bundler
# Check if the specs of the given source changed
# according to the locked source.
def specs_changed?(source)
- locked = @locked_sources.find(source)
+ locked = @locked_sources.find {|s| s == source }
- !locked || dependencies_for_source_changed?(source) || specs_for_source_changed?(source)
+ !locked || dependencies_for_source_changed?(source, locked) || specs_for_source_changed?(source)
end
- def dependencies_for_source_changed?(source)
+ def dependencies_for_source_changed?(source, locked_source = source)
deps_for_source = @dependencies.select {|s| s.source == source }
- locked_deps_for_source = @locked_deps.select {|s| s.source == source }
+ locked_deps_for_source = @locked_deps.select {|s| s.source == locked_source }
Set.new(deps_for_source) != Set.new(locked_deps_for_source)
end
@@ -557,9 +566,22 @@ module Bundler
end
end
+ def converge_path_source_to_gemspec_source(source)
+ return source unless source.instance_of?(Source::Path)
+ gemspec_source = sources.path_sources.find {|s| s.is_a?(Source::Gemspec) && s.as_path_source == source }
+ gemspec_source || source
+ end
+
def converge_sources
changes = false
+ @locked_sources.map! do |source|
+ converge_path_source_to_gemspec_source(source)
+ end
+ @locked_specs.each do |spec|
+ spec.source &&= converge_path_source_to_gemspec_source(spec.source)
+ end
+
# Get the Rubygems sources from the Gemfile.lock
locked_gem_sources = @locked_sources.select {|s| s.is_a?(Source::Rubygems) }
# Get the Rubygems remotes from the Gemfile
@@ -604,6 +626,9 @@ module Bundler
elsif dep.source
dep.source = sources.get(dep.source)
end
+ if dep.source.is_a?(Source::Gemspec)
+ dep.platforms.concat(@platforms.map {|p| Dependency::REVERSE_PLATFORM_MAP[p] }.flatten(1)).uniq!
+ end
end
Set.new(@dependencies) != Set.new(@locked_deps)
end
@@ -655,7 +680,7 @@ module Bundler
# then we unlock it.
# Path sources have special logic
- if s.source.instance_of?(Source::Path)
+ if s.source.instance_of?(Source::Path) || s.source.instance_of?(Source::Gemspec)
other = s.source.specs[s].first
# If the spec is no longer in the path source, unlock it. This
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 5577f40c26..b064c80d4c 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -50,22 +50,22 @@ module Bundler
end
def gemspec(opts = nil)
- path = opts && opts[:path] || "."
- glob = opts && opts[:glob]
- name = opts && opts[:name] || "{,*}"
- development_group = opts && opts[:development_group] || :development
+ opts ||= {}
+ path = opts[:path] || "."
+ glob = opts[:glob]
+ name = opts[:name]
+ development_group = opts[:development_group] || :development
expanded_path = gemfile_root.join(path)
- gemspecs = Dir[File.join(expanded_path, "#{name}.gemspec")]
+ gemspecs = Dir[File.join(expanded_path, "{,*}.gemspec")].map {|g| Bundler.load_gemspec(g) }.compact
+ gemspecs.reject! {|s| s.name != name } if name
+ Index.sort_specs(gemspecs)
+ specs_by_name_and_version = gemspecs.group_by {|s| [s.name, s.version] }
- case gemspecs.size
+ case specs_by_name_and_version.size
when 1
- spec = Bundler.load_gemspec(gemspecs.first)
-
- unless spec
- raise InvalidOption, "There was an error loading the gemspec at " \
- "#{file}. Make sure you can build the gem, then try again"
- end
+ specs = specs_by_name_and_version.values.first
+ spec = specs.find {|s| s.match_platform(Gem::Platform.local) } || specs.first
@gemspecs << spec
@@ -74,7 +74,7 @@ module Bundler
group(development_group) do
spec.development_dependencies.each do |dep|
- gem dep.name, *(dep.requirement.as_list + [:type => :development, :platforms => gem_platforms])
+ gem dep.name, *(dep.requirement.as_list + [:type => :development])
end
end
when 0
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index f0ee411df8..4529c57279 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -67,12 +67,20 @@ module Bundler
end
end
- results.sort_by do |s|
+ sort_specs(results)
+ end
+
+ def self.sort_specs(specs)
+ specs.sort_by do |s|
platform_string = s.platform.to_s
[s.version, platform_string == RUBY ? NULL : platform_string]
end
end
+ def sort_specs(specs)
+ self.class.sort_specs(specs)
+ end
+
def local_search(query, base = nil)
case query
when Gem::Specification, RemoteSpecification, LazySpecification, EndpointSpecification then search_by_spec(query)
diff --git a/lib/bundler/lazy_specification.rb b/lib/bundler/lazy_specification.rb
index ccaa791cc8..36ff5c59ed 100644
--- a/lib/bundler/lazy_specification.rb
+++ b/lib/bundler/lazy_specification.rb
@@ -5,6 +5,8 @@ require "bundler/match_platform"
module Bundler
class LazySpecification
+ Identifier = Struct.new(:name, :version, :source, :platform, :dependencies)
+
include MatchPlatform
attr_reader :name, :version, :dependencies, :platform
@@ -61,11 +63,15 @@ module Bundler
end
def to_s
- @__to_s ||= "#{name} (#{version})"
+ @__to_s ||= if platform == Gem::Platform::RUBY || platform.nil?
+ "#{name} (#{version})"
+ else
+ "#{name} (#{version}-#{platform})"
+ end
end
def identifier
- @__identifier ||= [name, version, source, platform, dependencies].hash
+ @__identifier ||= Identifier.new(name, version, source, platform, dependencies)
end
private
diff --git a/lib/bundler/lockfile_parser.rb b/lib/bundler/lockfile_parser.rb
index d5b2844079..90da4ac608 100644
--- a/lib/bundler/lockfile_parser.rb
+++ b/lib/bundler/lockfile_parser.rb
@@ -207,8 +207,10 @@ module Bundler
def parse_spec(line)
if line =~ NAME_VERSION_4
name = $1
- version = Gem::Version.new($2)
- platform = $3 ? Gem::Platform.new($3) : Gem::Platform::RUBY
+ version = $2
+ platform = $3
+ version = Gem::Version.new(version)
+ platform = platform ? Gem::Platform.new(platform) : Gem::Platform::RUBY
@current_spec = LazySpecification.new(name, version, platform)
@current_spec.source = @current_source
diff --git a/lib/bundler/source/gemspec.rb b/lib/bundler/source/gemspec.rb
index 37e9a43945..05e613277f 100644
--- a/lib/bundler/source/gemspec.rb
+++ b/lib/bundler/source/gemspec.rb
@@ -8,6 +8,10 @@ module Bundler
super
@gemspec = options["gemspec"]
end
+
+ def as_path_source
+ Path.new(options)
+ end
end
end
end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 3c4d914fb3..69bb0c1af2 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -11,7 +11,7 @@ module Bundler
DEFAULT_GLOB = "{,*,*/*}.gemspec".freeze
def initialize(options)
- @options = options
+ @options = options.dup
@glob = options["glob"] || DEFAULT_GLOB
@allow_cached = false
@@ -60,7 +60,7 @@ module Bundler
end
def eql?(other)
- return unless other.class == Path || other.class == Gemspec
+ return unless other.class == self.class
expanded_path == expand(other.path) &&
version == other.version
end
diff --git a/spec/commands/package_spec.rb b/spec/commands/package_spec.rb
index 9c722b3491..83b56f304e 100644
--- a/spec/commands/package_spec.rb
+++ b/spec/commands/package_spec.rb
@@ -127,7 +127,7 @@ describe "bundle package" do
source "file://#{gem_repo1}"
gem 'rack'
gemspec :name => 'mygem'
- gemspec :name => 'mygem_client'
+ gemspec :name => 'mygem_test'
D
bundle! "package --all"
diff --git a/spec/install/gemfile/gemspec_spec.rb b/spec/install/gemfile/gemspec_spec.rb
index f860f55f13..454dbcf8c2 100644
--- a/spec/install/gemfile/gemspec_spec.rb
+++ b/spec/install/gemfile/gemspec_spec.rb
@@ -67,7 +67,7 @@ describe "bundle install from an existing gemspec" do
it "should raise if there are too many gemspecs available" do
build_lib("foo", :path => tmp.join("foo")) do |s|
- s.write("foo2.gemspec", "")
+ s.write("foo2.gemspec", build_spec("foo", "4.0").first.to_ruby)
end
error = install_gemfile(<<-G, :expect_err => true)
@@ -196,7 +196,17 @@ describe "bundle install from an existing gemspec" do
before do
build_lib("foo", :path => tmp.join("foo")) do |s|
s.add_dependency "rack", "=1.0.0"
- s.platform = platform if explicit_platform
+ end
+
+ if explicit_platform
+ create_file(
+ tmp.join("foo", "foo-#{platform}.gemspec"),
+ build_spec("foo", "1.0", platform) do
+ dep "rack", "=1.0.0"
+ @spec.authors = "authors"
+ @spec.summary = "summary"
+ end.first.to_ruby
+ )
end
gemfile <<-G
@@ -266,5 +276,137 @@ describe "bundle install from an existing gemspec" do
end
end
end
+
+ context "bundled for ruby and jruby" do
+ let(:platform_specific_type) { :runtime }
+ let(:dependency) { "platform_specific" }
+ before do
+ build_repo2 do
+ build_gem "indirect_platform_specific" do |s|
+ s.add_runtime_dependency "platform_specific"
+ end
+ end
+
+ build_lib "foo", :path => "." do |s|
+ if platform_specific_type == :runtime
+ s.add_runtime_dependency dependency
+ elsif platform_specific_type == :development
+ s.add_development_dependency dependency
+ else
+ raise "wrong dependency type #{platform_specific_type}, can only be :development or :runtime"
+ end
+ end
+
+ %w(ruby jruby).each do |platform|
+ simulate_platform(platform) do
+ install_gemfile <<-G
+ source "file://#{gem_repo2}"
+ gemspec
+ G
+ end
+ end
+ end
+
+ context "on ruby" do
+ before do
+ simulate_platform("ruby")
+ bundle :install
+ end
+
+ context "as a runtime dependency" do
+ it "keeps java dependencies in the lockfile" do
+ should_be_installed "foo 1.0", "platform_specific 1.0 RUBY"
+ expect(lockfile).to eq strip_whitespace(<<-L)
+ PATH
+ remote: .
+ specs:
+ foo (1.0)
+ platform_specific
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+ platform_specific (1.0)
+ platform_specific (1.0-java)
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ foo!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "as a development dependency" do
+ let(:platform_specific_type) { :development }
+
+ it "keeps java dependencies in the lockfile" do
+ should_be_installed "foo 1.0", "platform_specific 1.0 RUBY"
+ expect(lockfile).to eq strip_whitespace(<<-L)
+ PATH
+ remote: .
+ specs:
+ foo (1.0)
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+ platform_specific (1.0)
+ platform_specific (1.0-java)
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ foo!
+ platform_specific
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+
+ context "with an indirect platform-specific development dependency" do
+ let(:platform_specific_type) { :development }
+ let(:dependency) { "indirect_platform_specific" }
+
+ it "keeps java dependencies in the lockfile" do
+ should_be_installed "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY"
+ expect(lockfile).to eq strip_whitespace(<<-L)
+ PATH
+ remote: .
+ specs:
+ foo (1.0)
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+ indirect_platform_specific (1.0)
+ platform_specific
+ platform_specific (1.0)
+ platform_specific (1.0-java)
+
+ PLATFORMS
+ java
+ ruby
+
+ DEPENDENCIES
+ foo!
+ indirect_platform_specific
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+ end
+ end
+ end
end
end
diff --git a/spec/install/gemfile/path_spec.rb b/spec/install/gemfile/path_spec.rb
index 9f2893a01c..d3910748cc 100644
--- a/spec/install/gemfile/path_spec.rb
+++ b/spec/install/gemfile/path_spec.rb
@@ -241,7 +241,7 @@ describe "bundle install with explicit source paths" do
it "raises if there are multiple gemspecs" do
build_lib "foo", "1.0", :path => lib_path("foo") do |s|
- s.write "bar.gemspec"
+ s.write "bar.gemspec", build_spec("bar", "1.0").first.to_ruby
end
install_gemfile <<-G
diff --git a/spec/support/builders.rb b/spec/support/builders.rb
index 3c10cba757..6ed3a2904e 100644
--- a/spec/support/builders.rb
+++ b/spec/support/builders.rb
@@ -395,6 +395,8 @@ module Spec
s.name = name
s.version = Gem::Version.new(v)
s.platform = platform
+ s.authors = ["no one in particular"]
+ s.summary = "a gemspec used only for testing"
DepBuilder.run(s, &block) if block_given?
end
end
diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb
index 0293f08716..0d2338df90 100644
--- a/spec/support/helpers.rb
+++ b/spec/support/helpers.rb
@@ -217,6 +217,7 @@ module Spec
opts[:retry] ||= 0
bundle :install, opts
end
+ bang :install_gemfile
def lock_gemfile(*args)
gemfile(*args)