diff options
author | Homu <homu@barosl.com> | 2016-06-05 16:25:30 +0900 |
---|---|---|
committer | Homu <homu@barosl.com> | 2016-06-05 16:25:30 +0900 |
commit | 3c55223f4c8e374a58eea52c4795315f4cb68d12 (patch) | |
tree | f46d06d321f85835d316149d2175141ce122b1eb | |
parent | 667d4e4487bde5196bb326a7c03531e65de85cf6 (diff) | |
parent | 8f4c288343b02d053a396ac3aa4bec0f2b85655c (diff) | |
download | bundler-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.rb | 14 | ||||
-rw-r--r-- | lib/bundler/env.rb | 4 | ||||
-rw-r--r-- | lib/bundler/index.rb | 1 | ||||
-rw-r--r-- | lib/bundler/resolver.rb | 2 | ||||
-rw-r--r-- | lib/bundler/runtime.rb | 9 | ||||
-rw-r--r-- | lib/bundler/source.rb | 5 | ||||
-rw-r--r-- | lib/bundler/source/gemspec.rb | 13 | ||||
-rw-r--r-- | lib/bundler/source/path.rb | 4 | ||||
-rw-r--r-- | lib/bundler/source_list.rb | 6 | ||||
-rw-r--r-- | man/gemfile.5.ronn | 4 | ||||
-rw-r--r-- | spec/install/gemfile/gemspec_spec.rb | 19 |
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 |