mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	Merge bundler to standard libraries.
rubygems 2.7.x depends bundler-1.15.x. This is preparation for
  rubygems and bundler migration.
  * lib/bundler.rb, lib/bundler/*: files of bundler-1.15.4
  * spec/bundler/*: rspec examples of bundler-1.15.4. I applied patches.
    * https://github.com/bundler/bundler/pull/6007
    * Exclude not working examples on ruby repository.
    * Fake ruby interpriter instead of installed ruby.
  * Makefile.in: Added test task named `test-bundler`. This task is only
    working macOS/linux yet. I'm going to support Windows environment later.
  * tool/sync_default_gems.rb: Added sync task for bundler.
  [Feature #12733][ruby-core:77172]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59779 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
			
			
This commit is contained in:
		
							parent
							
								
									f2e04b77aa
								
							
						
					
					
						commit
						8598f8c2dc
					
				
					 409 changed files with 60699 additions and 1 deletions
				
			
		
							
								
								
									
										258
									
								
								spec/bundler/resolver/basic_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								spec/bundler/resolver/basic_spec.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,258 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
require "spec_helper"
 | 
			
		||||
 | 
			
		||||
RSpec.describe "Resolving" do
 | 
			
		||||
  before :each do
 | 
			
		||||
    @index = an_awesome_index
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "resolves a single gem" do
 | 
			
		||||
    dep "rack"
 | 
			
		||||
 | 
			
		||||
    should_resolve_as %w(rack-1.1)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "resolves a gem with dependencies" do
 | 
			
		||||
    dep "actionpack"
 | 
			
		||||
 | 
			
		||||
    should_resolve_as %w(actionpack-2.3.5 activesupport-2.3.5 rack-1.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "resolves a conflicting index" do
 | 
			
		||||
    @index = a_conflict_index
 | 
			
		||||
    dep "my_app"
 | 
			
		||||
    should_resolve_as %w(activemodel-3.2.11 builder-3.0.4 grape-0.2.6 my_app-1.0.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "resolves a complex conflicting index" do
 | 
			
		||||
    @index = a_complex_conflict_index
 | 
			
		||||
    dep "my_app"
 | 
			
		||||
    should_resolve_as %w(a-1.4.0 b-0.3.5 c-3.2 d-0.9.8 my_app-1.1.0)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "resolves a index with conflict on child" do
 | 
			
		||||
    @index = index_with_conflict_on_child
 | 
			
		||||
    dep "chef_app"
 | 
			
		||||
    should_resolve_as %w(berkshelf-2.0.7 chef-10.26 chef_app-1.0.0 json-1.7.7)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "resolves a index with root level conflict on child" do
 | 
			
		||||
    @index = a_index_with_root_conflict_on_child
 | 
			
		||||
    dep "i18n", "~> 0.4"
 | 
			
		||||
    dep "activesupport", "~> 3.0"
 | 
			
		||||
    dep "activerecord", "~> 3.0"
 | 
			
		||||
    dep "builder", "~> 2.1.2"
 | 
			
		||||
    should_resolve_as %w(activesupport-3.0.5 i18n-0.4.2 builder-2.1.2 activerecord-3.0.5 activemodel-3.0.5)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "raises an exception if a child dependency is not resolved" do
 | 
			
		||||
    @index = a_unresovable_child_index
 | 
			
		||||
    dep "chef_app_error"
 | 
			
		||||
    expect do
 | 
			
		||||
      resolve
 | 
			
		||||
    end.to raise_error(Bundler::VersionConflict)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "raises an exception with the minimal set of conflicting dependencies" do
 | 
			
		||||
    @index = build_index do
 | 
			
		||||
      %w(0.9 1.0 2.0).each {|v| gem("a", v) }
 | 
			
		||||
      gem("b", "1.0") { dep "a", ">= 2" }
 | 
			
		||||
      gem("c", "1.0") { dep "a", "< 1" }
 | 
			
		||||
    end
 | 
			
		||||
    dep "a"
 | 
			
		||||
    dep "b"
 | 
			
		||||
    dep "c"
 | 
			
		||||
    expect do
 | 
			
		||||
      resolve
 | 
			
		||||
    end.to raise_error(Bundler::VersionConflict, <<-E.strip)
 | 
			
		||||
Bundler could not find compatible versions for gem "a":
 | 
			
		||||
  In Gemfile:
 | 
			
		||||
    b was resolved to 1.0, which depends on
 | 
			
		||||
      a (>= 2)
 | 
			
		||||
 | 
			
		||||
    c was resolved to 1.0, which depends on
 | 
			
		||||
      a (< 1)
 | 
			
		||||
    E
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "should throw error in case of circular dependencies" do
 | 
			
		||||
    @index = a_circular_index
 | 
			
		||||
    dep "circular_app"
 | 
			
		||||
 | 
			
		||||
    expect do
 | 
			
		||||
      resolve
 | 
			
		||||
    end.to raise_error(Bundler::CyclicDependencyError, /please remove either gem 'bar' or gem 'foo'/i)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Issue #3459
 | 
			
		||||
  it "should install the latest possible version of a direct requirement with no constraints given" do
 | 
			
		||||
    @index = a_complicated_index
 | 
			
		||||
    dep "foo"
 | 
			
		||||
    should_resolve_and_include %w(foo-3.0.5)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Issue #3459
 | 
			
		||||
  it "should install the latest possible version of a direct requirement with constraints given" do
 | 
			
		||||
    @index = a_complicated_index
 | 
			
		||||
    dep "foo", ">= 3.0.0"
 | 
			
		||||
    should_resolve_and_include %w(foo-3.0.5)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  it "takes into account required_ruby_version" do
 | 
			
		||||
    @index = build_index do
 | 
			
		||||
      gem "foo", "1.0.0" do
 | 
			
		||||
        dep "bar", ">= 0"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      gem "foo", "2.0.0" do |s|
 | 
			
		||||
        dep "bar", ">= 0"
 | 
			
		||||
        s.required_ruby_version = "~> 2.0.0"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      gem "bar", "1.0.0"
 | 
			
		||||
 | 
			
		||||
      gem "bar", "2.0.0" do |s|
 | 
			
		||||
        s.required_ruby_version = "~> 2.0.0"
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      gem "ruby\0", "1.8.7"
 | 
			
		||||
    end
 | 
			
		||||
    dep "foo"
 | 
			
		||||
    dep "ruby\0", "1.8.7"
 | 
			
		||||
 | 
			
		||||
    deps = []
 | 
			
		||||
    @deps.each do |d|
 | 
			
		||||
      deps << Bundler::DepProxy.new(d, "ruby")
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    should_resolve_and_include %w(foo-1.0.0 bar-1.0.0), [{}, []]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context "conservative" do
 | 
			
		||||
    before :each do
 | 
			
		||||
      @index = build_index do
 | 
			
		||||
        gem("foo", "1.3.7") { dep "bar", "~> 2.0" }
 | 
			
		||||
        gem("foo", "1.3.8") { dep "bar", "~> 2.0" }
 | 
			
		||||
        gem("foo", "1.4.3") { dep "bar", "~> 2.0" }
 | 
			
		||||
        gem("foo", "1.4.4") { dep "bar", "~> 2.0" }
 | 
			
		||||
        gem("foo", "1.4.5") { dep "bar", "~> 2.1" }
 | 
			
		||||
        gem("foo", "1.5.0") { dep "bar", "~> 2.1" }
 | 
			
		||||
        gem("foo", "1.5.1") { dep "bar", "~> 3.0" }
 | 
			
		||||
        gem("foo", "2.0.0") { dep "bar", "~> 3.0" }
 | 
			
		||||
        gem "bar", %w(2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0)
 | 
			
		||||
      end
 | 
			
		||||
      dep "foo"
 | 
			
		||||
 | 
			
		||||
      # base represents declared dependencies in the Gemfile that are still satisfied by the lockfile
 | 
			
		||||
      @base = Bundler::SpecSet.new([])
 | 
			
		||||
 | 
			
		||||
      # locked represents versions in lockfile
 | 
			
		||||
      @locked = locked(%w(foo 1.4.3), %w(bar 2.0.3))
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves all gems to latest patch" do
 | 
			
		||||
      # strict is not set, so bar goes up a minor version due to dependency from foo 1.4.5
 | 
			
		||||
      should_conservative_resolve_and_include :patch, [], %w(foo-1.4.5 bar-2.1.1)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves all gems to latest patch strict" do
 | 
			
		||||
      # strict is set, so foo can only go up to 1.4.4 to avoid bar going up a minor version, and bar can go up to 2.0.5
 | 
			
		||||
      should_conservative_resolve_and_include [:patch, :strict], [], %w(foo-1.4.4 bar-2.0.5)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves foo only to latest patch - same dependency case" do
 | 
			
		||||
      @locked = locked(%w(foo 1.3.7), %w(bar 2.0.3))
 | 
			
		||||
      # bar is locked, and the lock holds here because the dependency on bar doesn't change on the matching foo version.
 | 
			
		||||
      should_conservative_resolve_and_include :patch, ["foo"], %w(foo-1.3.8 bar-2.0.3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves foo only to latest patch - changing dependency not declared case" do
 | 
			
		||||
      # foo is the only gem being requested for update, therefore bar is locked, but bar is NOT
 | 
			
		||||
      # declared as a dependency in the Gemfile. In this case, locks don't apply to _changing_
 | 
			
		||||
      # dependencies and since the dependency of the selected foo gem changes, the latest matching
 | 
			
		||||
      # dependency of "bar", "~> 2.1" -- bar-2.1.1 -- is selected. This is not a bug and follows
 | 
			
		||||
      # the long-standing documented Conservative Updating behavior of bundle install.
 | 
			
		||||
      # http://bundler.io/v1.12/man/bundle-install.1.html#CONSERVATIVE-UPDATING
 | 
			
		||||
      should_conservative_resolve_and_include :patch, ["foo"], %w(foo-1.4.5 bar-2.1.1)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves foo only to latest patch - changing dependency declared case" do
 | 
			
		||||
      # bar is locked AND a declared dependency in the Gemfile, so it will not move, and therefore
 | 
			
		||||
      # foo can only move up to 1.4.4.
 | 
			
		||||
      @base << build_spec("bar", "2.0.3").first
 | 
			
		||||
      should_conservative_resolve_and_include :patch, ["foo"], %w(foo-1.4.4 bar-2.0.3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves foo only to latest patch strict" do
 | 
			
		||||
      # adding strict helps solve the possibly unexpected behavior of bar changing in the prior test case,
 | 
			
		||||
      # because no versions will be returned for bar ~> 2.1, so the engine falls back to ~> 2.0 (turn on
 | 
			
		||||
      # debugging to see this happen).
 | 
			
		||||
      should_conservative_resolve_and_include [:patch, :strict], ["foo"], %w(foo-1.4.4 bar-2.0.3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves bar only to latest patch" do
 | 
			
		||||
      # bar is locked, so foo can only go up to 1.4.4
 | 
			
		||||
      should_conservative_resolve_and_include :patch, ["bar"], %w(foo-1.4.3 bar-2.0.5)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves all gems to latest minor" do
 | 
			
		||||
      # strict is not set, so bar goes up a major version due to dependency from foo 1.4.5
 | 
			
		||||
      should_conservative_resolve_and_include :minor, [], %w(foo-1.5.1 bar-3.0.0)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves all gems to latest minor strict" do
 | 
			
		||||
      # strict is set, so foo can only go up to 1.5.0 to avoid bar going up a major version
 | 
			
		||||
      should_conservative_resolve_and_include [:minor, :strict], [], %w(foo-1.5.0 bar-2.1.1)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves all gems to latest major" do
 | 
			
		||||
      should_conservative_resolve_and_include :major, [], %w(foo-2.0.0 bar-3.0.0)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves all gems to latest major strict" do
 | 
			
		||||
      should_conservative_resolve_and_include [:major, :strict], [], %w(foo-2.0.0 bar-3.0.0)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    # Why would this happen in real life? If bar 2.2 has a bug that the author of foo wants to bypass
 | 
			
		||||
    # by reverting the dependency, the author of foo could release a new gem with an older requirement.
 | 
			
		||||
    context "revert to previous" do
 | 
			
		||||
      before :each do
 | 
			
		||||
        @index = build_index do
 | 
			
		||||
          gem("foo", "1.4.3") { dep "bar", "~> 2.2" }
 | 
			
		||||
          gem("foo", "1.4.4") { dep "bar", "~> 2.1.0" }
 | 
			
		||||
          gem("foo", "1.5.0") { dep "bar", "~> 2.0.0" }
 | 
			
		||||
          gem "bar", %w(2.0.5 2.1.1 2.2.3)
 | 
			
		||||
        end
 | 
			
		||||
        dep "foo"
 | 
			
		||||
 | 
			
		||||
        # base represents declared dependencies in the Gemfile that are still satisfied by the lockfile
 | 
			
		||||
        @base = Bundler::SpecSet.new([])
 | 
			
		||||
 | 
			
		||||
        # locked represents versions in lockfile
 | 
			
		||||
        @locked = locked(%w(foo 1.4.3), %w(bar 2.2.3))
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "could revert to a previous version level patch" do
 | 
			
		||||
        should_conservative_resolve_and_include :patch, [], %w(foo-1.4.4 bar-2.1.1)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "cannot revert to a previous version in strict mode level patch" do
 | 
			
		||||
        # the strict option removes the version required to match, so a version conflict results
 | 
			
		||||
        expect do
 | 
			
		||||
          should_conservative_resolve_and_include [:patch, :strict], [], %w(foo-1.4.3 bar-2.1.1)
 | 
			
		||||
        end.to raise_error Bundler::VersionConflict, /#{Regexp.escape("Could not find gem 'bar (~> 2.1.0)'")}/
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "could revert to a previous version level minor" do
 | 
			
		||||
        should_conservative_resolve_and_include :minor, [], %w(foo-1.5.0 bar-2.0.5)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      it "cannot revert to a previous version in strict mode level minor" do
 | 
			
		||||
        # the strict option removes the version required to match, so a version conflict results
 | 
			
		||||
        expect do
 | 
			
		||||
          should_conservative_resolve_and_include [:minor, :strict], [], %w(foo-1.4.3 bar-2.1.1)
 | 
			
		||||
        end.to raise_error Bundler::VersionConflict, /#{Regexp.escape("Could not find gem 'bar (~> 2.0.0)'")}/
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
							
								
								
									
										101
									
								
								spec/bundler/resolver/platform_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								spec/bundler/resolver/platform_spec.rb
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,101 @@
 | 
			
		|||
# frozen_string_literal: true
 | 
			
		||||
require "spec_helper"
 | 
			
		||||
 | 
			
		||||
RSpec.describe "Resolving platform craziness" do
 | 
			
		||||
  describe "with cross-platform gems" do
 | 
			
		||||
    before :each do
 | 
			
		||||
      @index = an_awesome_index
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "resolves a simple multi platform gem" do
 | 
			
		||||
      dep "nokogiri"
 | 
			
		||||
      platforms "ruby", "java"
 | 
			
		||||
 | 
			
		||||
      should_resolve_as %w(nokogiri-1.4.2 nokogiri-1.4.2-java weakling-0.0.3)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "doesn't pull gems that don't exist for the current platform" do
 | 
			
		||||
      dep "nokogiri"
 | 
			
		||||
      platforms "ruby"
 | 
			
		||||
 | 
			
		||||
      should_resolve_as %w(nokogiri-1.4.2)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "doesn't pull gems when the version is available for all requested platforms" do
 | 
			
		||||
      dep "nokogiri"
 | 
			
		||||
      platforms "mswin32"
 | 
			
		||||
 | 
			
		||||
      should_resolve_as %w(nokogiri-1.4.2.1-x86-mswin32)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "with mingw32" do
 | 
			
		||||
    before :each do
 | 
			
		||||
      @index = build_index do
 | 
			
		||||
        platforms "mingw32 mswin32 x64-mingw32" do |platform|
 | 
			
		||||
          gem "thin", "1.2.7", platform
 | 
			
		||||
        end
 | 
			
		||||
        gem "win32-api", "1.5.1", "universal-mingw32"
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "finds mswin gems" do
 | 
			
		||||
      # win32 is hardcoded to get CPU x86 in rubygems
 | 
			
		||||
      platforms "mswin32"
 | 
			
		||||
      dep "thin"
 | 
			
		||||
      should_resolve_as %w(thin-1.2.7-x86-mswin32)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "finds mingw gems" do
 | 
			
		||||
      # mingw is _not_ hardcoded to add CPU x86 in rubygems
 | 
			
		||||
      platforms "x86-mingw32"
 | 
			
		||||
      dep "thin"
 | 
			
		||||
      should_resolve_as %w(thin-1.2.7-mingw32)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "finds x64-mingw gems" do
 | 
			
		||||
      platforms "x64-mingw32"
 | 
			
		||||
      dep "thin"
 | 
			
		||||
      should_resolve_as %w(thin-1.2.7-x64-mingw32)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "finds universal-mingw gems on x86-mingw" do
 | 
			
		||||
      platform "x86-mingw32"
 | 
			
		||||
      dep "win32-api"
 | 
			
		||||
      should_resolve_as %w(win32-api-1.5.1-universal-mingw32)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "finds universal-mingw gems on x64-mingw" do
 | 
			
		||||
      platform "x64-mingw32"
 | 
			
		||||
      dep "win32-api"
 | 
			
		||||
      should_resolve_as %w(win32-api-1.5.1-universal-mingw32)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "with conflicting cases" do
 | 
			
		||||
    before :each do
 | 
			
		||||
      @index = build_index do
 | 
			
		||||
        gem "foo", "1.0.0" do
 | 
			
		||||
          dep "bar", ">= 0"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        gem "bar", "1.0.0" do
 | 
			
		||||
          dep "baz", "~> 1.0.0"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        gem "bar", "1.0.0", "java" do
 | 
			
		||||
          dep "baz", " ~> 1.1.0"
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        gem "baz", %w(1.0.0 1.1.0 1.2.0)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it "reports on the conflict" do
 | 
			
		||||
      platforms "ruby", "java"
 | 
			
		||||
      dep "foo"
 | 
			
		||||
 | 
			
		||||
      should_conflict_on "baz"
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue