summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2016-06-05 16:25:30 +0900
committerHomu <homu@barosl.com>2016-06-05 16:25:30 +0900
commit3c55223f4c8e374a58eea52c4795315f4cb68d12 (patch)
treef46d06d321f85835d316149d2175141ce122b1eb
parent667d4e4487bde5196bb326a7c03531e65de85cf6 (diff)
parent8f4c288343b02d053a396ac3aa4bec0f2b85655c (diff)
downloadbundler-3c55223f4c8e374a58eea52c4795315f4cb68d12.tar.gz
Auto merge of #4445 - bundler:seg-gemspec-allow-conflicts, r=indirect
Allow conflicts for gems resolved via `gemspec` Needs to be cleaned up, but this demonstrates the general idea
-rw-r--r--lib/bundler/dsl.rb14
-rw-r--r--lib/bundler/env.rb4
-rw-r--r--lib/bundler/index.rb1
-rw-r--r--lib/bundler/resolver.rb2
-rw-r--r--lib/bundler/runtime.rb9
-rw-r--r--lib/bundler/source.rb5
-rw-r--r--lib/bundler/source/gemspec.rb13
-rw-r--r--lib/bundler/source/path.rb4
-rw-r--r--lib/bundler/source_list.rb6
-rw-r--r--man/gemfile.5.ronn4
-rw-r--r--spec/install/gemfile/gemspec_spec.rb19
11 files changed, 60 insertions, 21 deletions
diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb
index 2c68a7b87a..dc482a698d 100644
--- a/lib/bundler/dsl.rb
+++ b/lib/bundler/dsl.rb
@@ -67,16 +67,16 @@ module Bundler
"#{file}. Make sure you can build the gem, then try again"
end
+ @gemspecs << spec
+
gem_platforms = Bundler::Dependency::REVERSE_PLATFORM_MAP[Bundler::GemHelpers.generic_local_platform]
- gem spec.name, :path => path, :glob => glob, :platforms => gem_platforms
+ gem spec.name, :name => spec.name, :path => path, :glob => glob, :platforms => gem_platforms
group(development_group) do
spec.development_dependencies.each do |dep|
- gem dep.name, *(dep.requirement.as_list + [:type => :development])
+ gem dep.name, *(dep.requirement.as_list + [:type => :development, :platforms => gem_platforms])
end
end
-
- @gemspecs << gemspecs.first
when 0
raise InvalidOption, "There are no gemspecs at #{expanded_path}"
else
@@ -149,7 +149,11 @@ module Bundler
end
def path(path, options = {}, &blk)
- source_options = normalize_hash(options).merge("path" => Pathname.new(path), "root_path" => gemfile_root)
+ source_options = normalize_hash(options).merge(
+ "path" => Pathname.new(path),
+ "root_path" => gemfile_root,
+ "gemspec" => gemspecs.find {|g| g.name == options["name"] }
+ )
source = @sources.add_path_source(source_options)
with_source(source, &blk)
end
diff --git a/lib/bundler/env.rb b/lib/bundler/env.rb
index baf6a10f31..47e720a201 100644
--- a/lib/bundler/env.rb
+++ b/lib/bundler/env.rb
@@ -44,8 +44,8 @@ module Bundler
if print_gemspecs
dsl = Dsl.new.tap {|d| d.eval_gemfile(Bundler.default_gemfile) }
dsl.gemspecs.each do |gs|
- out << "\n#{Pathname.new(gs).basename}"
- out << "\n\n " << read_file(gs).gsub(/\n/, "\n ") << "\n"
+ out << "\n#{File.basename(gs.loaded_from)}"
+ out << "\n\n " << read_file(gs.loaded_from).gsub(/\n/, "\n ") << "\n"
end
end
diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb
index 5c49034280..a03c11d992 100644
--- a/lib/bundler/index.rb
+++ b/lib/bundler/index.rb
@@ -156,6 +156,7 @@ module Bundler
@cache[base || false][dependency] ||= begin
specs = specs_by_name(dependency.name) + (base || [])
found = specs.select do |spec|
+ next true if spec.source.is_a?(Source::Gemspec)
if base # allow all platforms when searching from a lockfile
dependency.matches_spec?(spec)
else
diff --git a/lib/bundler/resolver.rb b/lib/bundler/resolver.rb
index 48f0d468b6..8c183ba885 100644
--- a/lib/bundler/resolver.rb
+++ b/lib/bundler/resolver.rb
@@ -293,7 +293,7 @@ module Bundler
end
def requirement_satisfied_by?(requirement, activated, spec)
- requirement.matches_spec?(spec)
+ requirement.matches_spec?(spec) || spec.source.is_a?(Source::Gemspec)
end
def sort_dependencies(dependencies, activated, conflicts)
diff --git a/lib/bundler/runtime.rb b/lib/bundler/runtime.rb
index b0ff6f5ae2..3a86fe9226 100644
--- a/lib/bundler/runtime.rb
+++ b/lib/bundler/runtime.rb
@@ -117,16 +117,9 @@ module Bundler
Bundler.ui.info "Updating files in #{Bundler.settings.app_cache_path}"
- # Do not try to cache specification for the gem described any of the gemspecs
- root_gem_names = nil
- if gemspec_cache_hash = Bundler.instance_variable_get(:@gemspec_cache)
- gemspecs = gemspec_cache_hash.values
- root_gem_names = gemspecs.map(&:name)
- end
-
specs.each do |spec|
next if spec.name == "bundler"
- next if !Dir.glob("*.gemspec").empty? && spec.source.class == Bundler::Source::Path && root_gem_names.include?(spec.name)
+ next if spec.source.is_a?(Source::Gemspec)
spec.source.send(:fetch_gem, spec) if Bundler.settings[:cache_all_platforms] && spec.source.respond_to?(:fetch_gem, true)
spec.source.cache(spec, custom_path) if spec.source.respond_to?(:cache)
end
diff --git a/lib/bundler/source.rb b/lib/bundler/source.rb
index eee4ade45b..afa7d91838 100644
--- a/lib/bundler/source.rb
+++ b/lib/bundler/source.rb
@@ -1,9 +1,10 @@
# frozen_string_literal: true
module Bundler
class Source
- autoload :Rubygems, "bundler/source/rubygems"
- autoload :Path, "bundler/source/path"
+ autoload :Gemspec, "bundler/source/gemspec"
autoload :Git, "bundler/source/git"
+ autoload :Path, "bundler/source/path"
+ autoload :Rubygems, "bundler/source/rubygems"
attr_accessor :dependency_names
diff --git a/lib/bundler/source/gemspec.rb b/lib/bundler/source/gemspec.rb
new file mode 100644
index 0000000000..37e9a43945
--- /dev/null
+++ b/lib/bundler/source/gemspec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+module Bundler
+ class Source
+ class Gemspec < Path
+ attr_reader :gemspec
+
+ def initialize(options)
+ super
+ @gemspec = options["gemspec"]
+ end
+ end
+ end
+end
diff --git a/lib/bundler/source/path.rb b/lib/bundler/source/path.rb
index 3ec1e78b97..569cea00f8 100644
--- a/lib/bundler/source/path.rb
+++ b/lib/bundler/source/path.rb
@@ -60,8 +60,8 @@ module Bundler
end
def eql?(other)
- other.instance_of?(Path) &&
- expanded_path == expand(other.path) &&
+ return unless other.class == Path || other.class == Gemspec
+ expanded_path == expand(other.path) &&
version == other.version
end
diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb
index dc62c8926a..0595cbdcf4 100644
--- a/lib/bundler/source_list.rb
+++ b/lib/bundler/source_list.rb
@@ -12,7 +12,11 @@ module Bundler
end
def add_path_source(options = {})
- add_source_to_list Source::Path.new(options), path_sources
+ if options["gemspec"]
+ add_source_to_list Source::Gemspec.new(options), path_sources
+ else
+ add_source_to_list Source::Path.new(options), path_sources
+ end
end
def add_git_source(options = {})
diff --git a/man/gemfile.5.ronn b/man/gemfile.5.ronn
index b707e2a5c5..5b39268657 100644
--- a/man/gemfile.5.ronn
+++ b/man/gemfile.5.ronn
@@ -480,6 +480,10 @@ options, which control where bundler looks for the `.gemspec`, the glob it uses
for the gemspec (defaults to: "{,*,*/*}.gemspec"), what named `.gemspec` it uses
(if more than one is present), and which group development dependencies are included in.
+When a `gemspec` dependency encounters version conflicts during resolution, the
+local version under development will always be selected -- even if there are
+remote versions that better match other requirements for the `gemspec` gem.
+
## SOURCE PRIORITY
When attempting to locate a gem to satisfy a gem requirement,
diff --git a/spec/install/gemfile/gemspec_spec.rb b/spec/install/gemfile/gemspec_spec.rb
index 36c7353045..f860f55f13 100644
--- a/spec/install/gemfile/gemspec_spec.rb
+++ b/spec/install/gemfile/gemspec_spec.rb
@@ -143,6 +143,25 @@ describe "bundle install from an existing gemspec" do
expect(@err).not_to match(/ahh/)
end
+ it "allows conflicts" do
+ build_lib("foo", :path => tmp.join("foo")) do |s|
+ s.version = "1.0.0"
+ s.add_dependency "bar", "= 1.0.0"
+ end
+ build_gem "deps", :to_system => true do |s|
+ s.add_dependency "foo", "= 0.0.1"
+ end
+ build_gem "foo", "0.0.1", :to_system => true
+
+ install_gemfile <<-G
+ source "file://#{gem_repo2}"
+ gem "deps"
+ gemspec :path => '#{tmp.join("foo")}', :name => 'foo'
+ G
+
+ should_be_installed "foo 1.0.0"
+ end
+
context "when child gemspecs conflict with a released gemspec" do
before do
# build the "parent" gem that depends on another gem in the same repo