From 6b40a8a22bfb3f04e677a3de4d5b9329c689d2c2 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 23 Jun 2017 17:13:11 -0500 Subject: Get the Bundler 2 specs passing with transitive source pinning --- .rubocop_todo.yml | 1 + lib/bundler/dsl.rb | 14 +- lib/bundler/plugin/installer.rb | 13 +- lib/bundler/source_list.rb | 14 +- spec/bundler/definition_spec.rb | 40 +- spec/bundler/plugin/installer_spec.rb | 1 + spec/bundler/source_list_spec.rb | 39 +- spec/commands/add_spec.rb | 2 +- spec/commands/exec_spec.rb | 20 +- spec/commands/install_spec.rb | 8 +- spec/commands/lock_spec.rb | 2 +- spec/install/bundler_spec.rb | 2 +- spec/install/deploy_spec.rb | 5 +- spec/install/gemfile/gemspec_spec.rb | 103 ++- spec/install/gemfile/path_spec.rb | 14 +- spec/install/gems/compact_index_spec.rb | 2 +- spec/lock/lockfile_bundler_1_spec.rb | 1382 +++++++++++++++++++++++++++++++ spec/lock/lockfile_spec.rb | 122 +-- spec/plugins/source/example_spec.rb | 29 +- spec/quality_spec.rb | 2 +- spec/resolver/basic_spec.rb | 2 +- spec/runtime/inline_spec.rb | 15 +- spec/runtime/require_spec.rb | 79 +- spec/runtime/setup_spec.rb | 5 +- spec/support/indexes.rb | 8 +- spec/update/git_spec.rb | 38 +- 26 files changed, 1818 insertions(+), 144 deletions(-) create mode 100644 spec/lock/lockfile_bundler_1_spec.rb diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 74a89bab6f..2eaf40e8de 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -73,6 +73,7 @@ Lint/AmbiguousBlockAssociation: - 'spec/commands/install_spec.rb' - 'spec/install/gems/flex_spec.rb' - 'spec/lock/lockfile_spec.rb' + - 'spec/lock/lockfile_bundler_1_spec.rb' - 'spec/other/major_deprecation_spec.rb' - 'spec/runtime/setup_spec.rb' - 'spec/support/helpers.rb' diff --git a/lib/bundler/dsl.rb b/lib/bundler/dsl.rb index 097e83298c..5435512810 100644 --- a/lib/bundler/dsl.rb +++ b/lib/bundler/dsl.rb @@ -172,10 +172,10 @@ module Bundler "the path method, like: \n\n" \ " path 'dir/containing/rails' do\n" \ " gem 'rails'\n" \ - " end" + " end\n\n" raise DeprecatedError, msg if Bundler.feature_flag.disable_multisource? - SharedHelpers.major_deprecation(msg) + SharedHelpers.major_deprecation(msg.strip) end source_options = normalize_hash(options).merge( @@ -446,10 +446,14 @@ repo_name ||= user_name return if source_list.rubygems_primary_remotes.empty? && source_list.global_rubygems_source.nil? if Bundler.feature_flag.disable_multisource? - raise GemfileError, "Warning: this Gemfile contains multiple primary sources. " \ + msg = "This Gemfile contains multiple primary sources. " \ "Each source after the first must include a block to indicate which gems " \ - "should come from that source. To downgrade this error to a warning, run " \ - "`bundle config --delete disable_multisource`" + "should come from that source" + unless Bundler.feature_flag.bundler_2_mode? + msg += ". To downgrade this error to a warning, run " \ + "`bundle config --delete disable_multisource`" + end + raise GemfileEvalError, msg else Bundler::SharedHelpers.major_deprecation "Your Gemfile contains multiple primary sources. " \ "Using `source` more than once without a block is a security risk, and " \ diff --git a/lib/bundler/plugin/installer.rb b/lib/bundler/plugin/installer.rb index a50d0ceedd..5379c38979 100644 --- a/lib/bundler/plugin/installer.rb +++ b/lib/bundler/plugin/installer.rb @@ -13,12 +13,13 @@ module Bundler def install(names, options) version = options[:version] || [">= 0"] - - if options[:git] - install_git(names, version, options) - else - sources = options[:source] || Bundler.rubygems.sources - install_rubygems(names, version, sources) + Bundler.settings.temporary(:lockfile_uses_separate_rubygems_sources => false, :disable_multisource => false) do + if options[:git] + install_git(names, version, options) + else + sources = options[:source] || Bundler.rubygems.sources + install_rubygems(names, version, sources) + end end end diff --git a/lib/bundler/source_list.rb b/lib/bundler/source_list.rb index c68eb51d59..136650e436 100644 --- a/lib/bundler/source_list.rb +++ b/lib/bundler/source_list.rb @@ -41,7 +41,7 @@ module Bundler def global_rubygems_source=(uri) if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? - @global_rubygems_source ||= Source::Rubygems.new("remotes" => uri) + @global_rubygems_source ||= rubygems_aggregate_class.new("remotes" => uri) end add_rubygems_remote(uri) end @@ -77,7 +77,7 @@ module Bundler def lock_sources if Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? - [rubygems_sources, git_sources, path_sources, plugin_sources].map do |sources| + [[default_source], @rubygems_sources, git_sources, path_sources, plugin_sources].map do |sources| sources.sort_by(&:to_s) end.flatten(1) else @@ -86,6 +86,7 @@ module Bundler end end + # Returns true if there are changes def replace_sources!(replacement_sources) return true if replacement_sources.empty? @@ -95,13 +96,14 @@ module Bundler end end - replacement_rubygems = + replacement_rubygems = !Bundler.feature_flag.lockfile_uses_separate_rubygems_sources? && replacement_sources.detect {|s| s.is_a?(Source::Rubygems) } @rubygems_aggregate = replacement_rubygems if replacement_rubygems - # Return true if there were changes - lock_sources.to_set != replacement_sources.to_set || - rubygems_remotes.to_set != replacement_rubygems.remotes.to_set + return true if lock_sources.to_set != replacement_sources.to_set + return true if replacement_rubygems && rubygems_remotes.to_set != replacement_rubygems.remotes.to_set + + false end def cached! diff --git a/spec/bundler/definition_spec.rb b/spec/bundler/definition_spec.rb index cb642da9f7..ca280c70a1 100644 --- a/spec/bundler/definition_spec.rb +++ b/spec/bundler/definition_spec.rb @@ -31,7 +31,7 @@ RSpec.describe Bundler::Definition do end describe "detects changes" do - it "for a path gem with changes" do + it "for a path gem with changes", :bundler => "< 2" do build_lib "foo", "1.0", :path => lib_path("foo") install_gemfile <<-G @@ -69,6 +69,44 @@ RSpec.describe Bundler::Definition do G end + it "for a path gem with changes", :bundler => "2" do + build_lib "foo", "1.0", :path => lib_path("foo") + + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "foo", :path => "#{lib_path("foo")}" + G + + build_lib "foo", "1.0", :path => lib_path("foo") do |s| + s.add_dependency "rack", "1.0" + end + + bundle :install, :env => { "DEBUG" => 1 } + + expect(out).to match(/re-resolving dependencies/) + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PATH + remote: #{lib_path("foo")} + specs: + foo (1.0) + rack (= 1.0) + + PLATFORMS + ruby + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + it "for a path gem with deps and no changes" do build_lib "foo", "1.0", :path => lib_path("foo") do |s| s.add_dependency "rack", "1.0" diff --git a/spec/bundler/plugin/installer_spec.rb b/spec/bundler/plugin/installer_spec.rb index 8ede96ffea..f8bf8450c9 100644 --- a/spec/bundler/plugin/installer_spec.rb +++ b/spec/bundler/plugin/installer_spec.rb @@ -10,6 +10,7 @@ RSpec.describe Bundler::Plugin::Installer do describe "cli install" do it "uses Gem.sources when non of the source is provided" do sources = double(:sources) + Bundler.settings # initialize it before we have to touch rubygems.ext_lock allow(Bundler).to receive_message_chain("rubygems.sources") { sources } allow(installer).to receive(:install_rubygems). diff --git a/spec/bundler/source_list_spec.rb b/spec/bundler/source_list_spec.rb index 5489b367ec..915b638a46 100644 --- a/spec/bundler/source_list_spec.rb +++ b/spec/bundler/source_list_spec.rb @@ -115,18 +115,19 @@ RSpec.describe Bundler::SourceList do end end - describe "#add_rubygems_remote" do - before do - @returned_source = source_list.add_rubygems_remote("https://rubygems.org/") - end + describe "#add_rubygems_remote", :bundler => "< 2" do + let!(:returned_source) { source_list.add_rubygems_remote("https://rubygems.org/") } it "returns the aggregate rubygems source" do - expect(@returned_source).to be_instance_of(Bundler::Source::Rubygems) + 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/")) + expect(returned_source.remotes).to eq [ + URI("https://othersource.org/"), + URI("https://rubygems.org/"), + ] end end @@ -355,7 +356,7 @@ RSpec.describe Bundler::SourceList do end describe "#lock_sources" do - it "combines the rubygems sources into a single instance, removing duplicate remotes from the end" do + before do source_list.add_git_source("uri" => "git://third-git.org/path.git") source_list.add_rubygems_source("remotes" => ["https://duplicate-rubygems.org"]) source_list.add_plugin_source("new_source", "uri" => "https://third-bar.org/foo") @@ -369,7 +370,9 @@ RSpec.describe Bundler::SourceList do source_list.add_path_source("path" => "/first/path/to/gem") source_list.add_rubygems_source("remotes" => ["https://duplicate-rubygems.org"]) source_list.add_git_source("uri" => "git://first-git.org/path.git") + end + it "combines the rubygems sources into a single instance, removing duplicate remotes from the end", :bundler => "< 2" do 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"), @@ -387,6 +390,24 @@ RSpec.describe Bundler::SourceList do ]), ] end + + it "returns all sources, without combining rubygems sources", :bundler => "2" do + expect(source_list.lock_sources).to eq [ + Bundler::Source::Rubygems.new, + Bundler::Source::Rubygems.new("remotes" => ["https://duplicate-rubygems.org"]), + 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::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"), + ASourcePlugin.new("uri" => "https://second-plugin.org/random"), + ASourcePlugin.new("uri" => "https://third-bar.org/foo"), + ] + end end describe "replace_sources!" do @@ -415,7 +436,7 @@ RSpec.describe Bundler::SourceList do end describe "#cached!" do - let(:rubygems_source) { source_list.add_rubygems_remote("https://rubygems.org") } + let(:rubygems_source) { source_list.add_rubygems_source("remotes" => ["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") } @@ -428,7 +449,7 @@ RSpec.describe Bundler::SourceList do end describe "#remote!" do - let(:rubygems_source) { source_list.add_rubygems_remote("https://rubygems.org") } + let(:rubygems_source) { source_list.add_rubygems_source("remotes" => ["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") } diff --git a/spec/commands/add_spec.rb b/spec/commands/add_spec.rb index 36e696da0b..aebe8442d1 100644 --- a/spec/commands/add_spec.rb +++ b/spec/commands/add_spec.rb @@ -92,7 +92,7 @@ RSpec.describe "bundle add" do it "shows error message when gem cannot be found" do bundle "add 'werk_it'" - expect(out).to match("Could not find gem 'werk_it' in any of the gem sources listed in your Gemfile.") + expect(out).to match("Could not find gem 'werk_it' in") bundle "add 'werk_it' -s='file://#{gem_repo2}'" expect(out).to match("Could not find gem 'werk_it' in rubygems repository") diff --git a/spec/commands/exec_spec.rb b/spec/commands/exec_spec.rb index cc5989790e..c2e3b88fdd 100644 --- a/spec/commands/exec_spec.rb +++ b/spec/commands/exec_spec.rb @@ -589,7 +589,7 @@ RSpec.describe "bundle exec" do it_behaves_like "it runs" end - context "when Bundler.setup fails" do + context "when Bundler.setup fails", :bundler => "< 2" do before do gemfile <<-G gem 'rack', '2' @@ -606,6 +606,24 @@ RSpec.describe "bundle exec" do it_behaves_like "it runs" end + context "when Bundler.setup fails", :bundler => "2" do + before do + gemfile <<-G + gem 'rack', '2' + G + ENV["BUNDLER_FORCE_TTY"] = "true" + end + + let(:exit_code) { Bundler::GemNotFound.new.status_code } + let(:expected) { <<-EOS.strip } +\e[31mCould not find gem 'rack (= 2)' in locally installed gems. +The source contains 'rack' at: 0.9.1, 1.0.0\e[0m +\e[33mRun `bundle install` to install missing gems.\e[0m + EOS + + it_behaves_like "it runs" + end + context "when the executable exits non-zero via at_exit" do let(:executable) { super() + "\n\nat_exit { $! ? raise($!) : exit(1) }" } let(:exit_code) { 1 } diff --git a/spec/commands/install_spec.rb b/spec/commands/install_spec.rb index 5be6c40a44..23dcdd1806 100644 --- a/spec/commands/install_spec.rb +++ b/spec/commands/install_spec.rb @@ -280,7 +280,7 @@ RSpec.describe "bundle install with gem sources" do end end - it "finds gems in multiple sources" do + it "finds gems in multiple sources", :bundler => "< 2" do build_repo2 update_repo2 @@ -314,9 +314,9 @@ RSpec.describe "bundle install with gem sources" do it "gracefully handles error when rubygems server is unavailable" do install_gemfile <<-G, :artifice => nil source "file://#{gem_repo1}" - source "http://localhost:9384" - - gem 'foo' + source "http://localhost:9384" do + gem 'foo' + end G bundle :install, :artifice => nil diff --git a/spec/commands/lock_spec.rb b/spec/commands/lock_spec.rb index 11742dede6..83bd233d6d 100644 --- a/spec/commands/lock_spec.rb +++ b/spec/commands/lock_spec.rb @@ -86,7 +86,7 @@ RSpec.describe "bundle lock" do it "does not fetch remote specs when using the --local option" do bundle "lock --update --local" - expect(out).to include("sources listed in your Gemfile") + expect(out).to match(/sources listed in your Gemfile|installed locally/) end it "writes to a custom location using --lockfile" do diff --git a/spec/install/bundler_spec.rb b/spec/install/bundler_spec.rb index d0ce331f7d..ecddff616a 100644 --- a/spec/install/bundler_spec.rb +++ b/spec/install/bundler_spec.rb @@ -46,7 +46,7 @@ RSpec.describe "bundle install" do This Gemfile requires a different version of Bundler. Perhaps you need to update Bundler by running `gem install bundler`? - Could not find gem 'bundler (= 0.9.2)' in any of the sources. + Could not find gem 'bundler (= 0.9.2)' in any E expect(last_command.bundler_err).to include(nice_error) end diff --git a/spec/install/deploy_spec.rb b/spec/install/deploy_spec.rb index 032ff01b66..8ef948de77 100644 --- a/spec/install/deploy_spec.rb +++ b/spec/install/deploy_spec.rb @@ -93,15 +93,14 @@ RSpec.describe "install with --deployment or --frozen" do end it "works with sources given by a block" do - install_gemfile <<-G + install_gemfile! <<-G source "file://#{gem_repo1}" do gem "rack" end G - bundle "install --deployment" + bundle! "install --deployment" - expect(exitstatus).to eq(0) if exitstatus expect(the_bundle).to include_gems "rack 1.0" end diff --git a/spec/install/gemfile/gemspec_spec.rb b/spec/install/gemfile/gemspec_spec.rb index 4f1a69688c..e04dafb2fa 100644 --- a/spec/install/gemfile/gemspec_spec.rb +++ b/spec/install/gemfile/gemspec_spec.rb @@ -424,7 +424,7 @@ RSpec.describe "bundle install from an existing gemspec" do end end - context "on ruby" do + context "on ruby", :bundler => "< 2" do before do simulate_platform("ruby") bundle :install @@ -524,6 +524,107 @@ RSpec.describe "bundle install from an existing gemspec" do end end end + + context "on ruby", :bundler => "2" do + before do + simulate_platform("ruby") + bundle :install + end + + context "as a runtime dependency" do + it "keeps java dependencies in the lockfile" do + expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" + expect(lockfile).to eq strip_whitespace(<<-L) + GEM + remote: file:#{gem_repo2}/ + specs: + platform_specific (1.0) + platform_specific (1.0-java) + + PATH + remote: . + specs: + foo (1.0) + platform_specific + + 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 + expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" + expect(lockfile).to eq strip_whitespace(<<-L) + GEM + remote: file:#{gem_repo2}/ + specs: + platform_specific (1.0) + platform_specific (1.0-java) + + PATH + remote: . + specs: + foo (1.0) + + 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 + expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY" + expect(lockfile).to eq strip_whitespace(<<-L) + GEM + remote: file:#{gem_repo2}/ + specs: + indirect_platform_specific (1.0) + platform_specific + platform_specific (1.0) + platform_specific (1.0-java) + + PATH + remote: . + specs: + foo (1.0) + + PLATFORMS + java + ruby + + DEPENDENCIES + foo! + indirect_platform_specific + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + end end end diff --git a/spec/install/gemfile/path_spec.rb b/spec/install/gemfile/path_spec.rb index e76d5c486e..5f5e82074b 100644 --- a/spec/install/gemfile/path_spec.rb +++ b/spec/install/gemfile/path_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe "bundle install with explicit source paths" do - it "fetches gems" do + it "fetches gems with a global path source", :bundler => "< 2" do build_lib "foo" install_gemfile <<-G @@ -12,6 +12,18 @@ RSpec.describe "bundle install with explicit source paths" do expect(the_bundle).to include_gems("foo 1.0") end + it "fetches gems" do + build_lib "foo" + + install_gemfile <<-G + path "#{lib_path("foo-1.0")}" do + gem 'foo' + end + G + + expect(the_bundle).to include_gems("foo 1.0") + end + it "supports pinned paths" do build_lib "foo" diff --git a/spec/install/gems/compact_index_spec.rb b/spec/install/gems/compact_index_spec.rb index ad1abe2e89..c9eae35016 100644 --- a/spec/install/gems/compact_index_spec.rb +++ b/spec/install/gems/compact_index_spec.rb @@ -539,7 +539,7 @@ The checksum of /versions does not match the checksum provided by the server! So expect(out).not_to include("#{user}:#{password}") end - it "strips http basic auth creds when warning about ambiguous sources" do + it "strips http basic auth creds when warning about ambiguous sources", :bundler => "< 2" do gemfile <<-G source "#{basic_auth_source_uri}" source "file://#{gem_repo1}" diff --git a/spec/lock/lockfile_bundler_1_spec.rb b/spec/lock/lockfile_bundler_1_spec.rb new file mode 100644 index 0000000000..209c70be78 --- /dev/null +++ b/spec/lock/lockfile_bundler_1_spec.rb @@ -0,0 +1,1382 @@ +# frozen_string_literal: true + +RSpec.describe "the lockfile format", :bundler => "< 2" do + include Bundler::GemHelpers + + it "generates a simple lockfile for a single source, gem" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "updates the lockfile's bundler version if current ver. is newer" do + lockfile <<-L + GIT + remote: git://github.com/nex3/haml.git + revision: 8a2271f + specs: + + GEM + remote: file://#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + omg! + rack + + BUNDLED WITH + 1.8.2 + L + + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not update the lockfile's bundler version if nothing changed during bundle install" do + version = "#{Bundler::VERSION.split(".").first}.0.0.0.a" + + lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + #{version} + L + + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + #{version} + G + end + + it "updates the lockfile's bundler version if not present" do + lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + L + + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack", "> 0" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack (> 0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "outputs a warning if the current is older than lockfile's bundler version" do + lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + 9999999.1.0 + L + + simulate_bundler_version "9999999.0.0" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + end + + warning_message = "the running version of Bundler (9999999.0.0) is older " \ + "than the version that created the lockfile (9999999.1.0)" + expect(out.scan(warning_message).size).to eq(1) + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + 9999999.1.0 + G + end + + it "errors if the current is a major version older than lockfile's bundler version" do + lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + 9999999.0.0 + L + + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + + expect(exitstatus > 0) if exitstatus + expect(out).to include("You must use Bundler 9999999 or greater with this lockfile.") + end + + it "shows a friendly error when running with a new bundler 2 lockfile" do + lockfile <<-L + GEM + remote: https://rails-assets.org/ + specs: + rails-assets-bootstrap (3.3.4) + rails-assets-jquery (>= 1.9.1) + rails-assets-jquery (2.1.4) + + GEM + remote: https://rubygems.org/ + specs: + rake (10.4.2) + + PLATFORMS + ruby + + DEPENDENCIES + rails-assets-bootstrap! + rake + + BUNDLED WITH + 9999999.0.0 + L + + install_gemfile <<-G + source 'https://rubygems.org' + gem 'rake' + + source 'https://rails-assets.org' do + gem 'rails-assets-bootstrap' + end + G + + expect(exitstatus > 0) if exitstatus + expect(out).to include("You must use Bundler 9999999 or greater with this lockfile.") + end + + it "warns when updating bundler major version" do + lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + 1.10.0 + L + + simulate_bundler_version "9999999.0.0" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + end + + expect(out).to include("Warning: the lockfile is being updated to Bundler " \ + "9999999, after which you will be unable to return to Bundler 1.") + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack + + BUNDLED WITH + 9999999.0.0 + G + end + + it "generates a simple lockfile for a single source, gem with dependencies" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack-obama" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + rack-obama (1.0) + rack + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack-obama + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "generates a simple lockfile for a single source, gem with a version requirement" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack-obama", ">= 1.0" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + rack-obama (1.0) + rack + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack-obama (>= 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + 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/" + source "http://user:pass@othergemserver.test/" + + gem "rack-obama", ">= 1.0" + G + + lockfile_should_be <<-G + GEM + remote: http://localgemserver.test/ + remote: http://user:pass@othergemserver.test/ + specs: + rack (1.0.0) + rack-obama (1.0) + rack + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack-obama (>= 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "generates lockfiles with multiple requirements" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "net-sftp" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + net-sftp (1.1.1) + net-ssh (>= 1.0.0, < 1.99.0) + net-ssh (1.0) + + PLATFORMS + ruby + + DEPENDENCIES + net-sftp + + BUNDLED WITH + #{Bundler::VERSION} + G + + expect(the_bundle).to include_gems "net-sftp 1.1.1", "net-ssh 1.0.0" + end + + it "generates a simple lockfile for a single pinned source, gem with a version requirement" do + git = build_git "foo" + + install_gemfile <<-G + gem "foo", :git => "#{lib_path("foo-1.0")}" + G + + lockfile_should_be <<-G + GIT + remote: #{lib_path("foo-1.0")} + revision: #{git.ref_for("master")} + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + 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 + source "file://#{gem_repo1}" + + platforms :#{not_local_tag} do + gem "omg", :path => "#{lib_path("omg")}" + end + + gem "rack" + G + + lockfile <<-L + GIT + remote: git://github.com/nex3/haml.git + revision: 8a2271f + specs: + + GEM + remote: file://#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{not_local} + + DEPENDENCIES + omg! + rack + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "install" + expect(the_bundle).to include_gems "rack 1.0.0" + end + + it "serializes global git sources" do + git = build_git "foo" + + install_gemfile <<-G + git "#{lib_path("foo-1.0")}" do + gem "foo" + end + G + + lockfile_should_be <<-G + GIT + remote: #{lib_path("foo-1.0")} + revision: #{git.ref_for("master")} + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "generates a lockfile with a ref for a single pinned source, git gem with a branch requirement" do + git = build_git "foo" + update_git "foo", :branch => "omg" + + install_gemfile <<-G + gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg" + G + + lockfile_should_be <<-G + GIT + remote: #{lib_path("foo-1.0")} + revision: #{git.ref_for("omg")} + branch: omg + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "generates a lockfile with a ref for a single pinned source, git gem with a tag requirement" do + git = build_git "foo" + update_git "foo", :tag => "omg" + + install_gemfile <<-G + gem "foo", :git => "#{lib_path("foo-1.0")}", :tag => "omg" + G + + lockfile_should_be <<-G + GIT + remote: #{lib_path("foo-1.0")} + revision: #{git.ref_for("omg")} + tag: omg + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "serializes pinned path sources to the lockfile" do + build_lib "foo" + + install_gemfile <<-G + gem "foo", :path => "#{lib_path("foo-1.0")}" + G + + lockfile_should_be <<-G + PATH + remote: #{lib_path("foo-1.0")} + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "serializes pinned path sources to the lockfile even when packaging" do + build_lib "foo" + + install_gemfile! <<-G + gem "foo", :path => "#{lib_path("foo-1.0")}" + G + + bundle! "package --all" + bundle! "install --local" + + lockfile_should_be <<-G + PATH + remote: #{lib_path("foo-1.0")} + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + 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_local_platform} + + DEPENDENCIES + bar! + foo! + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "lists gems alphabetically" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "thin" + gem "actionpack" + gem "rack-obama" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + actionpack (2.3.2) + activesupport (= 2.3.2) + activesupport (2.3.2) + rack (1.0.0) + rack-obama (1.0) + rack + thin (1.0) + rack + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + actionpack + rack-obama + thin + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "orders dependencies' dependencies in alphabetical order" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rails" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + actionmailer (2.3.2) + activesupport (= 2.3.2) + actionpack (2.3.2) + activesupport (= 2.3.2) + activerecord (2.3.2) + activesupport (= 2.3.2) + activeresource (2.3.2) + activesupport (= 2.3.2) + activesupport (2.3.2) + rails (2.3.2) + actionmailer (= 2.3.2) + actionpack (= 2.3.2) + activerecord (= 2.3.2) + activeresource (= 2.3.2) + rake (= 10.0.2) + rake (10.0.2) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rails + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "orders dependencies by version" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem 'double_deps' + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + double_deps (1.0) + net-ssh + net-ssh (>= 1.0.0) + net-ssh (1.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + double_deps + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not add the :require option to the lockfile" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack-obama", ">= 1.0", :require => "rack/obama" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + rack-obama (1.0) + rack + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack-obama (>= 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not add the :group option to the lockfile" do + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack-obama", ">= 1.0", :group => :test + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + rack-obama (1.0) + rack + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + rack-obama (>= 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "stores relative paths when the path is provided in a relative fashion and in Gemfile dir" do + build_lib "foo", :path => bundled_app("foo") + + install_gemfile <<-G + path "foo" + gem "foo" + G + + lockfile_should_be <<-G + PATH + remote: foo + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "stores relative paths when the path is provided in a relative fashion and is above Gemfile dir" do + build_lib "foo", :path => bundled_app(File.join("..", "foo")) + + install_gemfile <<-G + path "../foo" + gem "foo" + G + + lockfile_should_be <<-G + PATH + remote: ../foo + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "stores relative paths when the path is provided in an absolute fashion but is relative" do + build_lib "foo", :path => bundled_app("foo") + + install_gemfile <<-G + path File.expand_path("../foo", __FILE__) + gem "foo" + G + + lockfile_should_be <<-G + PATH + remote: foo + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "stores relative paths when the path is provided for gemspec" do + build_lib("foo", :path => tmp.join("foo")) + + install_gemfile <<-G + gemspec :path => "../foo" + G + + lockfile_should_be <<-G + PATH + remote: ../foo + specs: + foo (1.0) + + GEM + specs: + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "keeps existing platforms in the lockfile" do + lockfile <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + java + + DEPENDENCIES + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + + install_gemfile <<-G + source "file://#{gem_repo1}" + + gem "rack" + G + + platforms = ["java", generic_local_platform.to_s].sort + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + #{platforms[0]} + #{platforms[1]} + + DEPENDENCIES + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "persists the spec's platform to the lockfile" do + build_gem "platform_specific", "1.0.0", :to_system => true do |s| + s.platform = Gem::Platform.new("universal-java-16") + end + + simulate_platform "universal-java-16" + + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "platform_specific" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + platform_specific (1.0-java) + + PLATFORMS + java + + DEPENDENCIES + platform_specific + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not add duplicate gems" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack" + G + + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack" + gem "activesupport" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + activesupport (2.3.5) + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + activesupport + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not add duplicate dependencies" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack" + gem "rack" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not add duplicate dependencies with versions" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack", "1.0" + gem "rack", "1.0" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + rack (= 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "does not add duplicate dependencies in different groups" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack", "1.0", :group => :one + gem "rack", "1.0", :group => :two + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + + PLATFORMS + ruby + + DEPENDENCIES + rack (= 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "raises if two different versions are used" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack", "1.0" + gem "rack", "1.1" + G + + expect(bundled_app("Gemfile.lock")).not_to exist + expect(out).to include "rack (= 1.0) and rack (= 1.1)" + end + + it "raises if two different sources are used" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack" + gem "rack", :git => "git://hubz.com" + G + + expect(bundled_app("Gemfile.lock")).not_to exist + expect(out).to include "rack (>= 0) should come from an unspecified source and git://hubz.com (at master)" + end + + it "works correctly with multiple version dependencies" do + install_gemfile <<-G + source "file://#{gem_repo1}" + gem "rack", "> 0.9", "< 1.0" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (0.9.1) + + PLATFORMS + ruby + + DEPENDENCIES + rack (> 0.9, < 1.0) + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + it "captures the Ruby version in the lockfile" do + install_gemfile <<-G + source "file://#{gem_repo1}" + ruby '#{RUBY_VERSION}' + gem "rack", "> 0.9", "< 1.0" + G + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (0.9.1) + + PLATFORMS + ruby + + DEPENDENCIES + rack (> 0.9, < 1.0) + + RUBY VERSION + ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL} + + BUNDLED WITH + #{Bundler::VERSION} + G + end + + # Some versions of the Bundler 1.1 RC series introduced corrupted + # lockfiles. There were two major problems: + # + # * multiple copies of the same GIT section appeared in the lockfile + # * when this happened, those sections got multiple copies of gems + # in those sections. + it "fixes corrupted lockfiles" do + build_git "omg", :path => lib_path("omg") + revision = revision_for(lib_path("omg")) + + gemfile <<-G + source "file://#{gem_repo1}" + gem "omg", :git => "#{lib_path("omg")}", :branch => 'master' + G + + bundle "install --path vendor" + expect(the_bundle).to include_gems "omg 1.0" + + # Create a Gemfile.lock that has duplicate GIT sections + lockfile <<-L + GIT + remote: #{lib_path("omg")} + revision: #{revision} + branch: master + specs: + omg (1.0) + + GIT + remote: #{lib_path("omg")} + revision: #{revision} + branch: master + specs: + omg (1.0) + + GEM + remote: file:#{gem_repo1}/ + specs: + + PLATFORMS + #{local} + + DEPENDENCIES + omg! + + BUNDLED WITH + #{Bundler::VERSION} + L + + FileUtils.rm_rf(bundled_app("vendor")) + bundle "install" + expect(the_bundle).to include_gems "omg 1.0" + + # Confirm that duplicate specs do not appear + expect(File.read(bundled_app("Gemfile.lock"))).to eq(strip_whitespace(<<-L)) + GIT + remote: #{lib_path("omg")} + revision: #{revision} + branch: master + specs: + omg (1.0) + + GEM + remote: file:#{gem_repo1}/ + specs: + + PLATFORMS + #{local} + + DEPENDENCIES + omg! + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "raises a helpful error message when the lockfile is missing deps" do + lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + rack_middleware (1.0) + + PLATFORMS + #{local} + + DEPENDENCIES + rack_middleware + L + + install_gemfile <<-G + source "file:#{gem_repo1}" + gem "rack_middleware" + G + + expect(out).to include("Downloading rack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("rack", "= 0.9.1")})."). + and include("Either installing with `--full-index` or running `bundle update rack_middleware` should fix the problem.") + end + + describe "a line ending" do + def set_lockfile_mtime_to_known_value + time = Time.local(2000, 1, 1, 0, 0, 0) + File.utime(time, time, bundled_app("Gemfile.lock")) + end + before(:each) do + build_repo2 + + install_gemfile <<-G + source "file://#{gem_repo2}" + gem "rack" + G + set_lockfile_mtime_to_known_value + end + + it "generates Gemfile.lock with \\n line endings" do + expect(File.read(bundled_app("Gemfile.lock"))).not_to match("\r\n") + expect(the_bundle).to include_gems "rack 1.0" + end + + context "during updates" do + it "preserves Gemfile.lock \\n line endings" do + update_repo2 + + expect { bundle "update", :all => true }.to change { File.mtime(bundled_app("Gemfile.lock")) } + expect(File.read(bundled_app("Gemfile.lock"))).not_to match("\r\n") + expect(the_bundle).to include_gems "rack 1.2" + end + + it "preserves Gemfile.lock \\n\\r line endings" do + update_repo2 + win_lock = File.read(bundled_app("Gemfile.lock")).gsub(/\n/, "\r\n") + File.open(bundled_app("Gemfile.lock"), "wb") {|f| f.puts(win_lock) } + set_lockfile_mtime_to_known_value + + expect { bundle "update", :all => true }.to change { File.mtime(bundled_app("Gemfile.lock")) } + expect(File.read(bundled_app("Gemfile.lock"))).to match("\r\n") + expect(the_bundle).to include_gems "rack 1.2" + end + end + + context "when nothing changes" do + it "preserves Gemfile.lock \\n line endings" do + expect do + ruby <<-RUBY + require 'rubygems' + require 'bundler' + Bundler.setup + RUBY + end.not_to change { File.mtime(bundled_app("Gemfile.lock")) } + end + + it "preserves Gemfile.lock \\n\\r line endings" do + win_lock = File.read(bundled_app("Gemfile.lock")).gsub(/\n/, "\r\n") + File.open(bundled_app("Gemfile.lock"), "wb") {|f| f.puts(win_lock) } + set_lockfile_mtime_to_known_value + + expect do + ruby <<-RUBY + require 'rubygems' + require 'bundler' + Bundler.setup + RUBY + end.not_to change { File.mtime(bundled_app("Gemfile.lock")) } + end + end + end + + it "refuses to install if Gemfile.lock contains conflict markers" do + lockfile <<-L + GEM + remote: file://#{gem_repo1}/ + specs: + <<<<<<< + rack (1.0.0) + ======= + rack (1.0.1) + >>>>>>> + + PLATFORMS + ruby + + DEPENDENCIES + rack + + BUNDLED WITH + #{Bundler::VERSION} + L + + install_gemfile(<<-G) + source "file://#{gem_repo1}" + gem "rack" + G + + expect(last_command.bundler_err).to match(/your Gemfile.lock contains merge conflicts/i) + expect(last_command.bundler_err).to match(/git checkout HEAD -- Gemfile.lock/i) + end +end diff --git a/spec/lock/lockfile_spec.rb b/spec/lock/lockfile_spec.rb index 149372472d..2c4f2a6679 100644 --- a/spec/lock/lockfile_spec.rb +++ b/spec/lock/lockfile_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe "the lockfile format" do +RSpec.describe "the lockfile format", :bundler => "2" do include Bundler::GemHelpers it "generates a simple lockfile for a single source, gem" do @@ -360,19 +360,28 @@ RSpec.describe "the lockfile format" do G end - it "generates a lockfile wihout credentials for a configured source" do + it "generates a lockfile without 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/" - source "http://user:pass@othergemserver.test/" + source "http://localgemserver.test/" do - gem "rack-obama", ">= 1.0" + end + + source "http://user:pass@othergemserver.test/" do + gem "rack-obama", ">= 1.0" + end G lockfile_should_be <<-G + GEM + specs: + GEM remote: http://localgemserver.test/ + specs: + + GEM remote: http://user:pass@othergemserver.test/ specs: rack (1.0.0) @@ -383,7 +392,7 @@ RSpec.describe "the lockfile format" do #{generic_local_platform} DEPENDENCIES - rack-obama (>= 1.0) + rack-obama (>= 1.0)! BUNDLED WITH #{Bundler::VERSION} @@ -494,15 +503,15 @@ RSpec.describe "the lockfile format" do G lockfile_should_be <<-G + GEM + specs: + GIT remote: #{lib_path("foo-1.0")} revision: #{git.ref_for("master")} specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} @@ -523,6 +532,9 @@ RSpec.describe "the lockfile format" do G lockfile_should_be <<-G + GEM + specs: + GIT remote: #{lib_path("foo-1.0")} revision: #{git.ref_for("omg")} @@ -530,9 +542,6 @@ RSpec.describe "the lockfile format" do specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} @@ -553,6 +562,9 @@ RSpec.describe "the lockfile format" do G lockfile_should_be <<-G + GEM + specs: + GIT remote: #{lib_path("foo-1.0")} revision: #{git.ref_for("omg")} @@ -560,9 +572,6 @@ RSpec.describe "the lockfile format" do specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} @@ -582,14 +591,14 @@ RSpec.describe "the lockfile format" do G lockfile_should_be <<-G + GEM + specs: + PATH remote: #{lib_path("foo-1.0")} specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} @@ -612,14 +621,14 @@ RSpec.describe "the lockfile format" do bundle! "install --local" lockfile_should_be <<-G + GEM + specs: + PATH remote: #{lib_path("foo-1.0")} specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} @@ -644,6 +653,11 @@ RSpec.describe "the lockfile format" do G lockfile_should_be <<-G + GEM + remote: file:#{gem_repo1}/ + specs: + rack (1.0.0) + GIT remote: #{lib_path("bar-1.0")} revision: #{bar.ref_for("master")} @@ -655,11 +669,6 @@ RSpec.describe "the lockfile format" do specs: foo (1.0) - GEM - remote: file:#{gem_repo1}/ - specs: - rack (1.0.0) - PLATFORMS #{generic_local_platform} @@ -829,24 +838,25 @@ RSpec.describe "the lockfile format" do build_lib "foo", :path => bundled_app("foo") install_gemfile <<-G - path "foo" - gem "foo" + path "foo" do + gem "foo" + end G lockfile_should_be <<-G + GEM + specs: + PATH remote: foo specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} DEPENDENCIES - foo + foo! BUNDLED WITH #{Bundler::VERSION} @@ -857,24 +867,25 @@ RSpec.describe "the lockfile format" do build_lib "foo", :path => bundled_app(File.join("..", "foo")) install_gemfile <<-G - path "../foo" - gem "foo" + path "../foo" do + gem "foo" + end G lockfile_should_be <<-G + GEM + specs: + PATH remote: ../foo specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} DEPENDENCIES - foo + foo! BUNDLED WITH #{Bundler::VERSION} @@ -885,24 +896,25 @@ RSpec.describe "the lockfile format" do build_lib "foo", :path => bundled_app("foo") install_gemfile <<-G - path File.expand_path("../foo", __FILE__) - gem "foo" + path File.expand_path("../foo", __FILE__) do + gem "foo" + end G lockfile_should_be <<-G + GEM + specs: + PATH remote: foo specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} DEPENDENCIES - foo + foo! BUNDLED WITH #{Bundler::VERSION} @@ -917,14 +929,14 @@ RSpec.describe "the lockfile format" do G lockfile_should_be <<-G + GEM + specs: + PATH remote: ../foo specs: foo (1.0) - GEM - specs: - PLATFORMS #{generic_local_platform} @@ -1203,6 +1215,10 @@ RSpec.describe "the lockfile format" do # Create a Gemfile.lock that has duplicate GIT sections lockfile <<-L + GEM + remote: file:#{gem_repo1}/ + specs: + GIT remote: #{lib_path("omg")} revision: #{revision} @@ -1217,10 +1233,6 @@ RSpec.describe "the lockfile format" do specs: omg (1.0) - GEM - remote: file:#{gem_repo1}/ - specs: - PLATFORMS #{local} @@ -1237,6 +1249,10 @@ RSpec.describe "the lockfile format" do # Confirm that duplicate specs do not appear expect(File.read(bundled_app("Gemfile.lock"))).to eq(strip_whitespace(<<-L)) + GEM + remote: file:#{gem_repo1}/ + specs: + GIT remote: #{lib_path("omg")} revision: #{revision} @@ -1244,10 +1260,6 @@ RSpec.describe "the lockfile format" do specs: omg (1.0) - GEM - remote: file:#{gem_repo1}/ - specs: - PLATFORMS #{local} diff --git a/spec/plugins/source/example_spec.rb b/spec/plugins/source/example_spec.rb index d898c1f95c..69e33e4077 100644 --- a/spec/plugins/source/example_spec.rb +++ b/spec/plugins/source/example_spec.rb @@ -326,7 +326,7 @@ RSpec.describe "real source plugins" do expect(the_bundle).to include_gems("ma-gitp-gem 1.0") end - it "writes to lock file" do + it "writes to lock file", :bundler => "< 2" do revision = revision_for(lib_path("ma-gitp-gem-1.0")) bundle "install" @@ -353,6 +353,33 @@ RSpec.describe "real source plugins" do G end + it "writes to lock file", :bundler => "2" do + revision = revision_for(lib_path("ma-gitp-gem-1.0")) + bundle "install" + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo2}/ + specs: + + PLUGIN SOURCE + remote: file://#{lib_path("ma-gitp-gem-1.0")} + type: gitp + revision: #{revision} + specs: + ma-gitp-gem (1.0) + + PLATFORMS + #{generic_local_platform} + + DEPENDENCIES + ma-gitp-gem! + + BUNDLED WITH + #{Bundler::VERSION} + G + end + context "with lockfile" do before do revision = revision_for(lib_path("ma-gitp-gem-1.0")) diff --git a/spec/quality_spec.rb b/spec/quality_spec.rb index 4561ce0461..bbdaa8b30d 100644 --- a/spec/quality_spec.rb +++ b/spec/quality_spec.rb @@ -131,7 +131,7 @@ RSpec.describe "The library itself" do it "does not include any unresolved merge conflicts" do error_messages = [] - exempt = %r{lock/lockfile_spec|quality_spec|vcr_cassettes|\.ronn|lockfile_parser\.rb} + exempt = %r{lock/lockfile_(bundler_1_)?spec|quality_spec|vcr_cassettes|\.ronn|lockfile_parser\.rb} Dir.chdir(root) do `git ls-files -z`.split("\x0").each do |filename| next if filename =~ exempt diff --git a/spec/resolver/basic_spec.rb b/spec/resolver/basic_spec.rb index 8d9aef2891..a34b905806 100644 --- a/spec/resolver/basic_spec.rb +++ b/spec/resolver/basic_spec.rb @@ -124,7 +124,7 @@ Bundler could not find compatible versions for gem "a": deps << Bundler::DepProxy.new(d, "ruby") end - should_resolve_and_include %w[foo-1.0.0 bar-1.0.0], [{}, []] + should_resolve_and_include %w[foo-1.0.0 bar-1.0.0], [[]] end context "conservative" do diff --git a/spec/runtime/inline_spec.rb b/spec/runtime/inline_spec.rb index 3ebcfd8852..2893920e44 100644 --- a/spec/runtime/inline_spec.rb +++ b/spec/runtime/inline_spec.rb @@ -52,8 +52,9 @@ RSpec.describe "bundler/inline#gemfile" do it "requires the gems" do script <<-RUBY gemfile do - path "#{lib_path}" - gem "two" + path "#{lib_path}" do + gem "two" + end end RUBY @@ -62,8 +63,9 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile do - path "#{lib_path}" - gem "eleven" + path "#{lib_path}" do + gem "eleven" + end end puts "success" @@ -132,8 +134,9 @@ RSpec.describe "bundler/inline#gemfile" do require 'bundler' options = { :ui => Bundler::UI::Shell.new } gemfile(false, options) do - path "#{lib_path}" - gem "two" + path "#{lib_path}" do + gem "two" + end end puts "OKAY" if options.key?(:ui) RUBY diff --git a/spec/runtime/require_spec.rb b/spec/runtime/require_spec.rb index 749f2a4e33..5dcbba5d06 100644 --- a/spec/runtime/require_spec.rb +++ b/spec/runtime/require_spec.rb @@ -46,19 +46,20 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - path "#{lib_path}" - gem "one", :group => :bar, :require => %w[baz qux] - gem "two" - gem "three", :group => :not - gem "four", :require => false - gem "five" - gem "six", :group => "string" - gem "seven", :group => :not - gem "eight", :require => true, :group => :require_true - env "BUNDLER_TEST" => "nine" do - gem "nine", :require => true + path "#{lib_path}" do + gem "one", :group => :bar, :require => %w[baz qux] + gem "two" + gem "three", :group => :not + gem "four", :require => false + gem "five" + gem "six", :group => "string" + gem "seven", :group => :not + gem "eight", :require => true, :group => :require_true + env "BUNDLER_TEST" => "nine" do + gem "nine", :require => true + end + gem "ten", :install_if => lambda { ENV["BUNDLER_TEST"] == "ten" } end - gem "ten", :install_if => lambda { ENV["BUNDLER_TEST"] == "ten" } G end @@ -111,8 +112,9 @@ RSpec.describe "Bundler.require" do it "raises an exception if a require is specified but the file does not exist" do gemfile <<-G - path "#{lib_path}" - gem "two", :require => 'fail' + path "#{lib_path}" do + gem "two", :require => 'fail' + end G load_error_run <<-R, "fail" @@ -128,8 +130,9 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - path "#{lib_path}" - gem "faulty" + path "#{lib_path}" do + gem "faulty" + end G run "Bundler.require" @@ -143,8 +146,9 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - path "#{lib_path}" - gem "loadfuuu" + path "#{lib_path}" do + gem "loadfuuu" + end G cmd = <<-RUBY @@ -169,8 +173,9 @@ RSpec.describe "Bundler.require" do it "requires gem names that are namespaced" do gemfile <<-G - path '#{lib_path}' - gem 'jquery-rails' + path '#{lib_path}' do + gem 'jquery-rails' + end G run "Bundler.require" @@ -182,8 +187,9 @@ RSpec.describe "Bundler.require" do s.write "lib/brcrypt.rb", "BCrypt = '1.0.0'" end gemfile <<-G - path "#{lib_path}" - gem "bcrypt-ruby" + path "#{lib_path}" do + gem "bcrypt-ruby" + end G cmd = <<-RUBY @@ -197,8 +203,9 @@ RSpec.describe "Bundler.require" do it "does not mangle explicitly given requires" do gemfile <<-G - path "#{lib_path}" - gem 'jquery-rails', :require => 'jquery-rails' + path "#{lib_path}" do + gem 'jquery-rails', :require => 'jquery-rails' + end G load_error_run <<-R, "jquery-rails" @@ -213,8 +220,9 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - path "#{lib_path}" - gem "load-fuuu" + path "#{lib_path}" do + gem "load-fuuu" + end G cmd = <<-RUBY @@ -236,8 +244,9 @@ RSpec.describe "Bundler.require" do lib_path("load-fuuu-1.0.0/lib/load-fuuu.rb").rmtree gemfile <<-G - path "#{lib_path}" - gem "load-fuuu" + path "#{lib_path}" do + gem "load-fuuu" + end G cmd = <<-RUBY @@ -293,9 +302,10 @@ RSpec.describe "Bundler.require" do it "works when the gems are in the Gemfile in the correct order" do gemfile <<-G - path "#{lib_path}" - gem "two" - gem "one" + path "#{lib_path}" do + gem "two" + gem "one" + end G run "Bundler.require" @@ -333,9 +343,10 @@ RSpec.describe "Bundler.require" do it "fails when the gems are in the Gemfile in the wrong order" do gemfile <<-G - path "#{lib_path}" - gem "one" - gem "two" + path "#{lib_path}" do + gem "one" + gem "two" + end G run "Bundler.require" diff --git a/spec/runtime/setup_spec.rb b/spec/runtime/setup_spec.rb index 909378ab02..ef02ce0630 100644 --- a/spec/runtime/setup_spec.rb +++ b/spec/runtime/setup_spec.rb @@ -395,9 +395,10 @@ RSpec.describe "Bundler.setup" do end gemfile <<-G - path "#{lib_path("rack-1.0.0")}" source "file://#{gem_repo1}" - gem "rack" + path "#{lib_path("rack-1.0.0")}" do + gem "rack" + end G run "require 'rack'" diff --git a/spec/support/indexes.rb b/spec/support/indexes.rb index bb941e66ab..1feff7d816 100644 --- a/spec/support/indexes.rb +++ b/spec/support/indexes.rb @@ -16,12 +16,16 @@ module Spec def resolve(args = []) @platforms ||= ["ruby"] deps = [] + default_source = instance_double("Bundler::Source::Rubygems", :specs => @index) + source_requirements = { :default => default_source } @deps.each do |d| @platforms.each do |p| + source_requirements[d.name] = d.source = default_source deps << Bundler::DepProxy.new(d, p) end end - Bundler::Resolver.resolve(deps, @index, *args) + source_requirements ||= {} + Bundler::Resolver.resolve(deps, @index, source_requirements, *args) end def should_resolve_as(specs) @@ -62,7 +66,7 @@ module Spec s.level = opts.first s.strict = opts.include?(:strict) end - should_resolve_and_include specs, [{}, @base, search] + should_resolve_and_include specs, [@base, search] end def an_awesome_index diff --git a/spec/update/git_spec.rb b/spec/update/git_spec.rb index c04e3c68b0..f7e10de666 100644 --- a/spec/update/git_spec.rb +++ b/spec/update/git_spec.rb @@ -294,7 +294,7 @@ RSpec.describe "bundle update" do G end - it "the --source flag updates version of gems that were originally pulled in by the source" do + it "the --source flag updates version of gems that were originally pulled in by the source", :bundler => "< 2" do spec_lines = lib_path("bar/foo.gemspec").read.split("\n") spec_lines[5] = "s.version = '2.0'" @@ -329,5 +329,41 @@ RSpec.describe "bundle update" do #{Bundler::VERSION} G end + + it "the --source flag updates version of gems that were originally pulled in by the source", :bundler => "2" do + spec_lines = lib_path("bar/foo.gemspec").read.split("\n") + spec_lines[5] = "s.version = '2.0'" + + update_git "foo", "2.0", :path => @git.path do |s| + s.write "foo.gemspec", spec_lines.join("\n") + end + + ref = @git.ref_for "master" + + bundle "update --source bar" + + lockfile_should_be <<-G + GEM + remote: file:#{gem_repo2}/ + specs: + rack (1.0.0) + + GIT + remote: #{@git.path} + revision: #{ref} + specs: + foo (2.0) + + PLATFORMS + ruby + + DEPENDENCIES + foo! + rack + + BUNDLED WITH + #{Bundler::VERSION} + G + end end end -- cgit v1.2.1