ruby/spec/bundler/lock/lockfile_spec.rb

2416 lines
52 KiB
Ruby

# frozen_string_literal: true
RSpec.describe "the lockfile format" do
before do
build_repo2
end
it "generates a simple lockfile for a single source, gem" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "myrack", "1.0.0")
end
install_gemfile <<-G
source "https://gem.repo2"
gem "myrack"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "updates the lockfile's bundler version if current ver. is newer, and version was forced through BUNDLER_VERSION" do
system_gems "bundler-1.8.2"
lockfile <<-L
GIT
remote: git://github.com/nex3/haml.git
revision: 8a2271f
specs:
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
omg!
myrack
BUNDLED WITH
1.8.2
L
install_gemfile <<-G, verbose: true, env: { "BUNDLER_VERSION" => Bundler::VERSION }
source "https://gem.repo2"
gem "myrack"
G
expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with 1.8.2.")
expect(out).to include("Using bundler #{Bundler::VERSION}")
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not update the lockfile's bundler version if nothing changed during bundle install, but uses the locked version" do
version = "2.3.0"
build_repo4 do
build_gem "myrack", "1.0.0"
build_bundler version
end
lockfile <<-L
GEM
remote: https://gem.repo4/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{version}
L
install_gemfile <<-G, verbose: true
source "https://gem.repo4"
gem "myrack"
G
expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{version}.")
expect(out).to include("Using bundler #{version}")
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo4/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{version}
G
end
it "adds the BUNDLED WITH section if not present" do
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
L
install_gemfile <<-G
source "https://gem.repo2"
gem "myrack", "> 0"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack (> 0)
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "update the bundler major version just fine" do
current_version = Bundler::VERSION
older_major = previous_major(current_version)
system_gems "bundler-#{older_major}"
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{older_major}
L
install_gemfile <<-G, env: { "BUNDLER_VERSION" => Bundler::VERSION }
source "https://gem.repo2/"
gem "myrack"
G
expect(err).to be_empty
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{current_version}
G
end
it "generates a simple lockfile for a single source, gem with dependencies" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack-obama"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama
#{checksums}
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 "https://gem.repo2/"
gem "myrack-obama", ">= 1.0"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama (>= 1.0)
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "generates a lockfile without credentials" do
bundle "config set https://localgemserver.test/ user:pass"
install_gemfile(<<-G, artifice: "endpoint_strict_basic_authentication", quiet: true)
source "https://gem.repo1"
source "https://localgemserver.test/" do
end
source "https://user:pass@othergemserver.test/" do
gem "myrack-obama", ">= 1.0"
end
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo1/
specs:
GEM
remote: https://localgemserver.test/
specs:
GEM
remote: https://othergemserver.test/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama (>= 1.0)!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add credentials to lockfile when it does not have them already" do
bundle "config set http://localgemserver.test/ user:pass"
gemfile <<~G
source "https://gem.repo1"
source "http://localgemserver.test/" do
end
source "http://user:pass@othergemserver.test/" do
gem "myrack-obama", ">= 1.0"
end
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
lockfile_without_credentials = <<~L
GEM
remote: http://localgemserver.test/
specs:
GEM
remote: http://othergemserver.test/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama (>= 1.0)!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
lockfile lockfile_without_credentials
# when not re-resolving
bundle "install", artifice: "endpoint_strict_basic_authentication", quiet: true
expect(lockfile).to eq lockfile_without_credentials
# when re-resolving with full unlock
bundle "update", artifice: "endpoint_strict_basic_authentication"
expect(lockfile).to eq lockfile_without_credentials
# when re-resolving without ful unlocking
bundle "update myrack-obama", artifice: "endpoint_strict_basic_authentication"
expect(lockfile).to eq lockfile_without_credentials
end
it "keeps credentials in lockfile if already there" do
bundle "config set http://localgemserver.test/ user:pass"
gemfile <<~G
source "https://gem.repo1"
source "http://localgemserver.test/" do
end
source "http://user:pass@othergemserver.test/" do
gem "myrack-obama", ">= 1.0"
end
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
lockfile_with_credentials = <<~L
GEM
remote: http://localgemserver.test/
specs:
GEM
remote: http://user:pass@othergemserver.test/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama (>= 1.0)!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
lockfile lockfile_with_credentials
bundle "install", artifice: "endpoint_strict_basic_authentication", quiet: true
expect(lockfile).to eq lockfile_with_credentials
end
it "generates lockfiles with multiple requirements" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "net-sftp"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "net-sftp", "1.1.1"
c.checksum gem_repo2, "net-ssh", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
net-sftp (1.1.1)
net-ssh (>= 1.0.0, < 1.99.0)
net-ssh (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
net-sftp
#{checksums}
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
source "https://gem.repo1"
gem "foo", :git => "#{lib_path("foo-1.0")}"
G
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
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 "https://gem.repo2/"
platforms :#{not_local_tag} do
gem "omg", :path => "#{lib_path("omg")}"
end
gem "myrack"
G
lockfile <<-L
GIT
remote: git://github.com/nex3/haml.git
revision: 8a2271f
specs:
GEM
remote: https://gem.repo2//
specs:
myrack (1.0.0)
PLATFORMS
#{not_local}
DEPENDENCIES
omg!
myrack
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(the_bundle).to include_gems "myrack 1.0.0"
end
it "serializes global git sources" do
git = build_git "foo"
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
git "#{lib_path("foo-1.0")}" do
gem "foo"
end
G
expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
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"
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg"
G
expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
branch: omg
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
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"
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
gem "foo", :git => "#{lib_path("foo-1.0")}", :tag => "omg"
G
expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("omg")}
tag: omg
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "is conservative with dependencies of git gems" do
build_repo4 do
build_gem "orm_adapter", "0.4.1"
build_gem "orm_adapter", "0.5.0"
end
FileUtils.mkdir_p lib_path("ckeditor/lib")
@remote = build_git("ckeditor_remote", bare: true)
build_git "ckeditor", path: lib_path("ckeditor") do |s|
s.write "lib/ckeditor.rb", "CKEDITOR = '4.0.7'"
s.version = "4.0.7"
s.add_dependency "orm_adapter"
end
update_git "ckeditor", path: lib_path("ckeditor"), remote: @remote.path
update_git "ckeditor", path: lib_path("ckeditor"), tag: "v4.0.7"
old_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.7"
update_git "ckeditor", path: lib_path("ckeditor"), gemspec: true do |s|
s.write "lib/ckeditor.rb", "CKEDITOR = '4.0.8'"
s.version = "4.0.8"
s.add_dependency "orm_adapter"
end
update_git "ckeditor", path: lib_path("ckeditor"), tag: "v4.0.8"
new_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.8"
gemfile <<-G
source "https://gem.repo4"
gem "ckeditor", :git => "#{@remote.path}", :tag => "v4.0.8"
G
lockfile <<~L
GIT
remote: #{@remote.path}
revision: #{old_git.ref_for("v4.0.7")}
tag: v4.0.7
specs:
ckeditor (4.0.7)
orm_adapter
GEM
remote: https://gem.repo4/
specs:
orm_adapter (0.4.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
ckeditor!
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "lock"
# Bumps the git gem, but keeps its dependency locked
expect(lockfile).to eq <<~L
GIT
remote: #{@remote.path}
revision: #{new_git.ref_for("v4.0.8")}
tag: v4.0.8
specs:
ckeditor (4.0.8)
orm_adapter
GEM
remote: https://gem.repo4/
specs:
orm_adapter (0.4.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
ckeditor!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "serializes pinned path sources to the lockfile" do
build_lib "foo"
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "serializes pinned path sources to the lockfile even when packaging" do
build_lib "foo"
install_gemfile <<-G
source "https://gem.repo1"
gem "foo", :path => "#{lib_path("foo-1.0")}"
G
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
bundle :cache
bundle :install, local: true
expect(lockfile).to eq <<~G
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "sorts serialized sources by type" do
build_lib "foo"
bar = build_git "bar"
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
c.no_checksum "bar", "1.0"
c.checksum gem_repo2, "myrack", "1.0.0"
end
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack"
gem "foo", :path => "#{lib_path("foo-1.0")}"
gem "bar", :git => "#{lib_path("bar-1.0")}"
G
expect(lockfile).to eq <<~G
GIT
remote: #{lib_path("bar-1.0")}
revision: #{bar.ref_for("main")}
specs:
bar (1.0)
PATH
remote: #{lib_path("foo-1.0")}
specs:
foo (1.0)
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
bar!
foo!
myrack
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "removes redundant sources" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack", :source => "https://gem.repo2/"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "lists gems alphabetically" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "thin"
gem "actionpack"
gem "myrack-obama"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "actionpack", "2.3.2"
c.checksum gem_repo2, "activesupport", "2.3.2"
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
c.checksum gem_repo2, "thin", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
actionpack (2.3.2)
activesupport (= 2.3.2)
activesupport (2.3.2)
myrack (1.0.0)
myrack-obama (1.0)
myrack
thin (1.0)
myrack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
actionpack
myrack-obama
thin
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "orders dependencies' dependencies in alphabetical order" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "rails"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "actionmailer", "2.3.2"
c.checksum gem_repo2, "actionpack", "2.3.2"
c.checksum gem_repo2, "activerecord", "2.3.2"
c.checksum gem_repo2, "activeresource", "2.3.2"
c.checksum gem_repo2, "activesupport", "2.3.2"
c.checksum gem_repo2, "rails", "2.3.2"
c.checksum gem_repo2, "rake", rake_version
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
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 (= #{rake_version})
rake (#{rake_version})
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
rails
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "orders dependencies by version" do
update_repo2 do
# Capistrano did this (at least until version 2.5.10)
# RubyGems 2.2 doesn't allow the specifying of a dependency twice
# See https://github.com/ruby/rubygems/commit/03dbac93a3396a80db258d9bc63500333c25bd2f
build_gem "double_deps", "1.0", skip_validation: true do |s|
s.add_dependency "net-ssh", ">= 1.0.0"
s.add_dependency "net-ssh"
end
end
install_gemfile <<-G
source "https://gem.repo2"
gem 'double_deps'
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "double_deps", "1.0"
c.checksum gem_repo2, "net-ssh", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
double_deps (1.0)
net-ssh
net-ssh (>= 1.0.0)
net-ssh (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
double_deps
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add the :require option to the lockfile" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack-obama", ">= 1.0", :require => "myrack/obama"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama (>= 1.0)
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add the :group option to the lockfile" do
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack-obama", ">= 1.0", :group => :test
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "myrack", "1.0.0"
c.checksum gem_repo2, "myrack-obama", "1.0"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
myrack-obama (1.0)
myrack
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack-obama (>= 1.0)
#{checksums}
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")
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
path "foo" do
gem "foo"
end
G
expect(lockfile).to eq <<~G
PATH
remote: foo
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
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"))
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
path "../foo" do
gem "foo"
end
G
expect(lockfile).to eq <<~G
PATH
remote: ../foo
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
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
source "https://gem.repo1"
path File.expand_path("foo", __dir__) do
gem "foo"
end
G
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
expect(lockfile).to eq <<~G
PATH
remote: foo
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "stores relative paths when the path is provided for gemspec" do
build_lib("foo", path: tmp("foo"))
checksums = checksums_section_when_enabled do |c|
c.no_checksum "foo", "1.0"
end
install_gemfile <<-G
source "https://gem.repo1"
gemspec :path => "../foo"
G
expect(lockfile).to eq <<~G
PATH
remote: ../foo
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "keeps existing platforms in the lockfile" do
checksums = checksums_section_when_enabled do |c|
c.no_checksum "myrack", "1.0.0"
end
lockfile <<-G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
java
DEPENDENCIES
myrack
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack"
G
checksums.checksum(gem_repo2, "myrack", "1.0.0")
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms("java", local_platform, defaults: [])}
DEPENDENCIES
myrack
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "adds compatible platform specific variants to the lockfile, even if resolution fallback to ruby due to some other incompatible platform specific variant" do
simulate_platform "arm64-darwin-23" do
build_repo4 do
build_gem "google-protobuf", "3.25.1"
build_gem "google-protobuf", "3.25.1" do |s|
s.platform = "arm64-darwin-23"
end
build_gem "google-protobuf", "3.25.1" do |s|
s.platform = "x64-mingw-ucrt"
s.required_ruby_version = "> #{Gem.ruby_version}"
end
end
gemfile <<-G
source "https://gem.repo4"
gem "google-protobuf"
G
bundle "lock --add-platform x64-mingw-ucrt"
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo4, "google-protobuf", "3.25.1"
c.checksum gem_repo4, "google-protobuf", "3.25.1", "arm64-darwin-23"
end
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo4/
specs:
google-protobuf (3.25.1)
google-protobuf (3.25.1-arm64-darwin-23)
PLATFORMS
arm64-darwin-23
ruby
x64-mingw-ucrt
DEPENDENCIES
google-protobuf
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
L
end
end
it "persists the spec's specific platform to the lockfile" do
build_repo2 do
build_gem "platform_specific", "1.0" do |s|
s.platform = Gem::Platform.new("universal-java-16")
end
end
simulate_platform "universal-java-16" do
install_gemfile <<-G
source "https://gem.repo2"
gem "platform_specific"
G
checksums = checksums_section_when_enabled do |c|
c.checksum gem_repo2, "platform_specific", "1.0", "universal-java-16"
end
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
platform_specific (1.0-universal-java-16)
PLATFORMS
universal-java-16
DEPENDENCIES
platform_specific
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
end
it "does not add duplicate gems" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "activesupport", "2.3.5")
c.checksum(gem_repo2, "myrack", "1.0.0")
end
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack"
G
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack"
gem "activesupport"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
activesupport (2.3.5)
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
activesupport
myrack
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "myrack", "1.0.0")
end
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack"
gem "myrack"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies with versions" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "myrack", "1.0.0")
end
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack", "1.0"
gem "myrack", "1.0"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack (= 1.0)
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "does not add duplicate dependencies in different groups" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "myrack", "1.0.0")
end
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack", "1.0", :group => :one
gem "myrack", "1.0", :group => :two
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (1.0.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack (= 1.0)
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "raises if two different versions are used" do
install_gemfile <<-G, raise_on_error: false
source "https://gem.repo2/"
gem "myrack", "1.0"
gem "myrack", "1.1"
G
expect(bundled_app_lock).not_to exist
expect(err).to include "myrack (= 1.0) and myrack (= 1.1)"
end
it "raises if two different sources are used" do
install_gemfile <<-G, raise_on_error: false
source "https://gem.repo2/"
gem "myrack"
gem "myrack", :git => "git://hubz.com"
G
expect(bundled_app_lock).not_to exist
expect(err).to include "myrack (>= 0) should come from an unspecified source and git://hubz.com"
end
it "works correctly with multiple version dependencies" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "myrack", "0.9.1")
end
install_gemfile <<-G
source "https://gem.repo2/"
gem "myrack", "> 0.9", "< 1.0"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (0.9.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack (> 0.9, < 1.0)
#{checksums}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "captures the Ruby version in the lockfile" do
checksums = checksums_section_when_enabled do |c|
c.checksum(gem_repo2, "myrack", "0.9.1")
end
install_gemfile <<-G
source "https://gem.repo2/"
ruby '#{Gem.ruby_version}'
gem "myrack", "> 0.9", "< 1.0"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo2/
specs:
myrack (0.9.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack (> 0.9, < 1.0)
#{checksums}
RUBY VERSION
#{Bundler::RubyVersion.system}
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "automatically fixes the lockfile when it's missing deps" do
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack_middleware (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G
source "https://gem.repo2"
gem "myrack_middleware"
G
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo2/
specs:
myrack (0.9.1)
myrack_middleware (1.0)
myrack (= 0.9.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "raises a clear error when frozen mode is set and lockfile is missing deps, and does not install any gems" do
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack_middleware (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
source "https://gem.repo2"
gem "myrack_middleware"
G
expect(err).to eq("Bundler found incorrect dependencies in the lockfile for myrack_middleware-1.0")
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
end
it "raises a clear error when frozen mode is set and lockfile is missing entries in CHECKSUMS section, and does not install any gems" do
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack_middleware (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
CHECKSUMS
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
source "https://gem.repo2"
gem "myrack_middleware"
G
expect(err).to eq <<~L.strip
Your lockfile is missing a CHECKSUMS entry for \"myrack_middleware\", but can't be updated because frozen mode is set
Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
L
expect(the_bundle).not_to include_gems "myrack_middleware 1.0"
end
it "raises a clear error when frozen mode is set and lockfile has empty checksums in CHECKSUMS section, and does not install any gems" do
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack (0.9.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
CHECKSUMS
myrack (0.9.1)
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G, env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false
source "https://gem.repo2"
gem "myrack"
G
expect(err).to eq <<~L.strip
Your lockfile has an empty CHECKSUMS entry for \"myrack\", but can't be updated because frozen mode is set
Run `bundle install` elsewhere and add the updated Gemfile.lock to version control.
L
expect(the_bundle).not_to include_gems "myrack 0.9.1"
end
it "automatically fixes the lockfile when it's missing deps, they conflict with other locked deps, but conflicts are fixable" do
build_repo4 do
build_gem "other_dep", "0.9"
build_gem "other_dep", "1.0"
build_gem "myrack", "0.9.1"
build_gem "myrack_middleware", "1.0" do |s|
s.add_dependency "myrack", "= 0.9.1"
s.add_dependency "other_dep", "= 0.9"
end
end
lockfile <<~L
GEM
remote: https://gem.repo4/
specs:
myrack_middleware (1.0)
other_dep (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
other_dep
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G
source "https://gem.repo4"
gem "myrack_middleware"
gem "other_dep"
G
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo4/
specs:
myrack (0.9.1)
myrack_middleware (1.0)
myrack (= 0.9.1)
other_dep (= 0.9)
other_dep (0.9)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
other_dep
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically fixes the lockfile when it's missing multiple deps, they conflict with other locked deps, but conflicts are fixable" do
build_repo4 do
build_gem "other_dep", "0.9"
build_gem "other_dep", "1.0"
build_gem "myrack", "0.9.1"
build_gem "myrack_middleware", "1.0" do |s|
s.add_dependency "myrack", "= 0.9.1"
end
build_gem "another_dep_middleware", "1.0" do |s|
s.add_dependency "other_dep", "= 0.9"
end
end
lockfile <<~L
GEM
remote: https://gem.repo4/
specs:
myrack_middleware (1.0)
another_dep_middleware (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
another_dep_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G
source "https://gem.repo4"
gem "myrack_middleware"
gem "another_dep_middleware"
G
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo4/
specs:
another_dep_middleware (1.0)
other_dep (= 0.9)
myrack (0.9.1)
myrack_middleware (1.0)
myrack (= 0.9.1)
other_dep (0.9)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
another_dep_middleware
myrack_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "raises a resolution error when lockfile is missing deps, they conflict with other locked deps, and conflicts are not fixable" do
build_repo4 do
build_gem "other_dep", "0.9"
build_gem "other_dep", "1.0"
build_gem "myrack", "0.9.1"
build_gem "myrack_middleware", "1.0" do |s|
s.add_dependency "myrack", "= 0.9.1"
s.add_dependency "other_dep", "= 0.9"
end
end
lockfile <<~L
GEM
remote: https://gem.repo4/
specs:
myrack_middleware (1.0)
other_dep (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
other_dep
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G, raise_on_error: false
source "https://gem.repo4"
gem "myrack_middleware"
gem "other_dep", "1.0"
G
expect(err).to eq <<~ERROR.strip
Could not find compatible versions
Because every version of myrack_middleware depends on other_dep = 0.9
and Gemfile depends on myrack_middleware >= 0,
other_dep = 0.9 is required.
So, because Gemfile depends on other_dep = 1.0,
version solving has failed.
ERROR
end
it "regenerates a lockfile with no specs" do
build_repo4 do
build_gem "indirect_dependency", "1.2.3" do |s|
s.metadata["funding_uri"] = "https://example.com/donate"
end
build_gem "direct_dependency", "4.5.6" do |s|
s.add_dependency "indirect_dependency", ">= 0"
end
end
lockfile <<-G
GEM
remote: https://gem.repo4/
specs:
PLATFORMS
ruby
DEPENDENCIES
direct_dependency
BUNDLED WITH
#{Bundler::VERSION}
G
install_gemfile <<-G
source "https://gem.repo4"
gem "direct_dependency"
G
expect(lockfile).to eq <<~G
GEM
remote: https://gem.repo4/
specs:
direct_dependency (4.5.6)
indirect_dependency
indirect_dependency (1.2.3)
PLATFORMS
#{lockfile_platforms(generic_default_locked_platform || local_platform, defaults: ["ruby"])}
DEPENDENCIES
direct_dependency
BUNDLED WITH
#{Bundler::VERSION}
G
end
it "automatically fixes the lockfile when it's missing deps and the full index is in use" do
lockfile <<-L
GEM
remote: https://gem.repo2/
specs:
myrack_middleware (1.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G
source "#{file_uri_for(gem_repo2)}"
gem "myrack_middleware"
G
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo2)}/
specs:
myrack (0.9.1)
myrack_middleware (1.0)
myrack (= 0.9.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack_middleware
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically fixes the lockfile when it includes a gem under the correct GIT section, but also under an incorrect GEM section, with a higher version, and with no explicit Gemfile requirement" do
git = build_git "foo"
gemfile <<~G
source "https://gem.repo1/"
gem "foo", git: "#{lib_path("foo-1.0")}"
G
# If the lockfile erroneously lists platform versions of the gem
# that don't match the locked version of the git repo we should remove them.
lockfile <<~L
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
foo (1.1-x86_64-linux-gnu)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(lockfile).to eq <<~L
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically fixes the lockfile when it includes a gem under the correct GIT section, but also under an incorrect GEM section, with a higher version" do
git = build_git "foo"
gemfile <<~G
source "https://gem.repo1/"
gem "foo", "= 1.0", git: "#{lib_path("foo-1.0")}"
G
# If the lockfile erroneously lists platform versions of the gem
# that don't match the locked version of the git repo we should remove them.
lockfile <<~L
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
foo (1.1-x86_64-linux-gnu)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo (= 1.0)!
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(lockfile).to eq <<~L
GIT
remote: #{lib_path("foo-1.0")}
revision: #{git.ref_for("main")}
specs:
foo (1.0)
GEM
remote: https://gem.repo1/
specs:
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
foo (= 1.0)!
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "automatically fixes the lockfile when it has incorrect deps, keeping the locked version" do
build_repo4 do
build_gem "net-smtp", "0.5.0" do |s|
s.add_dependency "net-protocol"
end
build_gem "net-smtp", "0.5.1" do |s|
s.add_dependency "net-protocol"
end
build_gem "net-protocol", "0.2.2"
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "net-smtp"
G
lockfile <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
net-protocol (0.2.2)
net-smtp (0.5.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
net-smtp
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(lockfile).to eq <<~L
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
net-protocol (0.2.2)
net-smtp (0.5.0)
net-protocol
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
net-smtp
BUNDLED WITH
#{Bundler::VERSION}
L
end
it "successfully updates the lockfile when a new gem is added in the Gemfile includes a gem that shouldn't be included" do
build_repo4 do
build_gem "logger", "1.7.0"
build_gem "rack", "3.2.0"
build_gem "net-smtp", "0.5.0"
end
gemfile <<~G
source "#{file_uri_for(gem_repo4)}"
gem "logger"
gem "net-smtp"
install_if -> { false } do
gem 'rack', github: 'rack/rack'
end
G
lockfile <<~L
GIT
remote: https://github.com/rack/rack.git
revision: 2fface9ac09fc582a81386becd939c987ad33f99
specs:
rack (3.2.0)
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
logger (1.7.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
logger
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install"
expect(lockfile).to eq <<~L
GIT
remote: https://github.com/rack/rack.git
revision: 2fface9ac09fc582a81386becd939c987ad33f99
specs:
rack (3.2.0)
GEM
remote: #{file_uri_for(gem_repo4)}/
specs:
logger (1.7.0)
net-smtp (0.5.0)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
logger
net-smtp
rack!
BUNDLED WITH
#{Bundler::VERSION}
L
end
shared_examples_for "a lockfile missing dependent specs" do
it "auto-heals" do
build_repo4 do
build_gem "minitest-bisect", "1.6.0" do |s|
s.add_dependency "path_expander", "~> 1.1"
end
build_gem "path_expander", "1.1.1"
end
gemfile <<~G
source "https://gem.repo4"
gem "minitest-bisect"
G
# Corrupt lockfile (completely missing path_expander)
lockfile <<~L
GEM
remote: https://gem.repo4/
specs:
minitest-bisect (1.6.0)
PLATFORMS
#{platforms}
DEPENDENCIES
minitest-bisect
BUNDLED WITH
#{Bundler::VERSION}
L
cache_gems "minitest-bisect-1.6.0", "path_expander-1.1.1", gem_repo: gem_repo4
bundle :install
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo4/
specs:
minitest-bisect (1.6.0)
path_expander (~> 1.1)
path_expander (1.1.1)
PLATFORMS
#{platforms}
DEPENDENCIES
minitest-bisect
BUNDLED WITH
#{Bundler::VERSION}
L
end
end
context "with just specific platform" do
let(:platforms) { lockfile_platforms }
it_behaves_like "a lockfile missing dependent specs"
end
context "with both ruby and specific platform" do
let(:platforms) { lockfile_platforms("ruby") }
it_behaves_like "a lockfile missing dependent specs"
end
it "auto-heals when the lockfile is missing specs" do
build_repo4 do
build_gem "minitest-bisect", "1.6.0" do |s|
s.add_dependency "path_expander", "~> 1.1"
end
build_gem "path_expander", "1.1.1"
end
gemfile <<~G
source "https://gem.repo4"
gem "minitest-bisect"
G
lockfile <<~L
GEM
remote: https://gem.repo4/
specs:
minitest-bisect (1.6.0)
path_expander (~> 1.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
minitest-bisect
BUNDLED WITH
#{Bundler::VERSION}
L
bundle "install --verbose"
expect(out).to include("re-resolving dependencies because your lockfile includes \"minitest-bisect\" but not some of its dependencies")
expect(lockfile).to eq <<~L
GEM
remote: https://gem.repo4/
specs:
minitest-bisect (1.6.0)
path_expander (~> 1.1)
path_expander (1.1.1)
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
minitest-bisect
BUNDLED WITH
#{Bundler::VERSION}
L
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_lock)
end
before(:each) do
build_repo2
install_gemfile <<-G
source "https://gem.repo2"
gem "myrack"
G
set_lockfile_mtime_to_known_value
end
it "generates Gemfile.lock with \\n line endings" do
expect(File.read(bundled_app_lock)).not_to match("\r\n")
expect(the_bundle).to include_gems "myrack 1.0"
end
context "during updates" do
it "preserves Gemfile.lock \\n line endings" do
update_repo2 do
build_gem "myrack", "1.2" do |s|
s.executables = "myrackup"
end
end
expect { bundle "update", all: true }.to change { File.mtime(bundled_app_lock) }
expect(File.read(bundled_app_lock)).not_to match("\r\n")
expect(the_bundle).to include_gems "myrack 1.2"
end
it "preserves Gemfile.lock \\n\\r line endings" do
skip "needs to be adapted" if Gem.win_platform?
update_repo2 do
build_gem "myrack", "1.2" do |s|
s.executables = "myrackup"
end
end
win_lock = File.read(bundled_app_lock).gsub(/\n/, "\r\n")
File.open(bundled_app_lock, "wb") {|f| f.puts(win_lock) }
set_lockfile_mtime_to_known_value
expect { bundle "update", all: true }.to change { File.mtime(bundled_app_lock) }
expect(File.read(bundled_app_lock)).to match("\r\n")
expect(the_bundle).to include_gems "myrack 1.2"
end
end
context "when nothing changes" do
it "preserves Gemfile.lock \\n line endings" do
expect do
ruby <<-RUBY
require 'bundler'
Bundler.setup
RUBY
end.not_to change { File.mtime(bundled_app_lock) }
end
it "preserves Gemfile.lock \\n\\r line endings" do
win_lock = File.read(bundled_app_lock).gsub(/\n/, "\r\n")
File.open(bundled_app_lock, "wb") {|f| f.puts(win_lock) }
set_lockfile_mtime_to_known_value
expect do
ruby <<-RUBY
require 'bundler'
Bundler.setup
RUBY
end.not_to change { File.mtime(bundled_app_lock) }
end
end
end
it "refuses to install if Gemfile.lock contains conflict markers" do
lockfile <<-L
GEM
remote: https://gem.repo2//
specs:
<<<<<<<
myrack (1.0.0)
=======
myrack (1.0.1)
>>>>>>>
PLATFORMS
#{lockfile_platforms}
DEPENDENCIES
myrack
BUNDLED WITH
#{Bundler::VERSION}
L
install_gemfile <<-G, raise_on_error: false
source "https://gem.repo2/"
gem "myrack"
G
expect(err).to match(/your Gemfile.lock contains merge conflicts/i)
expect(err).to match(/git checkout HEAD -- Gemfile.lock/i)
end
private
def previous_major(version)
version.split(".").map.with_index {|v, i| i == 0 ? v.to_i - 1 : v }.join(".")
end
end