mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00

When we need to reset system gems during specs, there's no need to
rebuild bundler, we can copy over the original gem home.
7b4f80747b
555 lines
15 KiB
Ruby
555 lines
15 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe "bundle cache" do
|
|
it "doesn't update the cache multiple times, even if it already exists" do
|
|
gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "myrack"
|
|
G
|
|
|
|
bundle :cache
|
|
expect(out).to include("Updating files in vendor/cache").once
|
|
|
|
bundle :cache
|
|
expect(out).to include("Updating files in vendor/cache").once
|
|
end
|
|
|
|
context "with --gemfile" do
|
|
it "finds the gemfile" do
|
|
gemfile bundled_app("NotGemfile"), <<-G
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
G
|
|
|
|
bundle "cache --gemfile=NotGemfile"
|
|
|
|
ENV["BUNDLE_GEMFILE"] = "NotGemfile"
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
end
|
|
end
|
|
|
|
context "with --all" do
|
|
context "without a gemspec" do
|
|
it "caches all dependencies except bundler itself" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
gem 'bundler'
|
|
D
|
|
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
|
|
end
|
|
end
|
|
|
|
context "with a gemspec" do
|
|
context "that has the same name as the gem" do
|
|
before do
|
|
File.open(bundled_app("mygem.gemspec"), "w") do |f|
|
|
f.write <<-G
|
|
Gem::Specification.new do |s|
|
|
s.name = "mygem"
|
|
s.version = "0.1.1"
|
|
s.summary = ""
|
|
s.authors = ["gem author"]
|
|
s.add_development_dependency "nokogiri", "=1.4.2"
|
|
end
|
|
G
|
|
end
|
|
end
|
|
|
|
it "caches all dependencies except bundler and the gemspec specified gem" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
gemspec
|
|
D
|
|
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
|
|
expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
|
|
expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
|
|
end
|
|
end
|
|
|
|
context "that has a different name as the gem" do
|
|
before do
|
|
File.open(bundled_app("mygem_diffname.gemspec"), "w") do |f|
|
|
f.write <<-G
|
|
Gem::Specification.new do |s|
|
|
s.name = "mygem"
|
|
s.version = "0.1.1"
|
|
s.summary = ""
|
|
s.authors = ["gem author"]
|
|
s.add_development_dependency "nokogiri", "=1.4.2"
|
|
end
|
|
G
|
|
end
|
|
end
|
|
|
|
it "caches all dependencies except bundler and the gemspec specified gem" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
gemspec
|
|
D
|
|
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
|
|
expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
|
|
expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with multiple gemspecs" do
|
|
before do
|
|
File.open(bundled_app("mygem.gemspec"), "w") do |f|
|
|
f.write <<-G
|
|
Gem::Specification.new do |s|
|
|
s.name = "mygem"
|
|
s.version = "0.1.1"
|
|
s.summary = ""
|
|
s.authors = ["gem author"]
|
|
s.add_development_dependency "nokogiri", "=1.4.2"
|
|
end
|
|
G
|
|
end
|
|
File.open(bundled_app("mygem_client.gemspec"), "w") do |f|
|
|
f.write <<-G
|
|
Gem::Specification.new do |s|
|
|
s.name = "mygem_test"
|
|
s.version = "0.1.1"
|
|
s.summary = ""
|
|
s.authors = ["gem author"]
|
|
s.add_development_dependency "weakling", "=0.0.3"
|
|
end
|
|
G
|
|
end
|
|
end
|
|
|
|
it "caches all dependencies except bundler and the gemspec specified gems" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
gemspec :name => 'mygem'
|
|
gemspec :name => 'mygem_test'
|
|
D
|
|
|
|
bundle "config set cache_all true"
|
|
bundle :cache
|
|
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
expect(bundled_app("vendor/cache/nokogiri-1.4.2.gem")).to exist
|
|
expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
|
|
expect(bundled_app("vendor/cache/mygem-0.1.1.gem")).to_not exist
|
|
expect(bundled_app("vendor/cache/mygem_test-0.1.1.gem")).to_not exist
|
|
expect(bundled_app("vendor/cache/bundler-0.9.gem")).to_not exist
|
|
end
|
|
end
|
|
end
|
|
|
|
context "with --path" do
|
|
it "sets root directory for gems" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
D
|
|
|
|
bundle "cache --path #{bundled_app("test")}"
|
|
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
expect(bundled_app("test/vendor/cache/")).to exist
|
|
end
|
|
end
|
|
|
|
context "with --no-install" do
|
|
it "puts the gems in vendor/cache but does not install them" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
D
|
|
|
|
bundle "cache --no-install"
|
|
|
|
expect(the_bundle).not_to include_gems "myrack 1.0.0"
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
end
|
|
|
|
it "does not prevent installing gems with bundle install" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack'
|
|
D
|
|
|
|
bundle "cache --no-install"
|
|
bundle "install"
|
|
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
end
|
|
|
|
it "does not prevent installing gems with bundle update" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem "myrack", "1.0.0"
|
|
D
|
|
|
|
bundle "cache --no-install"
|
|
bundle "update --all"
|
|
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
end
|
|
end
|
|
|
|
context "with --all-platforms" do
|
|
it "puts the gems in vendor/cache even for other rubies" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack', :platforms => [:ruby_20, :windows_20]
|
|
D
|
|
|
|
bundle "cache --all-platforms"
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
end
|
|
|
|
it "puts the gems in vendor/cache even for legacy windows rubies, but prints a warning" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack', :platforms => [:ruby_20, :x64_mingw_20]
|
|
D
|
|
|
|
bundle "cache --all-platforms"
|
|
expect(err).to include("deprecated")
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist
|
|
end
|
|
|
|
it "prints an error when using legacy windows rubies", bundler: "4" do
|
|
gemfile <<-D
|
|
source "https://gem.repo1"
|
|
gem 'myrack', :platforms => [:ruby_20, :x64_mingw_20]
|
|
D
|
|
|
|
bundle "cache --all-platforms", raise_on_error: false
|
|
expect(err).to include("removed")
|
|
expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).not_to exist
|
|
end
|
|
|
|
it "does not attempt to install gems in without groups" do
|
|
build_repo4 do
|
|
build_gem "uninstallable", "2.0" do |s|
|
|
s.add_development_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", "task(:default) { raise 'CANNOT INSTALL' }"
|
|
end
|
|
end
|
|
|
|
bundle "config set --local without wo"
|
|
install_gemfile <<-G, artifice: "compact_index_extra_api"
|
|
source "https://main.repo"
|
|
gem "myrack"
|
|
group :wo do
|
|
gem "weakling"
|
|
gem "uninstallable", :source => "https://main.repo/extra"
|
|
end
|
|
G
|
|
|
|
bundle :cache, "all-platforms" => true, artifice: "compact_index_extra_api"
|
|
expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
|
|
expect(bundled_app("vendor/cache/uninstallable-2.0.gem")).to exist
|
|
expect(the_bundle).to include_gem "myrack 1.0"
|
|
expect(the_bundle).not_to include_gems "weakling", "uninstallable"
|
|
|
|
bundle "config set --local without wo"
|
|
bundle :install, artifice: "compact_index_extra_api"
|
|
expect(the_bundle).to include_gem "myrack 1.0"
|
|
expect(the_bundle).not_to include_gems "weakling"
|
|
end
|
|
|
|
it "does not fail to cache gems in excluded groups when there's a lockfile but gems not previously installed" do
|
|
bundle "config set --local without wo"
|
|
gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "myrack"
|
|
group :wo do
|
|
gem "weakling"
|
|
end
|
|
G
|
|
|
|
bundle :lock
|
|
bundle :cache, "all-platforms" => true
|
|
expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist
|
|
end
|
|
end
|
|
|
|
context "with frozen configured" do
|
|
before do
|
|
gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "myrack"
|
|
G
|
|
bundle "install"
|
|
end
|
|
|
|
subject do
|
|
bundle "config set --local frozen true"
|
|
bundle :cache, raise_on_error: false
|
|
end
|
|
|
|
it "tries to install with frozen" do
|
|
bundle "config set deployment true"
|
|
gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "myrack"
|
|
gem "myrack-obama"
|
|
G
|
|
subject
|
|
expect(exitstatus).to eq(16)
|
|
expect(err).to include("frozen mode")
|
|
expect(err).to include("You have added to the Gemfile")
|
|
expect(err).to include("* myrack-obama")
|
|
bundle "env"
|
|
expect(out).to include("frozen").or include("deployment")
|
|
end
|
|
end
|
|
|
|
context "with gems with extensions" do
|
|
before do
|
|
build_repo2 do
|
|
build_gem "racc", "2.0" do |s|
|
|
s.add_dependency "rake"
|
|
s.extensions << "Rakefile"
|
|
s.write "Rakefile", "task(:default) { puts 'INSTALLING myrack' }"
|
|
end
|
|
end
|
|
|
|
gemfile <<~G
|
|
source "https://gem.repo2"
|
|
|
|
gem "racc"
|
|
G
|
|
end
|
|
|
|
it "installs them properly from cache to a different path" do
|
|
bundle "cache"
|
|
bundle "config set --local path vendor/bundle"
|
|
bundle "install --local"
|
|
end
|
|
end
|
|
end
|
|
|
|
RSpec.describe "bundle install with gem sources" do
|
|
describe "when cached and locked" do
|
|
it "does not hit the remote at all" do
|
|
build_repo2
|
|
install_gemfile <<-G
|
|
source "https://gem.repo2"
|
|
gem "myrack"
|
|
G
|
|
|
|
bundle :cache
|
|
pristine_system_gems
|
|
FileUtils.rm_r gem_repo2
|
|
|
|
bundle "install --local"
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
end
|
|
|
|
it "does not hit the remote at all in frozen mode" do
|
|
build_repo2
|
|
install_gemfile <<-G
|
|
source "https://gem.repo2"
|
|
gem "myrack"
|
|
G
|
|
|
|
bundle :cache
|
|
pristine_system_gems
|
|
FileUtils.rm_r gem_repo2
|
|
|
|
bundle "config set --local deployment true"
|
|
bundle "config set --local path vendor/bundle"
|
|
bundle :install
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
end
|
|
|
|
it "does not hit the remote at all when cache_all_platforms configured" do
|
|
build_repo2
|
|
install_gemfile <<-G
|
|
source "https://gem.repo2"
|
|
gem "myrack"
|
|
G
|
|
|
|
bundle :cache
|
|
pristine_system_gems
|
|
FileUtils.rm_r gem_repo2
|
|
|
|
bundle "config set --local cache_all_platforms true"
|
|
bundle "config set --local path vendor/bundle"
|
|
bundle "install --local"
|
|
expect(out).not_to include("Fetching gem metadata")
|
|
expect(the_bundle).to include_gems "myrack 1.0.0"
|
|
end
|
|
|
|
it "uses cached gems for secondary sources when cache_all_platforms configured" do
|
|
build_repo4 do
|
|
build_gem "foo", "1.0.0" do |s|
|
|
s.platform = "x86_64-linux"
|
|
end
|
|
|
|
build_gem "foo", "1.0.0" do |s|
|
|
s.platform = "arm64-darwin"
|
|
end
|
|
end
|
|
|
|
gemfile <<~G
|
|
source "https://gem.repo2"
|
|
|
|
source "https://gem.repo4" do
|
|
gem "foo"
|
|
end
|
|
G
|
|
|
|
lockfile <<~L
|
|
GEM
|
|
remote: https://gem.repo2/
|
|
specs:
|
|
|
|
GEM
|
|
remote: https://gem.repo4/
|
|
specs:
|
|
foo (1.0.0-x86_64-linux)
|
|
foo (1.0.0-arm64-darwin)
|
|
|
|
PLATFORMS
|
|
arm64-darwin
|
|
ruby
|
|
x86_64-linux
|
|
|
|
DEPENDENCIES
|
|
foo
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
L
|
|
|
|
simulate_platform "x86_64-linux" do
|
|
bundle "config set cache_all_platforms true"
|
|
bundle "config set path vendor/bundle"
|
|
bundle :cache, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
|
|
|
|
# simulate removal of all remote gems
|
|
empty_repo4
|
|
|
|
# delete compact index cache
|
|
FileUtils.rm_r home(".bundle/cache/compact_index")
|
|
|
|
bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
|
|
|
|
expect(the_bundle).to include_gems "foo 1.0.0 x86_64-linux"
|
|
end
|
|
end
|
|
|
|
it "does not reinstall already-installed gems" do
|
|
install_gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "myrack"
|
|
G
|
|
bundle :cache
|
|
|
|
build_gem "myrack", "1.0.0", path: bundled_app("vendor/cache") do |s|
|
|
s.write "lib/myrack.rb", "raise 'omg'"
|
|
end
|
|
|
|
bundle :install
|
|
expect(err).to be_empty
|
|
expect(the_bundle).to include_gems "myrack 1.0"
|
|
end
|
|
|
|
it "ignores cached gems for the wrong platform" do
|
|
simulate_platform "java" do
|
|
install_gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "platform_specific"
|
|
G
|
|
bundle :cache
|
|
end
|
|
|
|
pristine_system_gems
|
|
|
|
bundle "config set --local force_ruby_platform true"
|
|
|
|
install_gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "platform_specific"
|
|
G
|
|
expect(the_bundle).to include_gems("platform_specific 1.0 ruby")
|
|
end
|
|
|
|
it "keeps gems that are locked and cached for the current platform, even if incompatible with the current ruby" do
|
|
build_repo4 do
|
|
build_gem "bcrypt_pbkdf", "1.1.1"
|
|
build_gem "bcrypt_pbkdf", "1.1.1" do |s|
|
|
s.platform = "arm64-darwin"
|
|
s.required_ruby_version = "< #{current_ruby_minor}"
|
|
end
|
|
end
|
|
|
|
app_cache = bundled_app("vendor/cache")
|
|
FileUtils.mkdir_p app_cache
|
|
FileUtils.cp gem_repo4("gems/bcrypt_pbkdf-1.1.1-arm64-darwin.gem"), app_cache
|
|
FileUtils.cp gem_repo4("gems/bcrypt_pbkdf-1.1.1.gem"), app_cache
|
|
|
|
bundle "config cache_all_platforms true"
|
|
|
|
lockfile <<~L
|
|
GEM
|
|
remote: https://gem.repo4/
|
|
specs:
|
|
bcrypt_pbkdf (1.1.1)
|
|
bcrypt_pbkdf (1.1.1-arm64-darwin)
|
|
|
|
PLATFORMS
|
|
arm64-darwin
|
|
ruby
|
|
|
|
DEPENDENCIES
|
|
bcrypt_pbkdf
|
|
|
|
BUNDLED WITH
|
|
#{Bundler::VERSION}
|
|
L
|
|
|
|
simulate_platform "arm64-darwin-23" do
|
|
install_gemfile <<~G, verbose: true
|
|
source "https://gem.repo4"
|
|
gem "bcrypt_pbkdf"
|
|
G
|
|
|
|
expect(out).to include("Updating files in vendor/cache")
|
|
expect(err).to be_empty
|
|
expect(app_cache.join("bcrypt_pbkdf-1.1.1-arm64-darwin.gem")).to exist
|
|
expect(app_cache.join("bcrypt_pbkdf-1.1.1.gem")).to exist
|
|
end
|
|
end
|
|
|
|
it "does not update the cache if --no-cache is passed" do
|
|
gemfile <<-G
|
|
source "https://gem.repo1"
|
|
gem "myrack"
|
|
G
|
|
bundled_app("vendor/cache").mkpath
|
|
expect(bundled_app("vendor/cache").children).to be_empty
|
|
|
|
bundle "install --no-cache"
|
|
expect(bundled_app("vendor/cache").children).to be_empty
|
|
end
|
|
end
|
|
end
|