mirror of
https://github.com/ruby/ruby.git
synced 2025-08-25 14:05:02 +02:00

Previously, when sorting and comparing git Gemfile vs lockfile sources during
`bundler/setup` to figure out whether we need to re-resolve or not, we
would try to find the default branch if nothing more specific was
specified in the Gemfile.
If the git cache has been deleted thought, that would fail.
The error would still be swallowed (and the branch would simply not be
displayed), but trying to clone would still generate the side effect of
creating the parent folder for the clone.
That could affect non-writable systems that don't expect `bundler/setup`
to write to the filesystem at all.
To fix this, override `Bundler::Source::Git#identifier` to use
exclusively static information, so it does not even try to clone the
repo nor generate any side effects.
582eb2ef39
1630 lines
46 KiB
Ruby
1630 lines
46 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe "bundle install with git sources" do
|
|
describe "when floating on main" do
|
|
before :each do
|
|
build_git "foo" do |s|
|
|
s.executables = "foobar"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem 'foo'
|
|
end
|
|
G
|
|
end
|
|
|
|
it "fetches gems" do
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" unless defined?(FOO_PREV_REF)
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "caches the git repo", :bundler => "< 3" do
|
|
expect(Dir["#{default_bundle_path}/cache/bundler/git/foo-1.0-*"]).to have_attributes :size => 1
|
|
end
|
|
|
|
it "does not write to cache on bundler/setup" do
|
|
cache_path = default_bundle_path.join("cache")
|
|
FileUtils.rm_rf(cache_path)
|
|
ruby "require 'bundler/setup'"
|
|
expect(cache_path).not_to exist
|
|
end
|
|
|
|
it "caches the git repo globally and properly uses the cached repo on the next invocation" do
|
|
simulate_new_machine
|
|
bundle "config set global_gem_cache true"
|
|
bundle :install
|
|
expect(Dir["#{home}/.bundle/cache/git/foo-1.0-*"]).to have_attributes :size => 1
|
|
|
|
bundle "install --verbose"
|
|
expect(err).to be_empty
|
|
expect(out).to include("Using foo 1.0 from #{lib_path("foo")}")
|
|
end
|
|
|
|
it "caches the evaluated gemspec" do
|
|
git = update_git "foo" do |s|
|
|
s.executables = ["foobar"] # we added this the first time, so keep it now
|
|
s.files = ["bin/foobar"] # updating git nukes the files list
|
|
foospec = s.to_ruby.gsub(/s\.files.*/, 's.files = `git ls-files -z`.split("\x0")')
|
|
s.write "foo.gemspec", foospec
|
|
end
|
|
|
|
bundle "update foo"
|
|
|
|
sha = git.ref_for("main", 11)
|
|
spec_file = default_bundle_path.join("bundler/gems/foo-1.0-#{sha}/foo.gemspec")
|
|
expect(spec_file).to exist
|
|
ruby_code = Gem::Specification.load(spec_file.to_s).to_ruby
|
|
file_code = File.read(spec_file)
|
|
expect(file_code).to eq(ruby_code)
|
|
end
|
|
|
|
it "does not update the git source implicitly" do
|
|
update_git "foo"
|
|
|
|
install_gemfile bundled_app2("Gemfile"), <<-G, :dir => bundled_app2
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem 'foo'
|
|
end
|
|
G
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "fail" if defined?(FOO_PREV_REF)
|
|
RUBY
|
|
|
|
expect(out).to be_empty
|
|
end
|
|
|
|
it "sets up git gem executables on the path" do
|
|
bundle "exec foobar"
|
|
expect(out).to eq("1.0")
|
|
end
|
|
|
|
it "complains if pinned specs don't exist in the git repo" do
|
|
build_git "foo"
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", "1.1", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
expect(err).to include("The source contains the following gems matching 'foo':\n * foo-1.0")
|
|
end
|
|
|
|
it "complains with version and platform if pinned specs don't exist in the git repo", :jruby_only do
|
|
build_git "only_java" do |s|
|
|
s.platform = "java"
|
|
end
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
platforms :jruby do
|
|
gem "only_java", "1.2", :git => "#{lib_path("only_java-1.0-java")}"
|
|
end
|
|
G
|
|
|
|
expect(err).to include("The source contains the following gems matching 'only_java':\n * only_java-1.0-java")
|
|
end
|
|
|
|
it "complains with multiple versions and platforms if pinned specs don't exist in the git repo", :jruby_only do
|
|
build_git "only_java", "1.0" do |s|
|
|
s.platform = "java"
|
|
end
|
|
|
|
build_git "only_java", "1.1" do |s|
|
|
s.platform = "java"
|
|
s.write "only_java1-0.gemspec", File.read("#{lib_path("only_java-1.0-java")}/only_java.gemspec")
|
|
end
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
platforms :jruby do
|
|
gem "only_java", "1.2", :git => "#{lib_path("only_java-1.1-java")}"
|
|
end
|
|
G
|
|
|
|
expect(err).to include("The source contains the following gems matching 'only_java':\n * only_java-1.0-java\n * only_java-1.1-java")
|
|
end
|
|
|
|
it "still works after moving the application directory" do
|
|
bundle "config set --local path vendor/bundle"
|
|
bundle "install"
|
|
|
|
FileUtils.mv bundled_app, tmp("bundled_app.bck")
|
|
|
|
expect(the_bundle).to include_gems "foo 1.0", :dir => tmp("bundled_app.bck")
|
|
end
|
|
|
|
it "can still install after moving the application directory" do
|
|
bundle "config set --local path vendor/bundle"
|
|
bundle "install"
|
|
|
|
FileUtils.mv bundled_app, tmp("bundled_app.bck")
|
|
|
|
update_git "foo", "1.1", :path => lib_path("foo-1.0")
|
|
|
|
gemfile tmp("bundled_app.bck/Gemfile"), <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem 'foo'
|
|
end
|
|
|
|
gem "rack", "1.0"
|
|
G
|
|
|
|
bundle "update foo", :dir => tmp("bundled_app.bck")
|
|
|
|
expect(the_bundle).to include_gems "foo 1.1", "rack 1.0", :dir => tmp("bundled_app.bck")
|
|
end
|
|
end
|
|
|
|
describe "with an empty git block" do
|
|
before do
|
|
build_git "foo"
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack"
|
|
|
|
git "#{lib_path("foo-1.0")}" do
|
|
# this page left intentionally blank
|
|
end
|
|
G
|
|
end
|
|
|
|
it "does not explode" do
|
|
bundle "install"
|
|
expect(the_bundle).to include_gems "rack 1.0"
|
|
end
|
|
end
|
|
|
|
describe "when specifying a revision" do
|
|
before(:each) do
|
|
build_git "foo"
|
|
@revision = revision_for(lib_path("foo-1.0"))
|
|
update_git "foo"
|
|
end
|
|
|
|
it "works" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}", :ref => "#{@revision}" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
expect(err).to be_empty
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" unless defined?(FOO_PREV_REF)
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "works when the revision is a symbol" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}", :ref => #{@revision.to_sym.inspect} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
expect(err).to be_empty
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" unless defined?(FOO_PREV_REF)
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "works when an abbreviated revision is added after an initial, potentially shallow clone" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}", :ref => #{@revision[0..7].inspect} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
end
|
|
|
|
it "works when a tag that does not look like a commit hash is used as the value of :ref" do
|
|
build_git "foo"
|
|
@remote = build_git("bar", :bare => true)
|
|
update_git "foo", :remote => file_uri_for(@remote.path)
|
|
update_git "foo", :push => "main"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem 'foo', :git => "#{@remote.path}"
|
|
G
|
|
|
|
# Create a new tag on the remote that needs fetching
|
|
update_git "foo", :tag => "v1.0.0"
|
|
update_git "foo", :push => "v1.0.0"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem 'foo', :git => "#{@remote.path}", :ref => "v1.0.0"
|
|
G
|
|
|
|
expect(err).to be_empty
|
|
end
|
|
|
|
it "works when the revision is a non-head ref" do
|
|
# want to ensure we don't fallback to main
|
|
update_git "foo", :path => lib_path("foo-1.0") do |s|
|
|
s.write("lib/foo.rb", "raise 'FAIL'")
|
|
end
|
|
|
|
sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0"))
|
|
|
|
# want to ensure we don't fallback to HEAD
|
|
update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s|
|
|
s.write("lib/foo.rb", "raise 'FAIL_FROM_RANDO'")
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}", :ref => "refs/bundler/1" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
expect(err).to be_empty
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" if defined?(FOO)
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "works when the revision is a non-head ref and it was previously downloaded" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
# want to ensure we don't fallback to main
|
|
update_git "foo", :path => lib_path("foo-1.0") do |s|
|
|
s.write("lib/foo.rb", "raise 'FAIL'")
|
|
end
|
|
|
|
sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0"))
|
|
|
|
# want to ensure we don't fallback to HEAD
|
|
update_git "foo", :path => lib_path("foo-1.0"), :branch => "rando" do |s|
|
|
s.write("lib/foo.rb", "raise 'FAIL_FROM_RANDO'")
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}", :ref => "refs/bundler/1" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
expect(err).to be_empty
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" if defined?(FOO)
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "does not download random non-head refs" do
|
|
sys_exec("git update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", :dir => lib_path("foo-1.0"))
|
|
|
|
bundle "config set global_gem_cache true"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
# ensure we also git fetch after cloning
|
|
bundle :update, :all => true
|
|
|
|
sys_exec("git ls-remote .", :dir => Dir[home(".bundle/cache/git/foo-*")].first)
|
|
|
|
expect(out).not_to include("refs/bundler/1")
|
|
end
|
|
end
|
|
|
|
describe "when specifying a branch" do
|
|
let(:branch) { "branch" }
|
|
let(:repo) { build_git("foo").path }
|
|
|
|
it "works" do
|
|
update_git("foo", :path => repo, :branch => branch)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{repo}", :branch => #{branch.dump} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
end
|
|
|
|
context "when the branch starts with a `#`" do
|
|
let(:branch) { "#149/redirect-url-fragment" }
|
|
it "works" do
|
|
skip "git does not accept this" if Gem.win_platform?
|
|
|
|
update_git("foo", :path => repo, :branch => branch)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{repo}", :branch => #{branch.dump} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
end
|
|
end
|
|
|
|
context "when the branch includes quotes" do
|
|
let(:branch) { %('") }
|
|
it "works" do
|
|
skip "git does not accept this" if Gem.win_platform?
|
|
|
|
update_git("foo", :path => repo, :branch => branch)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{repo}", :branch => #{branch.dump} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when specifying a tag" do
|
|
let(:tag) { "tag" }
|
|
let(:repo) { build_git("foo").path }
|
|
|
|
it "works" do
|
|
update_git("foo", :path => repo, :tag => tag)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{repo}", :tag => #{tag.dump} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
end
|
|
|
|
context "when the tag starts with a `#`" do
|
|
let(:tag) { "#149/redirect-url-fragment" }
|
|
it "works" do
|
|
skip "git does not accept this" if Gem.win_platform?
|
|
|
|
update_git("foo", :path => repo, :tag => tag)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{repo}", :tag => #{tag.dump} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
end
|
|
end
|
|
|
|
context "when the tag includes quotes" do
|
|
let(:tag) { %('") }
|
|
it "works" do
|
|
skip "git does not accept this" if Gem.win_platform?
|
|
|
|
update_git("foo", :path => repo, :tag => tag)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{repo}", :tag => #{tag.dump} do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "when specifying local override" do
|
|
it "uses the local repository instead of checking a new one out" do
|
|
build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
|
|
s.write "lib/rack.rb", "puts :LOCAL"
|
|
end
|
|
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install
|
|
|
|
run "require 'rack'"
|
|
expect(out).to eq("LOCAL")
|
|
end
|
|
|
|
it "chooses the local repository on runtime" do
|
|
build_git "rack", "0.8"
|
|
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
|
|
update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
|
|
s.write "lib/rack.rb", "puts :LOCAL"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
run "require 'rack'"
|
|
expect(out).to eq("LOCAL")
|
|
end
|
|
|
|
it "unlocks the source when the dependencies have changed while switching to the local" do
|
|
build_git "rack", "0.8"
|
|
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
|
|
update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
|
|
s.write "rack.gemspec", build_spec("rack", "0.8") { runtime "rspec", "> 0" }.first.to_ruby
|
|
s.write "lib/rack.rb", "puts :LOCAL"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install
|
|
run "require 'rack'"
|
|
expect(out).to eq("LOCAL")
|
|
end
|
|
|
|
it "updates specs on runtime" do
|
|
system_gems "nokogiri-1.4.2"
|
|
|
|
build_git "rack", "0.8"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
lockfile0 = File.read(bundled_app_lock)
|
|
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
update_git "rack", "0.8", :path => lib_path("local-rack") do |s|
|
|
s.add_dependency "nokogiri", "1.4.2"
|
|
end
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
run "require 'rack'"
|
|
|
|
lockfile1 = File.read(bundled_app_lock)
|
|
expect(lockfile1).not_to eq(lockfile0)
|
|
end
|
|
|
|
it "updates ref on install" do
|
|
build_git "rack", "0.8"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
lockfile0 = File.read(bundled_app_lock)
|
|
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
update_git "rack", "0.8", :path => lib_path("local-rack")
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install
|
|
|
|
lockfile1 = File.read(bundled_app_lock)
|
|
expect(lockfile1).not_to eq(lockfile0)
|
|
end
|
|
|
|
it "explodes and gives correct solution if given path does not exist on install" do
|
|
build_git "rack", "0.8"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install, :raise_on_error => false
|
|
expect(err).to match(/Cannot use local override for rack-0.8 because #{Regexp.escape(lib_path('local-rack').to_s)} does not exist/)
|
|
|
|
solution = "config unset local.rack"
|
|
expect(err).to match(/Run `bundle #{solution}` to remove the local override/)
|
|
|
|
bundle solution
|
|
bundle :install
|
|
|
|
expect(err).to be_empty
|
|
end
|
|
|
|
it "explodes and gives correct solution if branch is not given on install" do
|
|
build_git "rack", "0.8"
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install, :raise_on_error => false
|
|
expect(err).to match(/Cannot use local override for rack-0.8 at #{Regexp.escape(lib_path('local-rack').to_s)} because :branch is not specified in Gemfile/)
|
|
|
|
solution = "config unset local.rack"
|
|
expect(err).to match(/Specify a branch or run `bundle #{solution}` to remove the local override/)
|
|
|
|
bundle solution
|
|
bundle :install
|
|
|
|
expect(err).to be_empty
|
|
end
|
|
|
|
it "does not explode if disable_local_branch_check is given" do
|
|
build_git "rack", "0.8"
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle %(config set disable_local_branch_check true)
|
|
bundle :install
|
|
expect(out).to match(/Bundle complete!/)
|
|
end
|
|
|
|
it "explodes on different branches on install" do
|
|
build_git "rack", "0.8"
|
|
|
|
FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack"))
|
|
|
|
update_git "rack", "0.8", :path => lib_path("local-rack"), :branch => "another" do |s|
|
|
s.write "lib/rack.rb", "puts :LOCAL"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install, :raise_on_error => false
|
|
expect(err).to match(/is using branch another but Gemfile specifies main/)
|
|
end
|
|
|
|
it "explodes on invalid revision on install" do
|
|
build_git "rack", "0.8"
|
|
|
|
build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
|
|
s.write "lib/rack.rb", "puts :LOCAL"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle :install, :raise_on_error => false
|
|
expect(err).to match(/The Gemfile lock is pointing to revision \w+/)
|
|
end
|
|
|
|
it "does not explode on invalid revision on install" do
|
|
build_git "rack", "0.8"
|
|
|
|
build_git "rack", "0.8", :path => lib_path("local-rack") do |s|
|
|
s.write "lib/rack.rb", "puts :LOCAL"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main"
|
|
G
|
|
|
|
bundle %(config set local.rack #{lib_path("local-rack")})
|
|
bundle %(config set disable_local_revision_check true)
|
|
bundle :install
|
|
expect(out).to match(/Bundle complete!/)
|
|
end
|
|
end
|
|
|
|
describe "specified inline" do
|
|
# TODO: Figure out how to write this test so that it is not flaky depending
|
|
# on the current network situation.
|
|
# it "supports private git URLs" do
|
|
# gemfile <<-G
|
|
# gem "thingy", :git => "git@notthere.fallingsnow.net:somebody/thingy.git"
|
|
# G
|
|
#
|
|
# bundle :install
|
|
#
|
|
# # p out
|
|
# # p err
|
|
# puts err unless err.empty? # This spec fails randomly every so often
|
|
# err.should include("notthere.fallingsnow.net")
|
|
# err.should include("ssh")
|
|
# end
|
|
|
|
it "installs from git even if a newer gem is available elsewhere" do
|
|
build_git "rack", "0.8"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack-0.8")}"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "rack 0.8"
|
|
end
|
|
|
|
it "installs dependencies from git even if a newer gem is available elsewhere" do
|
|
system_gems "rack-1.0.0"
|
|
|
|
build_lib "rack", "1.0", :path => lib_path("nested/bar") do |s|
|
|
s.write "lib/rack.rb", "puts 'WIN OVERRIDE'"
|
|
end
|
|
|
|
build_git "foo", :path => lib_path("nested") do |s|
|
|
s.add_dependency "rack", "= 1.0"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("nested")}"
|
|
G
|
|
|
|
run "require 'rack'"
|
|
expect(out).to eq("WIN OVERRIDE")
|
|
end
|
|
|
|
it "correctly unlocks when changing to a git source" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", "0.9.1"
|
|
G
|
|
|
|
build_git "rack", :path => lib_path("rack")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", "1.0.0", :git => "#{lib_path("rack")}"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "rack 1.0.0"
|
|
end
|
|
|
|
it "correctly unlocks when changing to a git source without versions" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack"
|
|
G
|
|
|
|
build_git "rack", "1.2", :path => lib_path("rack")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", :git => "#{lib_path("rack")}"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "rack 1.2"
|
|
end
|
|
end
|
|
|
|
describe "block syntax" do
|
|
it "pulls all gems from a git block" do
|
|
build_lib "omg", :path => lib_path("hi2u/omg")
|
|
build_lib "hi2u", :path => lib_path("hi2u")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
path "#{lib_path("hi2u")}" do
|
|
gem "omg"
|
|
gem "hi2u"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "omg 1.0", "hi2u 1.0"
|
|
end
|
|
end
|
|
|
|
it "uses a ref if specified" do
|
|
build_git "foo"
|
|
@revision = revision_for(lib_path("foo-1.0"))
|
|
update_git "foo"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{@revision}"
|
|
G
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" unless defined?(FOO_PREV_REF)
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "correctly handles cases with invalid gemspecs" do
|
|
build_git "foo" do |s|
|
|
s.summary = nil
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
gem "rails", "2.3.2"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "foo 1.0"
|
|
expect(the_bundle).to include_gems "rails 2.3.2"
|
|
end
|
|
|
|
it "runs the gemspec in the context of its parent directory" do
|
|
build_lib "bar", :path => lib_path("foo/bar"), :gemspec => false do |s|
|
|
s.write lib_path("foo/bar/lib/version.rb"), %(BAR_VERSION = '1.0')
|
|
s.write "bar.gemspec", <<-G
|
|
$:.unshift Dir.pwd
|
|
require 'lib/version'
|
|
Gem::Specification.new do |s|
|
|
s.name = 'bar'
|
|
s.author = 'no one'
|
|
s.version = BAR_VERSION
|
|
s.summary = 'Bar'
|
|
s.files = Dir["lib/**/*.rb"]
|
|
end
|
|
G
|
|
end
|
|
|
|
build_git "foo", :path => lib_path("foo") do |s|
|
|
s.write "bin/foo", ""
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "bar", :git => "#{lib_path("foo")}"
|
|
gem "rails", "2.3.2"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "bar 1.0"
|
|
expect(the_bundle).to include_gems "rails 2.3.2"
|
|
end
|
|
|
|
it "installs from git even if a rubygems gem is present" do
|
|
build_gem "foo", "1.0", :path => lib_path("fake_foo"), :to_system => true do |s|
|
|
s.write "lib/foo.rb", "raise 'FAIL'"
|
|
end
|
|
|
|
build_git "foo", "1.0"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", "1.0", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "foo 1.0"
|
|
end
|
|
|
|
it "fakes the gem out if there is no gemspec" do
|
|
build_git "foo", :gemspec => false
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", "1.0", :git => "#{lib_path("foo-1.0")}"
|
|
gem "rails", "2.3.2"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems("foo 1.0")
|
|
expect(the_bundle).to include_gems("rails 2.3.2")
|
|
end
|
|
|
|
it "catches git errors and spits out useful output" do
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", "1.0", :git => "omgomg"
|
|
G
|
|
|
|
bundle :install, :raise_on_error => false
|
|
|
|
expect(err).to include("Git error:")
|
|
expect(err).to include("fatal")
|
|
expect(err).to include("omgomg")
|
|
end
|
|
|
|
it "works when the gem path has spaces in it" do
|
|
build_git "foo", :path => lib_path("foo space-1.0")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo space-1.0")}"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "foo 1.0"
|
|
end
|
|
|
|
it "handles repos that have been force-pushed" do
|
|
build_git "forced", "1.0"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("forced-1.0")}" do
|
|
gem 'forced'
|
|
end
|
|
G
|
|
expect(the_bundle).to include_gems "forced 1.0"
|
|
|
|
update_git "forced" do |s|
|
|
s.write "lib/forced.rb", "FORCED = '1.1'"
|
|
end
|
|
|
|
bundle "update", :all => true
|
|
expect(the_bundle).to include_gems "forced 1.1"
|
|
|
|
sys_exec("git reset --hard HEAD^", :dir => lib_path("forced-1.0"))
|
|
|
|
bundle "update", :all => true
|
|
expect(the_bundle).to include_gems "forced 1.0"
|
|
end
|
|
|
|
it "ignores submodules if :submodule is not passed" do
|
|
# CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
|
|
system(*%W[git config --global protocol.file.allow always])
|
|
|
|
build_git "submodule", "1.0"
|
|
build_git "has_submodule", "1.0" do |s|
|
|
s.add_dependency "submodule"
|
|
end
|
|
sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
|
|
sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("has_submodule-1.0")}" do
|
|
gem "has_submodule"
|
|
end
|
|
G
|
|
expect(err).to match(%r{submodule >= 0 could not be found in rubygems repository #{file_uri_for(gem_repo1)}/ or installed locally})
|
|
|
|
expect(the_bundle).not_to include_gems "has_submodule 1.0"
|
|
end
|
|
|
|
it "handles repos with submodules" do
|
|
# CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
|
|
system(*%W[git config --global protocol.file.allow always])
|
|
|
|
build_git "submodule", "1.0"
|
|
build_git "has_submodule", "1.0" do |s|
|
|
s.add_dependency "submodule"
|
|
end
|
|
sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
|
|
sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("has_submodule-1.0")}", :submodules => true do
|
|
gem "has_submodule"
|
|
end
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "has_submodule 1.0"
|
|
end
|
|
|
|
it "does not warn when deiniting submodules" do
|
|
# CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/
|
|
system(*%W[git config --global protocol.file.allow always])
|
|
|
|
build_git "submodule", "1.0"
|
|
build_git "has_submodule", "1.0"
|
|
|
|
sys_exec "git submodule add #{lib_path("submodule-1.0")} submodule-1.0", :dir => lib_path("has_submodule-1.0")
|
|
sys_exec "git commit -m \"submodulator\"", :dir => lib_path("has_submodule-1.0")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("has_submodule-1.0")}" do
|
|
gem "has_submodule"
|
|
end
|
|
G
|
|
expect(err).to be_empty
|
|
|
|
expect(the_bundle).to include_gems "has_submodule 1.0"
|
|
expect(the_bundle).to_not include_gems "submodule 1.0"
|
|
end
|
|
|
|
it "handles implicit updates when modifying the source info" do
|
|
git = build_git "foo"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
update_git "foo"
|
|
update_git "foo"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}", :ref => "#{git.ref_for("HEAD^")}" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
run <<-RUBY
|
|
require 'foo'
|
|
puts "WIN" if FOO_PREV_REF == '#{git.ref_for("HEAD^^")}'
|
|
RUBY
|
|
|
|
expect(out).to eq("WIN")
|
|
end
|
|
|
|
it "does not to a remote fetch if the revision is cached locally" do
|
|
build_git "foo"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
FileUtils.rm_rf(lib_path("foo-1.0"))
|
|
|
|
bundle "install"
|
|
expect(out).not_to match(/updating/i)
|
|
end
|
|
|
|
it "doesn't blow up if bundle install is run twice in a row" do
|
|
build_git "foo"
|
|
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
bundle "install"
|
|
bundle "install"
|
|
end
|
|
|
|
it "prints a friendly error if a file blocks the git repo" do
|
|
build_git "foo"
|
|
|
|
FileUtils.mkdir_p(default_bundle_path)
|
|
FileUtils.touch(default_bundle_path("bundler"))
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
expect(exitstatus).to_not eq(0)
|
|
expect(err).to include("Bundler could not install a gem because it " \
|
|
"needs to create a directory, but a file exists " \
|
|
"- #{default_bundle_path("bundler")}")
|
|
end
|
|
|
|
it "does not duplicate git gem sources" do
|
|
build_lib "foo", :path => lib_path("nested/foo")
|
|
build_lib "bar", :path => lib_path("nested/bar")
|
|
|
|
build_git "foo", :path => lib_path("nested")
|
|
build_git "bar", :path => lib_path("nested")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("nested")}"
|
|
gem "bar", :git => "#{lib_path("nested")}"
|
|
G
|
|
|
|
expect(File.read(bundled_app_lock).scan("GIT").size).to eq(1)
|
|
end
|
|
|
|
describe "switching sources" do
|
|
it "doesn't explode when switching Path to Git sources" do
|
|
build_gem "foo", "1.0", :to_system => true do |s|
|
|
s.write "lib/foo.rb", "raise 'fail'"
|
|
end
|
|
build_lib "foo", "1.0", :path => lib_path("bar/foo")
|
|
build_git "bar", "1.0", :path => lib_path("bar") do |s|
|
|
s.add_dependency "foo"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "bar", :path => "#{lib_path("bar")}"
|
|
G
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "bar", :git => "#{lib_path("bar")}"
|
|
G
|
|
|
|
expect(the_bundle).to include_gems "foo 1.0", "bar 1.0"
|
|
end
|
|
|
|
it "doesn't explode when switching Gem to Git source" do
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack-obama"
|
|
gem "rack", "1.0.0"
|
|
G
|
|
|
|
build_git "rack", "1.0" do |s|
|
|
s.write "lib/new_file.rb", "puts 'USING GIT'"
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack-obama"
|
|
gem "rack", "1.0.0", :git => "#{lib_path("rack-1.0")}"
|
|
G
|
|
|
|
run "require 'new_file'"
|
|
expect(out).to eq("USING GIT")
|
|
end
|
|
end
|
|
|
|
describe "bundle install after the remote has been updated" do
|
|
it "installs" do
|
|
build_git "valim"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "valim", :git => "#{file_uri_for(lib_path("valim-1.0"))}"
|
|
G
|
|
|
|
old_revision = revision_for(lib_path("valim-1.0"))
|
|
update_git "valim"
|
|
new_revision = revision_for(lib_path("valim-1.0"))
|
|
|
|
old_lockfile = File.read(bundled_app_lock)
|
|
lockfile(bundled_app_lock, old_lockfile.gsub(/revision: #{old_revision}/, "revision: #{new_revision}"))
|
|
|
|
bundle "install"
|
|
|
|
run <<-R
|
|
require "valim"
|
|
puts VALIM_PREV_REF
|
|
R
|
|
|
|
expect(out).to eq(old_revision)
|
|
end
|
|
|
|
it "gives a helpful error message when the remote ref no longer exists" do
|
|
build_git "foo"
|
|
revision = revision_for(lib_path("foo-1.0"))
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :ref => "#{revision}"
|
|
G
|
|
expect(out).to_not match(/Revision.*does not exist/)
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :ref => "deadbeef"
|
|
G
|
|
expect(err).to include("Revision deadbeef does not exist in the repository")
|
|
end
|
|
|
|
it "gives a helpful error message when the remote branch no longer exists" do
|
|
build_git "foo"
|
|
|
|
install_gemfile <<-G, :env => { "LANG" => "en" }, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :branch => "deadbeef"
|
|
G
|
|
|
|
expect(err).to include("Revision deadbeef does not exist in the repository")
|
|
end
|
|
end
|
|
|
|
describe "bundle install with deployment mode configured and git sources" do
|
|
it "works" do
|
|
build_git "valim", :path => lib_path("valim")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "valim", "= 1.0", :git => "#{lib_path("valim")}"
|
|
G
|
|
|
|
simulate_new_machine
|
|
|
|
bundle "config set --local deployment true"
|
|
bundle :install
|
|
end
|
|
end
|
|
|
|
describe "gem install hooks" do
|
|
it "runs pre-install hooks" do
|
|
build_git "foo"
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
File.open(lib_path("install_hooks.rb"), "w") do |h|
|
|
h.write <<-H
|
|
Gem.pre_install_hooks << lambda do |inst|
|
|
STDERR.puts "Ran pre-install hook: \#{inst.spec.full_name}"
|
|
end
|
|
H
|
|
end
|
|
|
|
bundle :install,
|
|
:requires => [lib_path("install_hooks.rb")]
|
|
expect(err_without_deprecations).to eq("Ran pre-install hook: foo-1.0")
|
|
end
|
|
|
|
it "runs post-install hooks" do
|
|
build_git "foo"
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
File.open(lib_path("install_hooks.rb"), "w") do |h|
|
|
h.write <<-H
|
|
Gem.post_install_hooks << lambda do |inst|
|
|
STDERR.puts "Ran post-install hook: \#{inst.spec.full_name}"
|
|
end
|
|
H
|
|
end
|
|
|
|
bundle :install,
|
|
:requires => [lib_path("install_hooks.rb")]
|
|
expect(err_without_deprecations).to eq("Ran post-install hook: foo-1.0")
|
|
end
|
|
|
|
it "complains if the install hook fails" do
|
|
build_git "foo"
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
File.open(lib_path("install_hooks.rb"), "w") do |h|
|
|
h.write <<-H
|
|
Gem.pre_install_hooks << lambda do |inst|
|
|
false
|
|
end
|
|
H
|
|
end
|
|
|
|
bundle :install, :requires => [lib_path("install_hooks.rb")], :raise_on_error => false
|
|
expect(err).to include("failed for foo-1.0")
|
|
end
|
|
end
|
|
|
|
context "with an extension" do
|
|
it "installs the extension" do
|
|
build_git "foo" do |s|
|
|
s.add_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", <<-RUBY
|
|
task :default do
|
|
path = File.expand_path("lib", __dir__)
|
|
FileUtils.mkdir_p(path)
|
|
File.open("\#{path}/foo.rb", "w") do |f|
|
|
f.puts "FOO = 'YES'"
|
|
end
|
|
end
|
|
RUBY
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
expect(out).to eq("YES")
|
|
|
|
run <<-R
|
|
puts $:.grep(/ext/)
|
|
R
|
|
expect(out).to include(Pathname.glob(default_bundle_path("bundler/gems/extensions/**/foo-1.0-*")).first.to_s)
|
|
end
|
|
|
|
it "does not use old extension after ref changes" do
|
|
git_reader = build_git "foo", :no_default => true do |s|
|
|
s.extensions = ["ext/extconf.rb"]
|
|
s.write "ext/extconf.rb", <<-RUBY
|
|
require "mkmf"
|
|
$extout = "$(topdir)/" + RbConfig::CONFIG["EXTOUT"]
|
|
create_makefile("foo")
|
|
RUBY
|
|
s.write "ext/foo.c", "void Init_foo() {}"
|
|
end
|
|
|
|
2.times do |i|
|
|
File.open(git_reader.path.join("ext/foo.c"), "w") do |file|
|
|
file.write <<-C
|
|
#include "ruby.h"
|
|
VALUE foo() { return INT2FIX(#{i}); }
|
|
void Init_foo() { rb_define_global_function("foo", &foo, 0); }
|
|
C
|
|
end
|
|
sys_exec("git commit -m \"commit for iteration #{i}\" ext/foo.c", :dir => git_reader.path)
|
|
|
|
git_commit_sha = git_reader.ref_for("HEAD")
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{git_commit_sha}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts foo
|
|
R
|
|
|
|
expect(out).to eq(i.to_s)
|
|
end
|
|
end
|
|
|
|
it "does not prompt to gem install if extension fails" do
|
|
build_git "foo" do |s|
|
|
s.add_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", <<-RUBY
|
|
task :default do
|
|
raise
|
|
end
|
|
RUBY
|
|
end
|
|
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
expect(err).to end_with(<<-M.strip)
|
|
An error occurred while installing foo (1.0), and Bundler cannot continue.
|
|
|
|
In Gemfile:
|
|
foo
|
|
M
|
|
expect(out).not_to include("gem install foo")
|
|
end
|
|
|
|
it "does not reinstall the extension" do
|
|
build_git "foo" do |s|
|
|
s.add_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", <<-RUBY
|
|
task :default do
|
|
path = File.expand_path("lib", __dir__)
|
|
FileUtils.mkdir_p(path)
|
|
cur_time = Time.now.to_f.to_s
|
|
File.open("\#{path}/foo.rb", "w") do |f|
|
|
f.puts "FOO = \#{cur_time}"
|
|
end
|
|
end
|
|
RUBY
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
|
|
installed_time = out
|
|
expect(installed_time).to match(/\A\d+\.\d+\z/)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
expect(out).to eq(installed_time)
|
|
end
|
|
|
|
it "does not reinstall the extension when changing another gem" do
|
|
build_git "foo" do |s|
|
|
s.add_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", <<-RUBY
|
|
task :default do
|
|
path = File.expand_path("lib", __dir__)
|
|
FileUtils.mkdir_p(path)
|
|
cur_time = Time.now.to_f.to_s
|
|
File.open("\#{path}/foo.rb", "w") do |f|
|
|
f.puts "FOO = \#{cur_time}"
|
|
end
|
|
end
|
|
RUBY
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", "0.9.1"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
|
|
installed_time = out
|
|
expect(installed_time).to match(/\A\d+\.\d+\z/)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "rack", "1.0.0"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
expect(out).to eq(installed_time)
|
|
end
|
|
|
|
it "does reinstall the extension when changing refs" do
|
|
build_git "foo" do |s|
|
|
s.add_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", <<-RUBY
|
|
task :default do
|
|
path = File.expand_path("lib", __dir__)
|
|
FileUtils.mkdir_p(path)
|
|
cur_time = Time.now.to_f.to_s
|
|
File.open("\#{path}/foo.rb", "w") do |f|
|
|
f.puts "FOO = \#{cur_time}"
|
|
end
|
|
end
|
|
RUBY
|
|
end
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
|
|
installed_time = out
|
|
|
|
update_git("foo", :branch => "branch2")
|
|
|
|
expect(installed_time).to match(/\A\d+\.\d+\z/)
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "branch2"
|
|
G
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
expect(out).not_to eq(installed_time)
|
|
|
|
installed_time = out
|
|
|
|
update_git("foo")
|
|
bundle "update foo"
|
|
|
|
run <<-R
|
|
require 'foo'
|
|
puts FOO
|
|
R
|
|
expect(out).not_to eq(installed_time)
|
|
end
|
|
end
|
|
|
|
it "ignores git environment variables" do
|
|
build_git "xxxxxx" do |s|
|
|
s.executables = "xxxxxxbar"
|
|
end
|
|
|
|
Bundler::SharedHelpers.with_clean_git_env do
|
|
ENV["GIT_DIR"] = "bar"
|
|
ENV["GIT_WORK_TREE"] = "bar"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("xxxxxx-1.0")}" do
|
|
gem 'xxxxxx'
|
|
end
|
|
G
|
|
|
|
expect(ENV["GIT_DIR"]).to eq("bar")
|
|
expect(ENV["GIT_WORK_TREE"]).to eq("bar")
|
|
end
|
|
end
|
|
|
|
describe "without git installed" do
|
|
it "prints a better error message when installing" do
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
|
|
gem "rake", git: "https://github.com/ruby/rake"
|
|
G
|
|
|
|
lockfile <<-L
|
|
GIT
|
|
remote: https://github.com/ruby/rake
|
|
revision: 5c60da8644a9e4f655e819252e3b6ca77f42b7af
|
|
specs:
|
|
rake (13.0.6)
|
|
|
|
GEM
|
|
remote: https://rubygems.org/
|
|
specs:
|
|
|
|
PLATFORMS
|
|
#{lockfile_platforms}
|
|
|
|
DEPENDENCIES
|
|
rake!
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
L
|
|
|
|
with_path_as("") do
|
|
bundle "install", :raise_on_error => false
|
|
end
|
|
expect(err).
|
|
to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
|
|
end
|
|
|
|
it "prints a better error message when updating" do
|
|
build_git "foo"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem 'foo'
|
|
end
|
|
G
|
|
|
|
with_path_as("") do
|
|
bundle "update", :all => true, :raise_on_error => false
|
|
end
|
|
expect(err).
|
|
to include("You need to install git to be able to use gems from git repositories. For help installing git, please refer to GitHub's tutorial at https://help.github.com/articles/set-up-git")
|
|
end
|
|
|
|
it "installs a packaged git gem successfully" do
|
|
build_git "foo"
|
|
|
|
install_gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "#{lib_path("foo-1.0")}" do
|
|
gem 'foo'
|
|
end
|
|
G
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
simulate_new_machine
|
|
|
|
bundle "install", :env => { "PATH" => "" }
|
|
expect(out).to_not include("You need to install git to be able to use gems from git repositories.")
|
|
end
|
|
end
|
|
|
|
describe "when the git source is overridden with a local git repo" do
|
|
before do
|
|
bundle "config set --global local.foo #{lib_path("foo")}"
|
|
end
|
|
|
|
describe "and git output is colorized" do
|
|
before do
|
|
File.open("#{ENV["HOME"]}/.gitconfig", "w") do |f|
|
|
f.write("[color]\n\tui = always\n")
|
|
end
|
|
end
|
|
|
|
it "installs successfully" do
|
|
build_git "foo", "1.0", :path => lib_path("foo")
|
|
|
|
gemfile <<-G
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
gem "foo", :git => "#{lib_path("foo")}", :branch => "main"
|
|
G
|
|
|
|
bundle :install
|
|
expect(the_bundle).to include_gems "foo 1.0"
|
|
end
|
|
end
|
|
end
|
|
|
|
context "git sources that include credentials" do
|
|
context "that are username and password" do
|
|
let(:credentials) { "user1:password1" }
|
|
|
|
it "does not display the password" do
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "https://#{credentials}@github.com/company/private-repo" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(last_command.stdboth).to_not include("password1")
|
|
expect(out).to include("Fetching https://user1@github.com/company/private-repo")
|
|
end
|
|
end
|
|
|
|
context "that is an oauth token" do
|
|
let(:credentials) { "oauth_token" }
|
|
|
|
it "displays the oauth scheme but not the oauth token" do
|
|
install_gemfile <<-G, :raise_on_error => false
|
|
source "#{file_uri_for(gem_repo1)}"
|
|
git "https://#{credentials}:x-oauth-basic@github.com/company/private-repo" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
expect(last_command.stdboth).to_not include("oauth_token")
|
|
expect(out).to include("Fetching https://x-oauth-basic@github.com/company/private-repo")
|
|
end
|
|
end
|
|
end
|
|
end
|