diff options
Diffstat (limited to 'spec')
287 files changed, 11274 insertions, 7199 deletions
diff --git a/spec/bundler/bundler/bundler_spec.rb b/spec/bundler/bundler/bundler_spec.rb index 6a2e435e54..7cfc12a6f6 100644 --- a/spec/bundler/bundler/bundler_spec.rb +++ b/spec/bundler/bundler/bundler_spec.rb @@ -227,14 +227,14 @@ RSpec.describe Bundler do describe "#mkdir_p" do it "creates a folder at the given path" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G allow(Bundler).to receive(:root).and_return(bundled_app) - Bundler.mkdir_p(bundled_app.join("foo", "bar")) - expect(bundled_app.join("foo", "bar")).to exist + Bundler.mkdir_p(bundled_app("foo", "bar")) + expect(bundled_app("foo", "bar")).to exist end end @@ -267,6 +267,7 @@ RSpec.describe Bundler do it "should issue a warning and return a temporary user home" do allow(Bundler.rubygems).to receive(:user_home).and_return(path) allow(File).to receive(:directory?).with(path).and_return true + allow(File).to receive(:writable?).and_call_original allow(File).to receive(:writable?).with(path).and_return false allow(File).to receive(:directory?).with(dotbundle).and_return false allow(Bundler).to receive(:tmp).and_return(Pathname.new("/tmp/trulyrandom")) diff --git a/spec/bundler/bundler/cli_spec.rb b/spec/bundler/bundler/cli_spec.rb index c71fc8e9e7..b2cc1ccfef 100644 --- a/spec/bundler/bundler/cli_spec.rb +++ b/spec/bundler/bundler/cli_spec.rb @@ -101,30 +101,30 @@ RSpec.describe "bundle executable" do context "when ENV['BUNDLE_GEMFILE'] is set to an empty string" do it "ignores it" do gemfile bundled_app_gemfile, <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle :install, env: { "BUNDLE_GEMFILE" => "" } - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end context "with --verbose" do it "prints the running command" do - gemfile "source \"#{file_uri_for(gem_repo1)}\"" + gemfile "source 'https://gem.repo1'" bundle "info bundler", verbose: true expect(out).to start_with("Running `bundle info bundler --verbose` with bundler #{Bundler::VERSION}") end it "doesn't print defaults" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", verbose: true + install_gemfile "source 'https://gem.repo1'", verbose: true expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}") end it "doesn't print defaults" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", verbose: true + install_gemfile "source 'https://gem.repo1'", verbose: true expect(out).to start_with("Running `bundle install --verbose` with bundler #{Bundler::VERSION}") end end @@ -138,8 +138,8 @@ RSpec.describe "bundle executable" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", '0.9.1' + source "https://gem.repo1" + gem "myrack", '0.9.1' G end @@ -149,8 +149,8 @@ RSpec.describe "bundle executable" do it "prints a message when there are outdated gems" do run_command - expect(out).to include("Gem Current Latest Requested Groups") - expect(out).to include("rack 0.9.1 1.0.0 = 0.9.1 default") + expect(out).to include("Gem Current Latest Requested Groups") + expect(out).to include("myrack 0.9.1 1.0.0 = 0.9.1 default") end end @@ -160,7 +160,7 @@ RSpec.describe "bundle executable" do it "prints a message when there are outdated gems" do run_command - expect(out).to include("rack (newest 1.0.0, installed 0.9.1, requested = 0.9.1)") + expect(out).to include("myrack (newest 1.0.0, installed 0.9.1, requested = 0.9.1)") end end @@ -170,7 +170,7 @@ RSpec.describe "bundle executable" do it "prints a simplified message when there are outdated gems" do run_command - expect(out).to include("rack (newest 1.0.0, installed 0.9.1, requested = 0.9.1)") + expect(out).to include("myrack (newest 1.0.0, installed 0.9.1, requested = 0.9.1)") end end end diff --git a/spec/bundler/bundler/compact_index_client/parser_spec.rb b/spec/bundler/bundler/compact_index_client/parser_spec.rb new file mode 100644 index 0000000000..1f6b9e593b --- /dev/null +++ b/spec/bundler/bundler/compact_index_client/parser_spec.rb @@ -0,0 +1,237 @@ +# frozen_string_literal: true + +require "bundler/compact_index_client" +require "bundler/compact_index_client/parser" + +TestCompactIndexClient = Struct.new(:names, :versions, :info_data) do + # Requiring the checksum to match the input data helps ensure + # that we are parsing the correct checksum from the versions file + def info(name, checksum) + info_data.dig(name, checksum) + end + + def set_info_data(name, value) + info_data[name] = value + end +end + +RSpec.describe Bundler::CompactIndexClient::Parser do + subject(:parser) { described_class.new(compact_index) } + + let(:compact_index) { TestCompactIndexClient.new(names, versions, info_data) } + let(:names) { "a\nb\nc\n" } + let(:versions) { <<~VERSIONS.dup } + created_at: 2024-05-01T00:00:04Z + --- + a 1.0.0,1.0.1,1.1.0 aaa111 + b 2.0.0,2.0.0-java bbb222 + c 3.0.0,3.0.3,3.3.3 ccc333 + c -3.0.3 ccc333yanked + VERSIONS + let(:info_data) do + { + "a" => { "aaa111" => a_info }, + "b" => { "bbb222" => b_info }, + "c" => { "ccc333yanked" => c_info }, + } + end + let(:a_info) { <<~INFO.dup } + --- + 1.0.0 |checksum:aaa1,ruby:>= 3.0.0,rubygems:>= 3.2.3 + 1.0.1 |checksum:aaa2,ruby:>= 3.0.0,rubygems:>= 3.2.3 + 1.1.0 |checksum:aaa3,ruby:>= 3.0.0,rubygems:>= 3.2.3 + INFO + let(:b_info) { <<~INFO } + 2.0.0 a:~> 1.0&<= 3.0|checksum:bbb1 + 2.0.0-java a:~> 1.0&<= 3.0|checksum:bbb2 + INFO + let(:c_info) { <<~INFO } + 3.0.0 a:= 1.0.0,b:~> 2.0|checksum:ccc1,ruby:>= 2.7.0,rubygems:>= 3.0.0 + 3.3.3 a:>= 1.1.0,b:~> 2.0|checksum:ccc3,ruby:>= 3.0.0,rubygems:>= 3.2.3 + INFO + + describe "#available?" do + it "returns true versions are available" do + expect(parser).to be_available + end + + it "returns true when versions has only one gem" do + compact_index.versions = +"a 1.0.0 aaa1\n" + expect(parser).to be_available + end + + it "returns true when versions has a gem and a header" do + compact_index.versions = +"---\na 1.0.0 aaa1\n" + expect(parser).to be_available + end + + it "returns true when versions has a gem and a header with header data" do + compact_index.versions = +"created_at: 2024-05-01T00:00:04Z\n---\na 1.0.0 aaa1\n" + expect(parser).to be_available + end + + it "returns false when versions has only the header" do + compact_index.versions = +"---\n" + expect(parser).not_to be_available + end + + it "returns false when versions has only the header with header data" do + compact_index.versions = +"created_at: 2024-05-01T00:00:04Z\n---\n" + expect(parser).not_to be_available + end + + it "returns false when versions index is not available" do + compact_index.versions = nil + expect(parser).not_to be_available + end + + it "returns false when versions is empty" do + compact_index.versions = +"" + expect(parser).not_to be_available + end + end + + describe "#names" do + it "returns the names" do + expect(parser.names).to eq(%w[a b c]) + end + + it "returns an empty array when names is empty" do + compact_index.names = "" + expect(parser.names).to eq([]) + end + + it "returns an empty array when names is not readable" do + compact_index.names = nil + expect(parser.names).to eq([]) + end + end + + describe "#versions" do + it "returns the versions" do + expect(parser.versions).to eq( + "a" => [ + ["a", "1.0.0"], + ["a", "1.0.1"], + ["a", "1.1.0"], + ], + "b" => [ + ["b", "2.0.0"], + ["b", "2.0.0", "java"], + ], + "c" => [ + ["c", "3.0.0"], + ["c", "3.3.3"], + ], + ) + end + + it "returns an empty hash when versions is empty" do + compact_index.versions = "" + expect(parser.versions).to eq({}) + end + + it "returns an empty hash when versions is not readable" do + compact_index.versions = nil + expect(parser.versions).to eq({}) + end + end + + describe "#info" do + let(:a_result) do + [ + [ + "a", + "1.0.0", + nil, + [], + [["checksum", ["aaa1"]], ["ruby", [">= 3.0.0"]], ["rubygems", [">= 3.2.3"]]], + ], + [ + "a", + "1.0.1", + nil, + [], + [["checksum", ["aaa2"]], ["ruby", [">= 3.0.0"]], ["rubygems", [">= 3.2.3"]]], + ], + [ + "a", + "1.1.0", + nil, + [], + [["checksum", ["aaa3"]], ["ruby", [">= 3.0.0"]], ["rubygems", [">= 3.2.3"]]], + ], + ] + end + let(:b_result) do + [ + [ + "b", + "2.0.0", + nil, + [["a", ["~> 1.0", "<= 3.0"]]], + [["checksum", ["bbb1"]]], + ], + [ + "b", + "2.0.0", + "java", + [["a", ["~> 1.0", "<= 3.0"]]], + [["checksum", ["bbb2"]]], + ], + ] + end + let(:c_result) do + [ + [ + "c", + "3.0.0", + nil, + [["a", ["= 1.0.0"]], ["b", ["~> 2.0"]]], + [["checksum", ["ccc1"]], ["ruby", [">= 2.7.0"]], ["rubygems", [">= 3.0.0"]]], + ], + [ + "c", + "3.3.3", + nil, + [["a", [">= 1.1.0"]], ["b", ["~> 2.0"]]], + [["checksum", ["ccc3"]], ["ruby", [">= 3.0.0"]], ["rubygems", [">= 3.2.3"]]], + ], + ] + end + + it "returns the info for example gem 'a' which has no deps" do + expect(parser.info("a")).to eq(a_result) + end + + it "returns the info for example gem 'b' which has platform and compound deps" do + expect(parser.info("b")).to eq(b_result) + end + + it "returns the info for example gem 'c' which has deps and yanked version (requires use of correct info checksum)" do + expect(parser.info("c")).to eq(c_result) + end + + it "returns an empty array when the info is empty" do + compact_index.set_info_data("a", {}) + expect(parser.info("a")).to eq([]) + end + + it "returns an empty array when the info is not readable" do + expect(parser.info("d")).to eq([]) + end + + it "handles empty lines in the versions file (Artifactory bug that they have yet to fix)" do + compact_index.versions = +<<~VERSIONS + created_at: 2024-05-01T00:00:04Z + --- + a 1.0.0,1.0.1,1.1.0 aaa111 + b 2.0.0,2.0.0-java bbb222 + + c 3.0.0,3.0.3,3.3.3 ccc333 + c -3.0.3 ccc333yanked + VERSIONS + expect(parser.info("a")).to eq(a_result) + end + end +end diff --git a/spec/bundler/bundler/compact_index_client/updater_spec.rb b/spec/bundler/bundler/compact_index_client/updater_spec.rb index 6eed88ca9e..87a73d993f 100644 --- a/spec/bundler/bundler/compact_index_client/updater_spec.rb +++ b/spec/bundler/bundler/compact_index_client/updater_spec.rb @@ -119,23 +119,7 @@ RSpec.describe Bundler::CompactIndexClient::Updater do context "without an etag file" do let(:headers) do - { - "Range" => "bytes=2-", - # This MD5 feature should be deleted after sufficient time has passed since release. - # From then on, requests that still don't have a saved etag will be made without this header. - "If-None-Match" => %("#{Digest::MD5.hexdigest(local_body)}"), - } - end - - it "saves only the etag_path if generated etag matches" do - expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response) - allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { false } - allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { true } - - updater.update(remote_path, local_path, etag_path) - - expect(local_path.read).to eq("abc") - expect(%("#{etag_path.read}")).to eq(headers["If-None-Match"]) + { "Range" => "bytes=2-" } end it "appends the file" do diff --git a/spec/bundler/bundler/definition_spec.rb b/spec/bundler/bundler/definition_spec.rb index 28c04e0860..6f8b24e68a 100644 --- a/spec/bundler/bundler/definition_spec.rb +++ b/spec/bundler/bundler/definition_spec.rb @@ -45,17 +45,17 @@ RSpec.describe Bundler::Definition do build_lib "foo", "1.0", path: lib_path("foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "1.0" + s.add_dependency "myrack", "1.0" end - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" - c.checksum gem_repo1, "rack", "1.0.0" + c.checksum gem_repo1, "myrack", "1.0.0" end bundle :install, env: { "DEBUG" => "1" } @@ -66,12 +66,12 @@ RSpec.describe Bundler::Definition do remote: #{lib_path("foo")} specs: foo (1.0) - rack (= 1.0) + myrack (= 1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} @@ -91,7 +91,7 @@ RSpec.describe Bundler::Definition do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "ffi" G @@ -104,17 +104,17 @@ RSpec.describe Bundler::Definition do it "for a path gem with deps and no changes" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "1.0" + s.add_dependency "myrack", "1.0" s.add_development_dependency "net-ssh", "1.0" end - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" - c.checksum gem_repo1, "rack", "1.0.0" + c.checksum gem_repo1, "myrack", "1.0.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G @@ -123,12 +123,12 @@ RSpec.describe Bundler::Definition do remote: #{lib_path("foo")} specs: foo (1.0) - rack (= 1.0) + myrack (= 1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} @@ -149,22 +149,22 @@ RSpec.describe Bundler::Definition do end it "for a locked gem for another platform" do - checksums = checksums_section_when_existing do |c| - c.no_checksum "only_java", "1.1", "java" - end - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "only_java", platform: :jruby G + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo1, "only_java", "1.1", "java" + end + bundle "lock --add-platform java" bundle :check, env: { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: only_java (1.1-java) @@ -180,12 +180,12 @@ RSpec.describe Bundler::Definition do end it "for a rubygems gem" do - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo1, "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G @@ -194,7 +194,7 @@ RSpec.describe Bundler::Definition do expect(out).to match(/using resolution from the lockfile/) expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: foo (1.0) @@ -215,13 +215,13 @@ RSpec.describe Bundler::Definition do context "eager unlock" do let(:source_list) do Bundler::SourceList.new.tap do |source_list| - source_list.add_global_rubygems_remote(file_uri_for(gem_repo4)) + source_list.add_global_rubygems_remote("https://gem.repo4") end end before do gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'isolated_owner' gem 'shared_owner_a' @@ -230,7 +230,7 @@ RSpec.describe Bundler::Definition do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: isolated_dep (2.0.1) isolated_owner (1.0.1) diff --git a/spec/bundler/bundler/dsl_spec.rb b/spec/bundler/bundler/dsl_spec.rb index 3c3b6c26c3..7b6d080593 100644 --- a/spec/bundler/bundler/dsl_spec.rb +++ b/spec/bundler/bundler/dsl_spec.rb @@ -175,7 +175,7 @@ RSpec.describe Bundler::Dsl do it "handles syntax errors with a useful message" do expect(Bundler).to receive(:read_file).with(source_root.join("Gemfile").to_s).and_return("}") expect { subject.eval_gemfile("Gemfile") }. - to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`: (syntax error, unexpected tSTRING_DEND|(compile error - )?syntax error, unexpected '\}'). Bundler cannot continue./) + to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`: (syntax error, unexpected tSTRING_DEND|(compile error - )?syntax error, unexpected '\}'|.+?unexpected '}', ignoring it\n). Bundler cannot continue./m) end it "distinguishes syntax errors from evaluation errors" do @@ -322,7 +322,7 @@ RSpec.describe Bundler::Dsl do it "will raise a Bundler::GemfileError" do gemfile "gem 'foo', :path => /unquoted/string/syntax/error" expect { Bundler::Dsl.evaluate(bundled_app_gemfile, nil, true) }. - to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`:( compile error -)? unknown regexp options - trg.+ Bundler cannot continue./) + to raise_error(Bundler::GemfileError, /There was an error parsing `Gemfile`:( compile error -)?.+?unknown regexp options - trg.+ Bundler cannot continue./m) end end diff --git a/spec/bundler/bundler/env_spec.rb b/spec/bundler/bundler/env_spec.rb index 7997cb0c40..e0ab0a45e3 100644 --- a/spec/bundler/bundler/env_spec.rb +++ b/spec/bundler/bundler/env_spec.rb @@ -70,16 +70,16 @@ RSpec.describe Bundler::Env do context "when there is a Gemfile and a lockfile and print_gemfile is true" do before do - gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem 'rack', '1.0.0'" + gemfile "source 'https://gem.repo1'; gem 'myrack', '1.0.0'" lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) DEPENDENCIES - rack + myrack BUNDLED WITH 1.10.0 @@ -92,12 +92,12 @@ RSpec.describe Bundler::Env do it "prints the Gemfile" do expect(output).to include("Gemfile") - expect(output).to include("'rack', '1.0.0'") + expect(output).to include("'myrack', '1.0.0'") end it "prints the lockfile" do expect(output).to include("Gemfile.lock") - expect(output).to include("rack (1.0.0)") + expect(output).to include("myrack (1.0.0)") end end @@ -148,9 +148,9 @@ RSpec.describe Bundler::Env do end before do - gemfile("source \"#{file_uri_for(gem_repo1)}\"; gemspec") + gemfile("source 'https://gem.repo1'; gemspec") - File.open(bundled_app.join("foo.gemspec"), "wb") do |f| + File.open(bundled_app("foo.gemspec"), "wb") do |f| f.write(gemspec) end @@ -167,10 +167,10 @@ RSpec.describe Bundler::Env do context "when eval_gemfile is used" do it "prints all gemfiles" do - create_file bundled_app("other/Gemfile-other"), "gem 'rack'" - create_file bundled_app("other/Gemfile"), "eval_gemfile 'Gemfile-other'" - create_file bundled_app("Gemfile-alt"), <<-G - source "#{file_uri_for(gem_repo1)}" + gemfile bundled_app("other/Gemfile-other"), "gem 'myrack'" + gemfile bundled_app("other/Gemfile"), "eval_gemfile 'Gemfile-other'" + gemfile bundled_app("Gemfile-alt"), <<-G + source "https://gem.repo1" eval_gemfile "other/Gemfile" G gemfile "eval_gemfile #{bundled_app("Gemfile-alt").to_s.dump}" @@ -190,7 +190,7 @@ RSpec.describe Bundler::Env do ### Gemfile-alt ```ruby - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "other/Gemfile" ``` @@ -203,7 +203,7 @@ RSpec.describe Bundler::Env do ### other/Gemfile-other ```ruby - gem 'rack' + gem 'myrack' ``` ### Gemfile.lock diff --git a/spec/bundler/bundler/fetcher/compact_index_spec.rb b/spec/bundler/bundler/fetcher/compact_index_spec.rb index a988171f34..aa536673d9 100644 --- a/spec/bundler/bundler/fetcher/compact_index_spec.rb +++ b/spec/bundler/bundler/fetcher/compact_index_spec.rb @@ -4,14 +4,18 @@ require "bundler/compact_index_client" RSpec.describe Bundler::Fetcher::CompactIndex do - let(:downloader) { double(:downloader) } + let(:response) { double(:response) } + let(:downloader) { double(:downloader, fetch: response) } let(:display_uri) { Gem::URI("http://sampleuri.com") } let(:remote) { double(:remote, cache_slug: "lsjdf", uri: display_uri) } let(:gem_remote_fetcher) { nil } let(:compact_index) { described_class.new(downloader, remote, display_uri, gem_remote_fetcher) } + let(:compact_index_client) { double(:compact_index_client, available?: true, info: [["lskdjf", "1", nil, [], []]]) } before do + allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified).and_return(true) allow(compact_index).to receive(:log_specs) {} + allow(compact_index).to receive(:compact_index_client).and_return(compact_index_client) end describe "#specs_for_names" do @@ -32,11 +36,6 @@ RSpec.describe Bundler::Fetcher::CompactIndex do end describe "#available?" do - before do - allow(compact_index).to receive(:compact_index_client). - and_return(double(:compact_index_client, update_and_parse_checksums!: true)) - end - it "returns true" do expect(compact_index).to be_available end diff --git a/spec/bundler/bundler/friendly_errors_spec.rb b/spec/bundler/bundler/friendly_errors_spec.rb index cda2ef31de..255019f40a 100644 --- a/spec/bundler/bundler/friendly_errors_spec.rb +++ b/spec/bundler/bundler/friendly_errors_spec.rb @@ -18,8 +18,8 @@ RSpec.describe Bundler, "friendly errors" do it "reports a relevant friendly error message" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle :install, env: { "DEBUG" => "true" } diff --git a/spec/bundler/bundler/gem_helper_spec.rb b/spec/bundler/bundler/gem_helper_spec.rb index 940e5df9de..94f66537d3 100644 --- a/spec/bundler/bundler/gem_helper_spec.rb +++ b/spec/bundler/bundler/gem_helper_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Bundler::GemHelper do before(:each) do global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false" - sys_exec("git config --global init.defaultBranch main") + git("config --global init.defaultBranch main") bundle "gem #{app_name}" prepare_gemspec(app_gemspec_path) end @@ -253,11 +253,11 @@ RSpec.describe Bundler::GemHelper do end before do - sys_exec("git init", dir: app_path) - sys_exec("git config user.email \"you@example.com\"", dir: app_path) - sys_exec("git config user.name \"name\"", dir: app_path) - sys_exec("git config commit.gpgsign false", dir: app_path) - sys_exec("git config push.default simple", dir: app_path) + git("init", app_path) + git("config user.email \"you@example.com\"", app_path) + git("config user.name \"name\"", app_path) + git("config commit.gpgsign false", app_path) + git("config push.default simple", app_path) # silence messages allow(Bundler.ui).to receive(:confirm) @@ -271,13 +271,13 @@ RSpec.describe Bundler::GemHelper do end it "when there are uncommitted files" do - sys_exec("git add .", dir: app_path) + git("add .", app_path) expect { Rake.application["release"].invoke }. to raise_error("There are files that need to be committed first.") end it "when there is no git remote" do - sys_exec("git commit -a -m \"initial commit\"", dir: app_path) + git("commit -a -m \"initial commit\"", app_path) expect { Rake.application["release"].invoke }.to raise_error(RuntimeError) end end @@ -286,8 +286,8 @@ RSpec.describe Bundler::GemHelper do let(:repo) { build_git("foo", bare: true) } before do - sys_exec("git remote add origin #{file_uri_for(repo.path)}", dir: app_path) - sys_exec('git commit -a -m "initial commit"', dir: app_path) + git("remote add origin #{repo.path}", app_path) + git('commit -a -m "initial commit"', app_path) end context "on releasing" do @@ -296,7 +296,7 @@ RSpec.describe Bundler::GemHelper do mock_confirm_message "Tagged v#{app_version}." mock_confirm_message "Pushed git commits and release tag." - sys_exec("git push -u origin main", dir: app_path) + git("push -u origin main", app_path) end it "calls rubygem_push with proper arguments" do @@ -314,8 +314,8 @@ RSpec.describe Bundler::GemHelper do it "also works when releasing from an ambiguous reference" do # Create a branch with the same name as the tag - sys_exec("git checkout -b v#{app_version}", dir: app_path) - sys_exec("git push -u origin v#{app_version}", dir: app_path) + git("checkout -b v#{app_version}", app_path) + git("push -u origin v#{app_version}", app_path) expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s) @@ -323,7 +323,7 @@ RSpec.describe Bundler::GemHelper do end it "also works with releasing from a branch not yet pushed" do - sys_exec("git checkout -b module_function", dir: app_path) + git("checkout -b module_function", app_path) expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s) @@ -337,7 +337,7 @@ RSpec.describe Bundler::GemHelper do mock_build_message app_name, app_version mock_confirm_message "Pushed git commits and release tag." - sys_exec("git push -u origin main", dir: app_path) + git("push -u origin main", app_path) expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s) end @@ -353,7 +353,7 @@ RSpec.describe Bundler::GemHelper do mock_confirm_message "Tag v#{app_version} has already been created." expect(subject).to receive(:rubygem_push).with(app_gem_path.to_s) - sys_exec("git tag -a -m \"Version #{app_version}\" v#{app_version}", dir: app_path) + git("tag -a -m \"Version #{app_version}\" v#{app_version}", app_path) Rake.application["release"].invoke end @@ -374,10 +374,10 @@ RSpec.describe Bundler::GemHelper do end before do - sys_exec("git init", dir: app_path) - sys_exec("git config user.email \"you@example.com\"", dir: app_path) - sys_exec("git config user.name \"name\"", dir: app_path) - sys_exec("git config push.gpgsign simple", dir: app_path) + git("init", app_path) + git("config user.email \"you@example.com\"", app_path) + git("config user.name \"name\"", app_path) + git("config push.gpgsign simple", app_path) # silence messages allow(Bundler.ui).to receive(:confirm) diff --git a/spec/bundler/bundler/installer/gem_installer_spec.rb b/spec/bundler/bundler/installer/gem_installer_spec.rb index 4b6a07f344..6583bd8181 100644 --- a/spec/bundler/bundler/installer/gem_installer_spec.rb +++ b/spec/bundler/bundler/installer/gem_installer_spec.rb @@ -7,6 +7,7 @@ RSpec.describe Bundler::GemInstaller do let(:installer) { instance_double("Installer", definition: definition) } let(:spec_source) { instance_double("SpecSource") } let(:spec) { instance_double("Specification", name: "dummy", version: "0.0.1", loaded_from: "dummy", source: spec_source) } + let(:base_options) { { force: false, local: false, previous_spec: nil } } subject { described_class.new(spec, installer) } @@ -14,7 +15,7 @@ RSpec.describe Bundler::GemInstaller do it "invokes install method with empty build_args" do allow(spec_source).to receive(:install).with( spec, - { force: false, ensure_builtin_gems_cached: false, build_args: [], previous_spec: nil } + base_options.merge(build_args: []) ) subject.install_from_spec end @@ -28,7 +29,7 @@ RSpec.describe Bundler::GemInstaller do allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy") expect(spec_source).to receive(:install).with( spec, - { force: false, ensure_builtin_gems_cached: false, build_args: ["--with-dummy-config=dummy"], previous_spec: nil } + base_options.merge(build_args: ["--with-dummy-config=dummy"]) ) subject.install_from_spec end @@ -42,7 +43,7 @@ RSpec.describe Bundler::GemInstaller do allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy --with-another-dummy-config") expect(spec_source).to receive(:install).with( spec, - { force: false, ensure_builtin_gems_cached: false, build_args: ["--with-dummy-config=dummy", "--with-another-dummy-config"], previous_spec: nil } + base_options.merge(build_args: ["--with-dummy-config=dummy", "--with-another-dummy-config"]) ) subject.install_from_spec end diff --git a/spec/bundler/bundler/plugin/index_spec.rb b/spec/bundler/bundler/plugin/index_spec.rb index 5a7047459f..e1f10a0db7 100644 --- a/spec/bundler/bundler/plugin/index_spec.rb +++ b/spec/bundler/bundler/plugin/index_spec.rb @@ -5,7 +5,7 @@ RSpec.describe Bundler::Plugin::Index do before do allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) - gemfile "source \"#{file_uri_for(gem_repo1)}\"" + gemfile "source 'https://gem.repo1'" path = lib_path(plugin_name) index.register_plugin("new-plugin", path.to_s, [path.join("lib").to_s], commands, sources, hooks) end diff --git a/spec/bundler/bundler/plugin/installer_spec.rb b/spec/bundler/bundler/plugin/installer_spec.rb index ed40029f5a..8e1879395a 100644 --- a/spec/bundler/bundler/plugin/installer_spec.rb +++ b/spec/bundler/bundler/plugin/installer_spec.rb @@ -57,7 +57,7 @@ RSpec.describe Bundler::Plugin::Installer do end let(:result) do - installer.install(["ga-plugin"], git: file_uri_for(lib_path("ga-plugin"))) + installer.install(["ga-plugin"], git: lib_path("ga-plugin").to_s) end it "returns the installed spec after installing" do diff --git a/spec/bundler/bundler/plugin_spec.rb b/spec/bundler/bundler/plugin_spec.rb index f41b4eff3a..3ac7b251a3 100644 --- a/spec/bundler/bundler/plugin_spec.rb +++ b/spec/bundler/bundler/plugin_spec.rb @@ -247,7 +247,7 @@ RSpec.describe Bundler::Plugin do end it "returns plugin dir in app .bundle path" do - expect(subject.root).to eq(bundled_app.join(".bundle/plugin")) + expect(subject.root).to eq(bundled_app(".bundle/plugin")) end end @@ -257,7 +257,7 @@ RSpec.describe Bundler::Plugin do end it "returns plugin dir in global bundle path" do - expect(subject.root).to eq(home.join(".bundle/plugin")) + expect(subject.root).to eq(home(".bundle/plugin")) end end end diff --git a/spec/bundler/bundler/resolver/candidate_spec.rb b/spec/bundler/bundler/resolver/candidate_spec.rb index f7b378d32b..aefad3316e 100644 --- a/spec/bundler/bundler/resolver/candidate_spec.rb +++ b/spec/bundler/bundler/resolver/candidate_spec.rb @@ -2,20 +2,19 @@ RSpec.describe Bundler::Resolver::Candidate do it "compares fine" do - version1 = described_class.new("1.12.5", specs: [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }]) - version2 = described_class.new("1.12.5") # passing no specs creates a platform specific candidate, so sorts higher + version1 = described_class.new("1.12.5", priority: -1) + version2 = described_class.new("1.12.5", priority: 1) - expect(version2 >= version1).to be true + expect(version2 > version1).to be true - expect(version1.generic! == version2.generic!).to be true - expect(version1.platform_specific! == version2.platform_specific!).to be true + version1 = described_class.new("1.12.5") + version2 = described_class.new("1.12.5") - expect(version1.platform_specific! >= version2.generic!).to be true - expect(version2.platform_specific! >= version1.generic!).to be true + expect(version2 == version1).to be true - version1 = described_class.new("1.12.5", specs: [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::RUBY }]) - version2 = described_class.new("1.12.5", specs: [Gem::Specification.new("foo", "1.12.5") {|s| s.platform = Gem::Platform::X64_LINUX }]) + version1 = described_class.new("1.12.5", priority: 1) + version2 = described_class.new("1.12.5", priority: -1) - expect(version2 >= version1).to be true + expect(version2 < version1).to be true end end diff --git a/spec/bundler/bundler/retry_spec.rb b/spec/bundler/bundler/retry_spec.rb index b893580d72..ffbc078074 100644 --- a/spec/bundler/bundler/retry_spec.rb +++ b/spec/bundler/bundler/retry_spec.rb @@ -68,7 +68,7 @@ RSpec.describe Bundler::Retry do it "print error message with newlines" do allow(Bundler.ui).to receive(:debug?).and_return(false) expect(Bundler.ui).to receive(:info).with("").twice - expect(Bundler.ui).to receive(:warn).with(failure_message, false) + expect(Bundler.ui).to receive(:warn).with(failure_message, true) expect do Bundler::Retry.new("test", [], 1).attempt do diff --git a/spec/bundler/bundler/ruby_dsl_spec.rb b/spec/bundler/bundler/ruby_dsl_spec.rb index 384ac4b8b2..c5ebbdf4db 100644 --- a/spec/bundler/bundler/ruby_dsl_spec.rb +++ b/spec/bundler/bundler/ruby_dsl_spec.rb @@ -80,7 +80,7 @@ RSpec.describe Bundler::RubyDsl do context "with two requirements in the same string" do let(:ruby_version) { ">= 2.0.0, < 3.0" } it "raises an error" do - expect { subject }.to raise_error(ArgumentError) + expect { subject }.to raise_error(Bundler::InvalidArgumentError) end end @@ -168,7 +168,7 @@ RSpec.describe Bundler::RubyDsl do let(:file_content) { "ruby-#{version}@gemset\n" } it "raises an error" do - expect { subject }.to raise_error(Gem::Requirement::BadRequirementError, "Illformed requirement [\"#{version}@gemset\"]") + expect { subject }.to raise_error(Bundler::InvalidArgumentError, "2.0.0@gemset is not a valid requirement on the Ruby version") end end diff --git a/spec/bundler/bundler/rubygems_integration_spec.rb b/spec/bundler/bundler/rubygems_integration_spec.rb index b6bda9f43e..81859d10f2 100644 --- a/spec/bundler/bundler/rubygems_integration_spec.rb +++ b/spec/bundler/bundler/rubygems_integration_spec.rb @@ -11,14 +11,14 @@ RSpec.describe Bundler::RubygemsIntegration do end subject { Bundler.rubygems.validate(spec) } - it "validates with packaging mode disabled" do - expect(spec).to receive(:validate).with(false) + it "validates for resolution" do + expect(spec).to receive(:validate_for_resolution) subject end context "with an invalid spec" do before do - expect(spec).to receive(:validate).with(false). + expect(spec).to receive(:validate_for_resolution). and_raise(Gem::InvalidSpecificationException.new("TODO is not an author")) end diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb index 634e0faf91..b7db548cf9 100644 --- a/spec/bundler/bundler/settings_spec.rb +++ b/spec/bundler/bundler/settings_spec.rb @@ -6,12 +6,18 @@ RSpec.describe Bundler::Settings do subject(:settings) { described_class.new(bundled_app) } describe "#set_local" do - context "when the local config file is not found" do + context "root is nil" do subject(:settings) { described_class.new(nil) } - it "raises a GemfileNotFound error with explanation" do - expect { subject.set_local("foo", "bar") }. - to raise_error(Bundler::GemfileNotFound, "Could not locate Gemfile") + before do + allow(Pathname).to receive(:new).and_call_original + allow(Pathname).to receive(:new).with(".bundle").and_return home(".bundle") + end + + it "works" do + subject.set_local("foo", "bar") + + expect(subject["foo"]).to eq("bar") end end end @@ -310,8 +316,8 @@ that would suck --ehhh=oh geez it looks like i might have broken bundler somehow let(:settings) { described_class.new(bundled_app(".bundle")) } it "converts older keys without double underscore" do - config("BUNDLE_MY__PERSONAL.RACK" => "~/Work/git/rack") - expect(settings["my.personal.rack"]).to eq("~/Work/git/rack") + config("BUNDLE_MY__PERSONAL.MYRACK" => "~/Work/git/myrack") + expect(settings["my.personal.myrack"]).to eq("~/Work/git/myrack") end it "converts older keys without trailing slashes and double underscore" do diff --git a/spec/bundler/bundler/source/git/git_proxy_spec.rb b/spec/bundler/bundler/source/git/git_proxy_spec.rb index 1450316d59..f7c883eed4 100644 --- a/spec/bundler/bundler/source/git/git_proxy_spec.rb +++ b/spec/bundler/bundler/source/git/git_proxy_spec.rb @@ -197,4 +197,18 @@ RSpec.describe Bundler::Source::Git::GitProxy do expect(Pathname.new(bundled_app("canary"))).not_to exist end + + context "URI is HTTP" do + let(:uri) { "http://github.com/rubygems/rubygems.git" } + let(:without_depth_arguments) { ["clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--single-branch"] } + let(:fail_clone_result) { double(Process::Status, success?: false) } + + it "retries without --depth when git url is http and fails" do + allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0") + allow(git_proxy).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "dumb http transport does not support shallow capabilities", fail_clone_result]) + expect(git_proxy).to receive(:capture).with([*without_depth_arguments, "--", uri, path.to_s], nil).and_return(["", "", clone_result]) + + subject.checkout + end + end end diff --git a/spec/bundler/bundler/ui/shell_spec.rb b/spec/bundler/bundler/ui/shell_spec.rb index 15120a8a41..422c850a65 100644 --- a/spec/bundler/bundler/ui/shell_spec.rb +++ b/spec/bundler/bundler/ui/shell_spec.rb @@ -10,6 +10,13 @@ RSpec.describe Bundler::UI::Shell do it "prints to stdout" do expect { subject.info("info") }.to output("info\n").to_stdout end + + context "when output_stream is :stderr" do + before { subject.output_stream = :stderr } + it "prints to stderr" do + expect { subject.info("info") }.to output("info\n").to_stderr + end + end end describe "#confirm" do @@ -17,19 +24,36 @@ RSpec.describe Bundler::UI::Shell do it "prints to stdout" do expect { subject.confirm("confirm") }.to output("confirm\n").to_stdout end + + context "when output_stream is :stderr" do + before { subject.output_stream = :stderr } + it "prints to stderr" do + expect { subject.confirm("confirm") }.to output("confirm\n").to_stderr + end + end end describe "#warn" do before { subject.level = "warn" } - it "prints to stderr" do + it "prints to stderr, implicitly adding a newline" do expect { subject.warn("warning") }.to output("warning\n").to_stderr end + it "can be told not to emit a newline" do + expect { subject.warn("warning", false) }.to output("warning").to_stderr + end end describe "#debug" do it "prints to stdout" do expect { subject.debug("debug") }.to output("debug\n").to_stdout end + + context "when output_stream is :stderr" do + before { subject.output_stream = :stderr } + it "prints to stderr" do + expect { subject.debug("debug") }.to output("debug\n").to_stderr + end + end end describe "#error" do diff --git a/spec/bundler/cache/cache_path_spec.rb b/spec/bundler/cache/cache_path_spec.rb index 12385427b1..d5bd14965b 100644 --- a/spec/bundler/cache/cache_path_spec.rb +++ b/spec/bundler/cache/cache_path_spec.rb @@ -3,15 +3,15 @@ RSpec.describe "bundle package" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end context "with --cache-path" do it "caches gems at given path" do bundle :cache, "cache-path" => "vendor/cache-foo" - expect(bundled_app("vendor/cache-foo/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache-foo/myrack-1.0.0.gem")).to exist end end @@ -19,14 +19,14 @@ RSpec.describe "bundle package" do it "caches gems at given path" do bundle "config set cache_path vendor/cache-foo" bundle :cache - expect(bundled_app("vendor/cache-foo/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache-foo/myrack-1.0.0.gem")).to exist end end context "with absolute --cache-path" do it "caches gems at given path" do - bundle :cache, "cache-path" => "/tmp/cache-foo" - expect(bundled_app("/tmp/cache-foo/rack-1.0.0.gem")).to exist + bundle :cache, "cache-path" => bundled_app("vendor/cache-foo") + expect(bundled_app("vendor/cache-foo/myrack-1.0.0.gem")).to exist end end end diff --git a/spec/bundler/cache/gems_spec.rb b/spec/bundler/cache/gems_spec.rb index abbc2c3cf2..a694df2700 100644 --- a/spec/bundler/cache/gems_spec.rb +++ b/spec/bundler/cache/gems_spec.rb @@ -4,23 +4,23 @@ RSpec.describe "bundle cache" do shared_examples_for "when there are only gemsources" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G - system_gems "rack-1.0.0", path: path + system_gems "myrack-1.0.0", path: path bundle :cache end it "copies the .gem file to vendor/cache" do - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end it "uses the cache as a source when installing gems" do build_gem "omg", path: bundled_app("vendor/cache") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "omg" G @@ -31,44 +31,44 @@ RSpec.describe "bundle cache" do system_gems [], path: default_bundle_path bundle "install --local" - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") end it "does not reinstall gems from the cache if they exist on the system" do - build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0", path: bundled_app("vendor/cache") do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") end it "does not reinstall gems from the cache if they exist in the bundle" do - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0", path: bundled_app("vendor/cache") do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end bundle :install, local: true - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") end it "creates a lockfile" do - cache_gems "rack-1.0.0" + cache_gems "myrack-1.0.0" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "cache" @@ -93,82 +93,97 @@ RSpec.describe "bundle cache" do let(:default_json_version) { ruby "gem 'json'; require 'json'; puts JSON::VERSION" } before :each do - build_repo2 do - build_gem "json", default_json_version - end - build_gem "json", default_json_version, to_system: true, default: true end - it "uses builtin gems when installing to system gems" do - bundle "config set path.system true" - install_gemfile %(source "#{file_uri_for(gem_repo1)}"; gem 'json', '#{default_json_version}'), verbose: true - expect(out).to include("Using json #{default_json_version}") - end + context "when a remote gem is available for caching" do + before do + build_repo2 do + build_gem "json", default_json_version + end + end - it "caches remote and builtin gems" do - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'json', '#{default_json_version}' - gem 'rack', '1.0.0' - G + it "uses remote gems when installing" do + install_gemfile %(source "https://gem.repo2"; gem 'json', '#{default_json_version}'), verbose: true + expect(out).to include("Installing json #{default_json_version}") + end - bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist - expect(bundled_app("vendor/cache/json-#{default_json_version}.gem")).to exist - end + it "does not use remote gems when installing with --local flag" do + install_gemfile %(source "https://gem.repo2"; gem 'json', '#{default_json_version}'), verbose: true, local: true + expect(out).to include("Using json #{default_json_version}") + end - it "caches builtin gems when cache_all_platforms is set" do - gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "json" - G + it "caches remote and builtin gems" do + install_gemfile <<-G + source "https://gem.repo2" + gem 'json', '#{default_json_version}' + gem 'myrack', '1.0.0' + G - bundle "config set cache_all_platforms true" + bundle :cache + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/json-#{default_json_version}.gem")).to exist + end - bundle :cache - expect(bundled_app("vendor/cache/json-#{default_json_version}.gem")).to exist - end + it "caches builtin gems when cache_all_platforms is set" do + gemfile <<-G + source "https://gem.repo2" + gem "json" + G + + bundle "config set cache_all_platforms true" - it "doesn't make remote request after caching the gem" do - build_gem "builtin_gem_2", "1.0.2", path: bundled_app("vendor/cache") do |s| - s.summary = "This builtin_gem is bundled with Ruby" + bundle :cache + expect(bundled_app("vendor/cache/json-#{default_json_version}.gem")).to exist end - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'builtin_gem_2', '1.0.2' - G + it "doesn't make remote request after caching the gem" do + build_gem "builtin_gem_2", "1.0.2", path: bundled_app("vendor/cache"), default: true - bundle "install --local" - expect(the_bundle).to include_gems("builtin_gem_2 1.0.2") + install_gemfile <<-G + source "https://gem.repo2" + gem 'builtin_gem_2', '1.0.2' + G + + bundle "install --local" + expect(the_bundle).to include_gems("builtin_gem_2 1.0.2") + end end - it "errors if the builtin gem isn't available to cache" do - bundle "config set path.system true" + context "when a remote gem is not available for caching" do + it "warns, but uses builtin gems when installing to system gems" do + bundle "config set path.system true" + install_gemfile %(source "https://gem.repo1"; gem 'json', '#{default_json_version}'), verbose: true + expect(err).to include("json-#{default_json_version} is built in to Ruby, and can't be cached") + expect(out).to include("Using json #{default_json_version}") + end - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'json', '#{default_json_version}' - G + it "errors when explicitly caching" do + bundle "config set path.system true" - bundle :cache, raise_on_error: false - expect(exitstatus).to_not eq(0) - expect(err).to include("json-#{default_json_version} is built in to Ruby, and can't be cached") + install_gemfile <<-G + source "https://gem.repo1" + gem 'json', '#{default_json_version}' + G + + bundle :cache, raise_on_error: false + expect(exitstatus).to_not eq(0) + expect(err).to include("json-#{default_json_version} is built in to Ruby, and can't be cached") + end end end describe "when there are also git sources" do before do build_git "foo" - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem 'foo' end - gem 'rack' + gem 'myrack' G end @@ -178,7 +193,7 @@ RSpec.describe "bundle cache" do system_gems [] bundle "install --local" - expect(the_bundle).to include_gems("rack 1.0.0", "foo 1.0") + expect(the_bundle).to include_gems("myrack 1.0.0", "foo 1.0") end it "should not explode if the lockfile is not present" do @@ -191,41 +206,44 @@ RSpec.describe "bundle cache" do end describe "when previously cached" do - before :each do + let :setup_main_repo do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" gem "actionpack" G bundle :cache - expect(cached_gem("rack-1.0.0")).to exist + expect(cached_gem("myrack-1.0.0")).to exist expect(cached_gem("actionpack-2.3.2")).to exist expect(cached_gem("activesupport-2.3.2")).to exist end it "re-caches during install" do - cached_gem("rack-1.0.0").rmtree + setup_main_repo + cached_gem("myrack-1.0.0").rmtree bundle :install expect(out).to include("Updating files in vendor/cache") - expect(cached_gem("rack-1.0.0")).to exist + expect(cached_gem("myrack-1.0.0")).to exist end it "adds and removes when gems are updated" do + setup_main_repo update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end end bundle "update", all: true - expect(cached_gem("rack-1.2")).to exist - expect(cached_gem("rack-1.0.0")).not_to exist + expect(cached_gem("myrack-1.2")).to exist + expect(cached_gem("myrack-1.0.0")).not_to exist end it "adds new gems and dependencies" do + setup_main_repo install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" G expect(cached_gem("rails-2.3.2")).to exist @@ -233,24 +251,26 @@ RSpec.describe "bundle cache" do end it "removes .gems for removed gems and dependencies" do + setup_main_repo install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" G - expect(cached_gem("rack-1.0.0")).to exist + expect(cached_gem("myrack-1.0.0")).to exist expect(cached_gem("actionpack-2.3.2")).not_to exist expect(cached_gem("activesupport-2.3.2")).not_to exist end it "removes .gems when gem changes to git source" do - build_git "rack" + setup_main_repo + build_git "myrack" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", :git => "#{lib_path("rack-1.0")}" + source "https://gem.repo2" + gem "myrack", :git => "#{lib_path("myrack-1.0")}" gem "actionpack" G - expect(cached_gem("rack-1.0.0")).not_to exist + expect(cached_gem("myrack-1.0.0")).not_to exist expect(cached_gem("actionpack-2.3.2")).to exist expect(cached_gem("activesupport-2.3.2")).to exist end @@ -258,7 +278,7 @@ RSpec.describe "bundle cache" do it "doesn't remove gems that are for another platform" do simulate_platform "java" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G @@ -267,83 +287,108 @@ RSpec.describe "bundle cache" do end simulate_new_machine - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "platform_specific" - G - expect(cached_gem("platform_specific-1.0-#{Bundler.local_platform}")).to exist - expect(cached_gem("platform_specific-1.0-java")).to exist + simulate_platform "x86-darwin-100" do + install_gemfile <<-G + source "https://gem.repo1" + gem "platform_specific" + G + + expect(cached_gem("platform_specific-1.0-x86-darwin-100")).to exist + expect(cached_gem("platform_specific-1.0-java")).to exist + end end - it "doesn't remove gems with mismatched :rubygems_version or :date" do - cached_gem("rack-1.0.0").rmtree - build_gem "rack", "1.0.0", - path: bundled_app("vendor/cache"), + it "doesn't remove gems cached gems that don't match their remote counterparts, but also refuses to install and prints an error" do + setup_main_repo + cached_myrack = cached_gem("myrack-1.0.0") + cached_myrack.rmtree + build_gem "myrack", "1.0.0", + path: cached_myrack.parent, rubygems_version: "1.3.2" - # This test is only really valid if the checksum isn't saved. It otherwise can't be the same gem. Tested below. - bundled_app_lock.write remove_checksums_from_lockfile(bundled_app_lock.read, "rack (1.0.0)") + simulate_new_machine - bundle :install - expect(cached_gem("rack-1.0.0")).to exist + FileUtils.rm bundled_app_lock + bundle :install, raise_on_error: false + + expect(err).to eq <<~E.strip + Bundler found mismatched checksums. This is a potential security risk. + #{checksum_to_lock(gem_repo2, "myrack", "1.0.0")} + from the API at https://gem.repo2/ + #{checksum_from_package(cached_myrack, "myrack", "1.0.0")} + from the gem at #{cached_myrack} + + If you trust the API at https://gem.repo2/, to resolve this issue you can: + 1. remove the gem at #{cached_myrack} + 2. run `bundle install` + + To ignore checksum security warnings, disable checksum validation with + `bundle config set --local disable_checksum_validation true` + E + + expect(cached_gem("myrack-1.0.0")).to exist end - it "raises an error when the gem is altered and produces a different checksum" do - cached_gem("rack-1.0.0").rmtree - build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") + it "raises an error when a cached gem is altered and produces a different checksum than the remote gem" do + setup_main_repo + cached_gem("myrack-1.0.0").rmtree + build_gem "myrack", "1.0.0", path: bundled_app("vendor/cache") checksums = checksums_section do |c| - c.checksum gem_repo1, "rack", "1.0.0" + c.checksum gem_repo1, "myrack", "1.0.0" end simulate_new_machine lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) #{checksums} L bundle :install, raise_on_error: false expect(exitstatus).to eq(37) expect(err).to include("Bundler found mismatched checksums.") - expect(err).to include("1. remove the gem at #{cached_gem("rack-1.0.0")}") + expect(err).to include("1. remove the gem at #{cached_gem("myrack-1.0.0")}") - expect(cached_gem("rack-1.0.0")).to exist - cached_gem("rack-1.0.0").rmtree + expect(cached_gem("myrack-1.0.0")).to exist + cached_gem("myrack-1.0.0").rmtree bundle :install - expect(cached_gem("rack-1.0.0")).to exist + expect(cached_gem("myrack-1.0.0")).to exist end - it "installs a modified gem with a non-matching checksum when checksums is not opted in" do - cached_gem("rack-1.0.0").rmtree - build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") + it "installs a modified gem with a non-matching checksum when the API implementation does not provide checksums" do + setup_main_repo + cached_gem("myrack-1.0.0").rmtree + build_gem "myrack", "1.0.0", path: bundled_app("vendor/cache") simulate_new_machine lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) L - bundle :install - expect(cached_gem("rack-1.0.0")).to exist + bundle :install, artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + expect(cached_gem("myrack-1.0.0")).to exist end it "handles directories and non .gem files in the cache" do + setup_main_repo bundled_app("vendor/cache/foo").mkdir File.open(bundled_app("vendor/cache/bar"), "w") {|f| f.write("not a gem") } bundle :cache end it "does not say that it is removing gems when it isn't actually doing so" do + setup_main_repo install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "cache" bundle "install" @@ -351,9 +396,10 @@ RSpec.describe "bundle cache" do end it "does not warn about all if it doesn't have any git/path dependency" do + setup_main_repo install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "cache" expect(out).not_to match(/\-\-all/) @@ -364,7 +410,7 @@ RSpec.describe "bundle cache" do path: bundled_app("vendor/cache") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo-bundler" G diff --git a/spec/bundler/cache/git_spec.rb b/spec/bundler/cache/git_spec.rb index 4b3cd4d2eb..88436c79aa 100644 --- a/spec/bundler/cache/git_spec.rb +++ b/spec/bundler/cache/git_spec.rb @@ -18,7 +18,7 @@ RSpec.describe "bundle cache with git" do ref = git.ref_for("main", 11) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G @@ -27,6 +27,7 @@ RSpec.describe "bundle cache with git" do expect(bundled_app("vendor/cache/foo-1.0-#{ref}")).to exist expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.git")).not_to exist expect(bundled_app("vendor/cache/foo-1.0-#{ref}/.bundlecache")).to be_file + expect(Dir.glob(bundled_app("vendor/cache/foo-1.0-#{ref}/hooks/*.sample"))).to be_empty FileUtils.rm_rf lib_path("foo-1.0") expect(the_bundle).to include_gems "foo 1.0" @@ -37,7 +38,7 @@ RSpec.describe "bundle cache with git" do ref = git.ref_for("main", 11) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G @@ -57,7 +58,7 @@ RSpec.describe "bundle cache with git" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G @@ -75,7 +76,7 @@ RSpec.describe "bundle cache with git" do old_ref = git.ref_for("main", 11) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G @@ -105,7 +106,7 @@ RSpec.describe "bundle cache with git" do old_ref = git.ref_for("main", 11) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G @@ -134,7 +135,7 @@ RSpec.describe "bundle cache with git" do ref = git.ref_for("main", 11) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-invalid")}', :branch => :main G @@ -154,7 +155,92 @@ RSpec.describe "bundle cache with git" do expect(out).to eq("LOCAL") end - it "copies repository to vendor cache, including submodules" do + it "can use gems after copying install folder to a different machine with git not installed" do + build_git "foo" + + gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => '#{lib_path("foo-1.0")}' + G + bundle "config set path vendor/bundle" + bundle :install + + simulate_new_machine + with_path_as "" do + bundle "config set deployment true" + bundle "install --local" + expect(the_bundle).to include_gem "foo 1.0" + end + end + + it "can install after bundle cache without cloning remote repositories" do + build_git "foo" + + gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => '#{lib_path("foo-1.0")}' + G + bundle "config set cache_all true" + bundle :cache, "all-platforms" => true + FileUtils.rm_rf Dir.glob(default_bundle_path("bundler/gems/extensions/**/foo-1.0-*")).first.to_s + FileUtils.rm_rf Dir.glob(default_bundle_path("bundler/gems/foo-1.0-*")).first.to_s + + simulate_new_machine + bundle "config set frozen true" + bundle "install --local --verbose" + expect(out).to_not include("Fetching") + expect(the_bundle).to include_gem "foo 1.0" + end + + it "can install after bundle cache without cloning remote repositories even without the original cache" do + build_git "foo" + + gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => '#{lib_path("foo-1.0")}' + G + bundle "config set cache_all true" + bundle :cache, "all-platforms" => true + FileUtils.rm_rf Dir.glob(default_bundle_path("bundler/gems/extensions/**/foo-1.0-*")).first.to_s + FileUtils.rm_rf Dir.glob(default_bundle_path("bundler/gems/foo-1.0-*")).first.to_s + + simulate_new_machine + bundle "config set frozen true" + FileUtils.rm_rf "#{default_bundle_path}/cache/bundler/git/foo-1.0-*" + bundle "install --local --verbose" + expect(out).to_not include("Fetching") + expect(the_bundle).to include_gem "foo 1.0" + end + + it "can install after bundle cache without cloning remote repositories with only git tracked files" do + build_git "foo" + + gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => '#{lib_path("foo-1.0")}' + G + bundle "config set cache_all true" + bundle :cache, "all-platforms" => true + FileUtils.rm_rf Dir.glob(default_bundle_path("bundler/gems/extensions/**/foo-1.0-*")).first.to_s + FileUtils.rm_rf Dir.glob(default_bundle_path("bundler/gems/foo-1.0-*")).first.to_s + + simulate_new_machine + bundle "config set frozen true" + FileUtils.rm_rf "#{default_bundle_path}/cache/bundler/git/foo-1.0-*" + + # Remove untracked files (including the empty refs dir in the cache) + Dir.chdir(bundled_app) do + system(*%W[git init --quiet]) + system(*%W[git add --all]) + system(*%W[git clean -d --force --quiet]) + end + + bundle "install --local --verbose" + expect(out).to_not include("Fetching") + expect(the_bundle).to include_gem "foo 1.0" + end + + it "copies repository to vendor cache" do # CVE-2022-39253: https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/ system(*%W[git config --global protocol.file.allow always]) @@ -164,11 +250,11 @@ RSpec.describe "bundle cache with git" do 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") + git "submodule add #{lib_path("submodule-1.0")} submodule-1.0", lib_path("has_submodule-1.0") + git "commit -m \"submodulator\"", lib_path("has_submodule-1.0") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("has_submodule-1.0")}", :submodules => true do gem "has_submodule" end @@ -179,37 +265,17 @@ RSpec.describe "bundle cache with git" do bundle :cache expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}")).to exist - expect(bundled_app("vendor/cache/has_submodule-1.0-#{ref}/submodule-1.0")).to exist expect(the_bundle).to include_gems "has_submodule 1.0" end - it "caches pre-evaluated gemspecs" do - git = build_git "foo" - - # Insert a gemspec method that shells out - spec_lines = lib_path("foo-1.0/foo.gemspec").read.split("\n") - spec_lines.insert(-2, "s.description = `echo bob`") - update_git("foo") {|s| s.write "foo.gemspec", spec_lines.join("\n") } - - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => '#{lib_path("foo-1.0")}' - G - bundle "config set cache_all true" - bundle :cache - - ref = git.ref_for("main", 11) - gemspec = bundled_app("vendor/cache/foo-1.0-#{ref}/foo.gemspec").read - expect(gemspec).to_not match("`echo bob`") - end - it "can install after bundle cache with git not installed" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G + bundle "config set path vendor/bundle" bundle "config set cache_all true" bundle :cache, "all-platforms" => true, :install => false @@ -221,12 +287,54 @@ RSpec.describe "bundle cache with git" do end end + it "can install after bundle cache generated with an older Bundler that kept checkouts in the cache" do + git = build_git("foo") + locked_revision = git.ref_for("main") + path_revision = git.ref_for("main", 11) + + git_path = lib_path("foo-1.0") + + gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => '#{git_path}' + G + lockfile <<~L + GIT + remote: #{git_path}/ + revision: #{locked_revision} + specs: + foo (1.0) + + GEM + remote: https://gem.repo1/ + specs: + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + foo! + + BUNDLED WITH + #{Bundler::VERSION} + L + + # Simulate an old incorrect situation where vendor/cache would be the install location of git gems + FileUtils.mkdir_p bundled_app("vendor/cache") + FileUtils.cp_r git_path, bundled_app("vendor/cache/foo-1.0-#{path_revision}") + FileUtils.rm_rf bundled_app("vendor/cache/foo-1.0-#{path_revision}/.git") + # bundle install with git repo needs to be run under the git environment. + Dir.chdir(bundled_app) { system(*%W[git init --quiet]) } + + bundle :install, env: { "BUNDLE_DEPLOYMENT" => "true", "BUNDLE_CACHE_ALL" => "true" } + end + it "respects the --no-install flag" do git = build_git "foo", &:add_c_extension ref = git.ref_for("main", 11) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G bundle "config set cache_all true" @@ -273,4 +381,33 @@ RSpec.describe "bundle cache with git" do R expect(last_command).to_not be_failure end + + it "doesn't fail when git gem has extensions and an empty cache folder is present before bundle install" do + build_git "puma" do |s| + s.add_dependency "rake" + s.extensions << "Rakefile" + s.executables = "puma" + s.write "Rakefile", <<-RUBY + task :default do + path = File.expand_path("../lib", __FILE__) + FileUtils.mkdir_p(path) + File.open("\#{path}/puma.rb", "w") do |f| + f.puts "PUMA = 'YES'" + end + end + RUBY + end + + FileUtils.mkdir_p(bundled_app("vendor/cache")) + bundle "config set cache_all all" + + install_gemfile <<-G + source "https://gem.repo1" + gem "puma", :git => "#{lib_path("puma-1.0")}" + G + + bundle "exec puma" + + expect(out).to eq("YES") + end end diff --git a/spec/bundler/cache/path_spec.rb b/spec/bundler/cache/path_spec.rb index 2c8a52617a..966cb6f531 100644 --- a/spec/bundler/cache/path_spec.rb +++ b/spec/bundler/cache/path_spec.rb @@ -5,7 +5,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo", path: bundled_app("lib/foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{bundled_app("lib/foo")}' G @@ -19,7 +19,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -38,7 +38,7 @@ RSpec.describe "bundle cache with path" do build_lib libname, path: libpath install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "#{libname}", :path => '#{libpath}' G @@ -54,7 +54,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -77,7 +77,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -89,7 +89,7 @@ RSpec.describe "bundle cache with path" do build_lib "bar" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :path => '#{lib_path("bar-1.0")}' G @@ -101,7 +101,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -114,7 +114,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -127,7 +127,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -136,7 +136,7 @@ RSpec.describe "bundle cache with path" do build_lib "bar" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' gem "bar", :path => '#{lib_path("bar-1.0")}' G @@ -149,7 +149,7 @@ RSpec.describe "bundle cache with path" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' G @@ -158,7 +158,7 @@ RSpec.describe "bundle cache with path" do build_lib "baz" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => '#{lib_path("foo-1.0")}' gem "baz", :path => '#{lib_path("baz-1.0")}' G diff --git a/spec/bundler/cache/platform_spec.rb b/spec/bundler/cache/platform_spec.rb index 36db954c79..71c0eaee8e 100644 --- a/spec/bundler/cache/platform_spec.rb +++ b/spec/bundler/cache/platform_spec.rb @@ -3,10 +3,10 @@ RSpec.describe "bundle cache with multiple platforms" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platforms :mri, :rbx do - gem "rack", "1.0.0" + gem "myrack", "1.0.0" end platforms :jruby do @@ -16,9 +16,9 @@ RSpec.describe "bundle cache with multiple platforms" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) activesupport (2.3.5) PLATFORMS @@ -26,24 +26,24 @@ RSpec.describe "bundle cache with multiple platforms" do java DEPENDENCIES - rack (1.0.0) + myrack (1.0.0) activesupport (2.3.5) G - cache_gems "rack-1.0.0", "activesupport-2.3.5" + cache_gems "myrack-1.0.0", "activesupport-2.3.5" end it "ensures that a successful bundle install does not delete gems for other platforms" do bundle "install" - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist expect(bundled_app("vendor/cache/activesupport-2.3.5.gem")).to exist end it "ensures that a successful bundle update does not delete gems for other platforms" do bundle "update", all: true - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist expect(bundled_app("vendor/cache/activesupport-2.3.5.gem")).to exist end end diff --git a/spec/bundler/commands/add_spec.rb b/spec/bundler/commands/add_spec.rb index 36e286793b..0a0d4c0046 100644 --- a/spec/bundler/commands/add_spec.rb +++ b/spec/bundler/commands/add_spec.rb @@ -15,7 +15,7 @@ RSpec.describe "bundle add" do build_git "foo", "2.0" gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "weakling", "~> 0.0.1" G end @@ -28,6 +28,15 @@ RSpec.describe "bundle add" do end end + context "when Gemfile is empty, and frozen mode is set" do + it "shows error" do + gemfile 'source "https://gem.repo2"' + bundle "add bar", raise_on_error: false, env: { "BUNDLE_FROZEN" => "true" } + + expect(err).to include("Frozen mode is set, but there's no lockfile") + end + end + describe "without version specified" do it "version requirement becomes ~> major.minor.patch when resolved version is < 1.0" do bundle "add 'bar'" @@ -104,9 +113,9 @@ RSpec.describe "bundle add" do describe "with --source" do it "adds dependency with specified source" do - bundle "add 'foo' --source='#{file_uri_for(gem_repo2)}'" + bundle "add 'foo' --source='https://gem.repo2'" - expect(bundled_app_gemfile.read).to match(/gem "foo", "~> 2.0", :source => "#{file_uri_for(gem_repo2)}"/) + expect(bundled_app_gemfile.read).to match(%r{gem "foo", "~> 2.0", :source => "https://gem.repo2"}) expect(the_bundle).to include_gems "foo 2.0" end end @@ -152,7 +161,7 @@ RSpec.describe "bundle add" do end describe "with --github" do - it "adds dependency with specified github source", :realworld do + it "adds dependency with specified github source" do bundle "add rake --github=ruby/rake" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake"}) @@ -160,7 +169,7 @@ RSpec.describe "bundle add" do end describe "with --github and --branch" do - it "adds dependency with specified github source and branch", :realworld do + it "adds dependency with specified github source and branch" do bundle "add rake --github=ruby/rake --branch=master" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :branch => "master"}) @@ -168,7 +177,7 @@ RSpec.describe "bundle add" do end describe "with --github and --ref" do - it "adds dependency with specified github source and ref", :realworld do + it "adds dependency with specified github source and ref" do bundle "add rake --github=ruby/rake --ref=5c60da8" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :ref => "5c60da8"}) @@ -207,7 +216,7 @@ RSpec.describe "bundle add" do end describe "with --github and --glob" do - it "adds dependency with specified github source", :realworld do + it "adds dependency with specified github source" do bundle "add rake --github=ruby/rake --glob='./*.gemspec'" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :glob => "\.\/\*\.gemspec"}) @@ -215,7 +224,7 @@ RSpec.describe "bundle add" do end describe "with --github and --branch --and glob" do - it "adds dependency with specified github source and branch", :realworld do + it "adds dependency with specified github source and branch" do bundle "add rake --github=ruby/rake --branch=master --glob='./*.gemspec'" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :branch => "master", :glob => "\.\/\*\.gemspec"}) @@ -223,7 +232,7 @@ RSpec.describe "bundle add" do end describe "with --github and --ref and --glob" do - it "adds dependency with specified github source and ref", :realworld do + it "adds dependency with specified github source and ref" do bundle "add rake --github=ruby/rake --ref=5c60da8 --glob='./*.gemspec'" expect(bundled_app_gemfile.read).to match(%r{gem "rake", "~> 13\.\d+", :github => "ruby\/rake", :ref => "5c60da8", :glob => "\.\/\*\.gemspec"}) @@ -240,8 +249,8 @@ RSpec.describe "bundle add" do end it "using combination of short form options works like long form" do - bundle "add 'foo' -s='#{file_uri_for(gem_repo2)}' -g='development' -v='~>1.0'" - expect(bundled_app_gemfile.read).to include %(gem "foo", "~> 1.0", :group => :development, :source => "#{file_uri_for(gem_repo2)}") + bundle "add 'foo' -s='https://gem.repo2' -g='development' -v='~>1.0'" + expect(bundled_app_gemfile.read).to include %(gem "foo", "~> 1.0", :group => :development, :source => "https://gem.repo2") expect(the_bundle).to include_gems "foo 1.1" end @@ -255,12 +264,12 @@ RSpec.describe "bundle add" do bundle "add 'werk_it'", raise_on_error: false expect(err).to match("Could not find gem 'werk_it' in") - bundle "add 'werk_it' -s='#{file_uri_for(gem_repo2)}'", raise_on_error: false + bundle "add 'werk_it' -s='https://gem.repo2'", raise_on_error: false expect(err).to match("Could not find gem 'werk_it' in rubygems repository") end it "shows error message when source cannot be reached" do - bundle "add 'baz' --source='http://badhostasdf'", raise_on_error: false + bundle "add 'baz' --source='http://badhostasdf'", raise_on_error: false, artifice: "fail" expect(err).to include("Could not reach host badhostasdf. Check your network connection and try again.") bundle "add 'baz' --source='file://does/not/exist'", raise_on_error: false @@ -295,7 +304,7 @@ RSpec.describe "bundle add" do it "throws error" do bundle "add 'foo' --strict --optimistic", raise_on_error: false - expect(err).to include("You can not specify `--strict` and `--optimistic` at the same time") + expect(err).to include("You cannot specify `--strict` and `--optimistic` at the same time") end end @@ -318,41 +327,41 @@ RSpec.describe "bundle add" do describe "when a gem is added which is already specified in Gemfile with version" do it "shows an error when added with different version requirement" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", "1.0" + source "https://gem.repo2" + gem "myrack", "1.0" G - bundle "add 'rack' --version=1.1", raise_on_error: false + bundle "add 'myrack' --version=1.1", raise_on_error: false expect(err).to include("You cannot specify the same gem twice with different version requirements") - expect(err).to include("If you want to update the gem version, run `bundle update rack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive") + expect(err).to include("If you want to update the gem version, run `bundle update myrack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive") end it "shows error when added without version requirements" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", "1.0" + source "https://gem.repo2" + gem "myrack", "1.0" G - bundle "add 'rack'", raise_on_error: false + bundle "add 'myrack'", raise_on_error: false expect(err).to include("Gem already added.") expect(err).to include("You cannot specify the same gem twice with different version requirements") - expect(err).not_to include("If you want to update the gem version, run `bundle update rack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive") + expect(err).not_to include("If you want to update the gem version, run `bundle update myrack`. You may also need to change the version requirement specified in the Gemfile if it's too restrictive") end end describe "when a gem is added which is already specified in Gemfile without version" do it "shows an error when added with different version requirement" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" G - bundle "add 'rack' --version=1.1", raise_on_error: false + bundle "add 'myrack' --version=1.1", raise_on_error: false expect(err).to include("You cannot specify the same gem twice with different version requirements") - expect(err).to include("If you want to update the gem version, run `bundle update rack`.") + expect(err).to include("If you want to update the gem version, run `bundle update myrack`.") expect(err).not_to include("You may also need to change the version requirement specified in the Gemfile if it's too restrictive") end end @@ -361,8 +370,8 @@ RSpec.describe "bundle add" do it "caches all new dependencies added for the specified gem" do bundle :cache - bundle "add 'rack' --version=1.0.0" - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + bundle "add 'myrack' --version=1.0.0" + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end end end diff --git a/spec/bundler/commands/binstubs_spec.rb b/spec/bundler/commands/binstubs_spec.rb index 6c3dc7bb2d..87a68a9cf1 100644 --- a/spec/bundler/commands/binstubs_spec.rb +++ b/spec/bundler/commands/binstubs_spec.rb @@ -4,44 +4,44 @@ RSpec.describe "bundle binstubs <gem>" do context "when the gem exists in the lockfile" do it "sets up the binstub" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack" + bundle "binstubs myrack" - expect(bundled_app("bin/rackup")).to exist + expect(bundled_app("bin/myrackup")).to exist end it "does not install other binstubs" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "rails" G bundle "binstubs rails" - expect(bundled_app("bin/rackup")).not_to exist + expect(bundled_app("bin/myrackup")).not_to exist expect(bundled_app("bin/rails")).to exist end it "does install multiple binstubs" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "rails" G - bundle "binstubs rails rack" + bundle "binstubs rails myrack" - expect(bundled_app("bin/rackup")).to exist + expect(bundled_app("bin/myrackup")).to exist expect(bundled_app("bin/rails")).to exist end it "allows installing all binstubs" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -53,20 +53,20 @@ RSpec.describe "bundle binstubs <gem>" do it "allows installing binstubs for all platforms" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack --all-platforms" + bundle "binstubs myrack --all-platforms" - expect(bundled_app("bin/rackup")).to exist - expect(bundled_app("bin/rackup.cmd")).to exist + expect(bundled_app("bin/myrackup")).to exist + expect(bundled_app("bin/myrackup.cmd")).to exist end it "displays an error when used without any gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "binstubs", raise_on_error: false @@ -76,11 +76,11 @@ RSpec.describe "bundle binstubs <gem>" do it "displays an error when used with --all and gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack", all: true, raise_on_error: false + bundle "binstubs myrack", all: true, raise_on_error: false expect(last_command).to be_failure expect(err).to include("Cannot specify --all with specific gems") end @@ -88,17 +88,17 @@ RSpec.describe "bundle binstubs <gem>" do context "when generating bundle binstub outside bundler" do it "should abort" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack" + bundle "binstubs myrack" File.open(bundled_app("bin/bundle"), "wb") do |file| file.print "OMG" end - sys_exec "bin/rackup", raise_on_error: false + sys_exec "bin/myrackup", raise_on_error: false expect(err).to include("was not generated by Bundler") end @@ -108,37 +108,42 @@ RSpec.describe "bundle binstubs <gem>" do before do pristine_system_gems "bundler-#{system_bundler_version}" build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "prints_loaded_gems", "1.0" do |s| s.executables = "print_loaded_gems" s.bindir = "exe" - s.write "exe/print_loaded_gems", <<-R + s.write "exe/print_loaded_gems", <<~R + #!/usr/bin/env ruby specs = Gem.loaded_specs.values.reject {|s| s.default_gem? } puts specs.map(&:full_name).sort.inspect R end + + build_bundler locked_bundler_version end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" gem "prints_loaded_gems" G - bundle "binstubs bundler rack prints_loaded_gems" + bundle "binstubs bundler myrack prints_loaded_gems" end let(:system_bundler_version) { Bundler::VERSION } + let(:locked_bundler_version) { nil } + let(:lockfile_content) { lockfile.gsub(system_bundler_version, locked_bundler_version) } it "runs bundler" do - sys_exec "bin/bundle install", env: { "DEBUG" => "1" } + bundle "install --verbose", bundle_bin: "bin/bundle" expect(out).to include %(Using bundler #{system_bundler_version}\n) end context "when BUNDLER_VERSION is set" do it "runs the correct version of bundler" do - sys_exec "bin/bundle install", env: { "BUNDLER_VERSION" => "999.999.999" }, raise_on_error: false + bundle "install", env: { "BUNDLER_VERSION" => "999.999.999" }, raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (999.999.999) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`") @@ -147,19 +152,21 @@ RSpec.describe "bundle binstubs <gem>" do it "runs the correct version of bundler even if a higher version is installed" do system_gems "bundler-999.999.998", "bundler-999.999.999" - sys_exec "bin/bundle install", env: { "BUNDLER_VERSION" => "999.999.998", "DEBUG" => "1" }, raise_on_error: false + bundle "install --verbose", env: { "BUNDLER_VERSION" => "999.999.998" }, raise_on_error: false, bundle_bin: "bin/bundle" expect(out).to include %(Using bundler 999.999.998\n) end end context "when a lockfile exists with a locked bundler version" do + let(:locked_bundler_version) { "999.999" } + context "and the version is newer" do before do - lockfile lockfile.gsub(system_bundler_version, "999.999") + lockfile lockfile_content end it "runs the correct version of bundler" do - sys_exec "bin/bundle install", raise_on_error: false + bundle "install", raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (~> 999.999) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`") @@ -169,11 +176,11 @@ RSpec.describe "bundle binstubs <gem>" do context "and the version is newer when given `gems.rb` and `gems.locked`" do before do gemfile bundled_app("gems.rb"), gemfile - lockfile bundled_app("gems.locked"), lockfile.gsub(system_bundler_version, "999.999") + lockfile bundled_app("gems.locked"), lockfile_content end it "runs the correct version of bundler" do - sys_exec "bin/bundle install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false + bundle "install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (~> 999.999) failed:"). @@ -183,13 +190,14 @@ RSpec.describe "bundle binstubs <gem>" do context "and the version is older and a different major" do let(:system_bundler_version) { "55" } + let(:locked_bundler_version) { "44" } before do - lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 44.0") + lockfile lockfile_content end it "runs the correct version of bundler" do - sys_exec "bin/bundle install", raise_on_error: false + bundle "install", raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (~> 44.0) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`") @@ -198,14 +206,15 @@ RSpec.describe "bundle binstubs <gem>" do context "and the version is older and a different major when given `gems.rb` and `gems.locked`" do let(:system_bundler_version) { "55" } + let(:locked_bundler_version) { "44" } before do gemfile bundled_app("gems.rb"), gemfile - lockfile bundled_app("gems.locked"), lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 44.0") + lockfile bundled_app("gems.locked"), lockfile_content end it "runs the correct version of bundler" do - sys_exec "bin/bundle install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false + bundle "install", env: { "BUNDLE_GEMFILE" => "gems.rb" }, raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (~> 44.0) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 44.0'`") @@ -214,13 +223,14 @@ RSpec.describe "bundle binstubs <gem>" do context "and the version is older and the same major" do let(:system_bundler_version) { "2.999.999" } + let(:locked_bundler_version) { "2.3.0" } before do - lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.3.0") + lockfile lockfile_content end - it "installs and runs the exact version of bundler", rubygems: ">= 3.3.0.dev", realworld: true do - sys_exec "bin/bundle install --verbose", artifice: "vcr" + it "installs and runs the exact version of bundler", rubygems: ">= 3.3.0.dev" do + bundle "install --verbose", bundle_bin: "bin/bundle" expect(exitstatus).not_to eq(42) expect(out).to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.") expect(out).to include("Using bundler 2.3.0") @@ -228,7 +238,7 @@ RSpec.describe "bundle binstubs <gem>" do end it "runs the available version of bundler", rubygems: "< 3.3.0.dev" do - sys_exec "bin/bundle install --verbose" + bundle "install --verbose", bundle_bin: "bin/bundle" expect(exitstatus).not_to eq(42) expect(out).not_to include("Bundler 2.999.999 is running, but your lockfile was generated with 2.3.0. Installing Bundler 2.3.0 and restarting using that version.") expect(out).to include("Using bundler 2.999.999") @@ -238,13 +248,14 @@ RSpec.describe "bundle binstubs <gem>" do context "and the version is a pre-releaser" do let(:system_bundler_version) { "55" } + let(:locked_bundler_version) { "2.12.0.a" } before do - lockfile lockfile.gsub(/BUNDLED WITH\n .*$/m, "BUNDLED WITH\n 2.12.0.a") + lockfile lockfile_content end it "runs the correct version of bundler when the version is a pre-release" do - sys_exec "bin/bundle install", raise_on_error: false + bundle "install", raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (~> 2.12.a) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 2.12.a'`") @@ -253,10 +264,8 @@ RSpec.describe "bundle binstubs <gem>" do end context "when update --bundler is called" do - before { lockfile.gsub(system_bundler_version, "1.1.1") } - - it "calls through to the latest bundler version", :realworld do - sys_exec "bin/bundle update --bundler", env: { "DEBUG" => "1" } + it "calls through to the latest bundler version" do + bundle "update --bundler --verbose", bundle_bin: "bin/bundle" using_bundler_line = /Using bundler ([\w\.]+)\n/.match(out) expect(using_bundler_line).to_not be_nil latest_version = using_bundler_line[1] @@ -264,7 +273,7 @@ RSpec.describe "bundle binstubs <gem>" do end it "calls through to the explicit bundler version" do - sys_exec "bin/bundle update --bundler=999.999.999", raise_on_error: false + bundle "update --bundler=999.999.999", raise_on_error: false, bundle_bin: "bin/bundle" expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (999.999.999) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '999.999.999'`") @@ -274,7 +283,7 @@ RSpec.describe "bundle binstubs <gem>" do context "without a lockfile" do it "falls back to the latest installed bundler" do FileUtils.rm bundled_app_lock - sys_exec "bin/bundle install", env: { "DEBUG" => "1" } + bundle "install --verbose", bundle_bin: "bin/bundle" expect(out).to include "Using bundler #{system_bundler_version}\n" end end @@ -282,14 +291,14 @@ RSpec.describe "bundle binstubs <gem>" do context "using another binstub" do it "loads all gems" do sys_exec bundled_app("bin/print_loaded_gems").to_s - expect(out).to eq %(["bundler-#{Bundler::VERSION}", "prints_loaded_gems-1.0", "rack-1.2"]) + expect(out).to eq %(["bundler-#{Bundler::VERSION}", "myrack-1.2", "prints_loaded_gems-1.0"]) end context "when requesting a different bundler version" do before { lockfile lockfile.gsub(Bundler::VERSION, "999.999.999") } it "attempts to load that version" do - sys_exec bundled_app("bin/rackup").to_s, raise_on_error: false + sys_exec bundled_app("bin/myrackup").to_s, raise_on_error: false expect(exitstatus).to eq(42) expect(err).to include("Activating bundler (~> 999.999) failed:"). and include("To install the version of bundler this project requires, run `gem install bundler -v '~> 999.999'`") @@ -305,7 +314,7 @@ RSpec.describe "bundle binstubs <gem>" do s.executables = %w[foo] end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo")}" G @@ -321,7 +330,7 @@ RSpec.describe "bundle binstubs <gem>" do s.executables = %w[foo] end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G @@ -333,12 +342,12 @@ RSpec.describe "bundle binstubs <gem>" do it "sets correct permissions for binstubs" do with_umask(0o002) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack" - binary = bundled_app("bin/rackup") + bundle "binstubs myrack" + binary = bundled_app("bin/myrackup") expect(File.stat(binary).mode.to_s(8)).to eq(Gem.win_platform? ? "100644" : "100775") end end @@ -346,12 +355,12 @@ RSpec.describe "bundle binstubs <gem>" do context "when using --shebang" do it "sets the specified shebang for the binstub" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack --shebang jruby" - expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env jruby\n") + bundle "binstubs myrack --shebang jruby" + expect(File.readlines(bundled_app("bin/myrackup")).first).to eq("#!/usr/bin/env jruby\n") end end end @@ -359,7 +368,7 @@ RSpec.describe "bundle binstubs <gem>" do context "when the gem doesn't exist" do it "displays an error with correct status" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G bundle "binstubs doesnt_exist", raise_on_error: false @@ -372,23 +381,23 @@ RSpec.describe "bundle binstubs <gem>" do context "--path" do it "sets the binstubs dir" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack --path exec" + bundle "binstubs myrack --path exec" - expect(bundled_app("exec/rackup")).to exist + expect(bundled_app("exec/myrackup")).to exist end it "setting is saved for bundle install", bundler: "< 3" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "rails" G - bundle "binstubs rack", path: "exec" + bundle "binstubs myrack", path: "exec" bundle :install expect(bundled_app("exec/rails")).to exist @@ -398,34 +407,34 @@ RSpec.describe "bundle binstubs <gem>" do context "with --standalone option" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "rails" G end it "generates a standalone binstub" do - bundle "binstubs rack --standalone" - expect(bundled_app("bin/rackup")).to exist + bundle "binstubs myrack --standalone" + expect(bundled_app("bin/myrackup")).to exist end it "generates a binstub that does not depend on rubygems or bundler" do - bundle "binstubs rack --standalone" - expect(File.read(bundled_app("bin/rackup"))).to_not include("Gem.bin_path") + bundle "binstubs myrack --standalone" + expect(File.read(bundled_app("bin/myrackup"))).to_not include("Gem.bin_path") end context "when specified --path option" do it "generates a standalone binstub at the given path" do - bundle "binstubs rack --standalone --path foo" - expect(bundled_app("foo/rackup")).to exist + bundle "binstubs myrack --standalone --path foo" + expect(bundled_app("foo/myrackup")).to exist end end context "when specified --all-platforms option" do it "generates standalone binstubs for all platforms" do - bundle "binstubs rack --standalone --all-platforms" - expect(bundled_app("bin/rackup")).to exist - expect(bundled_app("bin/rackup.cmd")).to exist + bundle "binstubs myrack --standalone --all-platforms" + expect(bundled_app("bin/myrackup")).to exist + expect(bundled_app("bin/myrackup.cmd")).to exist end end @@ -441,7 +450,7 @@ RSpec.describe "bundle binstubs <gem>" do context "when specified --all option" do it "generates standalone binstubs for all gems except bundler" do bundle "binstubs --standalone --all" - expect(bundled_app("bin/rackup")).to exist + expect(bundled_app("bin/myrackup")).to exist expect(bundled_app("bin/rails")).to exist expect(bundled_app("bin/bundle")).not_to exist expect(bundled_app("bin/bundler")).not_to exist @@ -453,39 +462,39 @@ RSpec.describe "bundle binstubs <gem>" do context "when the bin already exists" do it "doesn't overwrite and warns" do FileUtils.mkdir_p(bundled_app("bin")) - File.open(bundled_app("bin/rackup"), "wb") do |file| + File.open(bundled_app("bin/myrackup"), "wb") do |file| file.print "OMG" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack" + bundle "binstubs myrack" - expect(bundled_app("bin/rackup")).to exist - expect(File.read(bundled_app("bin/rackup"))).to eq("OMG") - expect(err).to include("Skipped rackup") + expect(bundled_app("bin/myrackup")).to exist + expect(File.read(bundled_app("bin/myrackup"))).to eq("OMG") + expect(err).to include("Skipped myrackup") expect(err).to include("overwrite skipped stubs, use --force") end context "when using --force" do it "overwrites the binstub" do FileUtils.mkdir_p(bundled_app("bin")) - File.open(bundled_app("bin/rackup"), "wb") do |file| + File.open(bundled_app("bin/myrackup"), "wb") do |file| file.print "OMG" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "binstubs rack --force" + bundle "binstubs myrack --force" - expect(bundled_app("bin/rackup")).to exist - expect(File.read(bundled_app("bin/rackup"))).not_to eq("OMG") + expect(bundled_app("bin/myrackup")).to exist + expect(File.read(bundled_app("bin/myrackup"))).not_to eq("OMG") end end end @@ -493,18 +502,18 @@ RSpec.describe "bundle binstubs <gem>" do context "when the gem has no bins" do it "suggests child gems if they have bins" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack-obama" G - bundle "binstubs rack-obama" - expect(err).to include("rack-obama has no executables") - expect(err).to include("rack has: rackup") + bundle "binstubs myrack-obama" + expect(err).to include("myrack-obama has no executables") + expect(err).to include("myrack has: myrackup") end it "works if child gems don't have bins" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "actionpack" G @@ -520,7 +529,7 @@ RSpec.describe "bundle binstubs <gem>" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "with_development_dependency" G @@ -532,25 +541,25 @@ RSpec.describe "bundle binstubs <gem>" do context "when BUNDLE_INSTALL is specified" do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set auto_install 1" - bundle "binstubs rack" - expect(out).to include("Installing rack 1.0.0") - expect(the_bundle).to include_gems "rack 1.0.0" + bundle "binstubs myrack" + expect(out).to include("Installing myrack 1.0.0") + expect(the_bundle).to include_gems "myrack 1.0.0" end it "does nothing when already up to date" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set auto_install 1" - bundle "binstubs rack", env: { "BUNDLE_INSTALL" => "1" } - expect(out).not_to include("Installing rack 1.0.0") + bundle "binstubs myrack", env: { "BUNDLE_INSTALL" => "1" } + expect(out).not_to include("Installing myrack 1.0.0") end end end diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb index 70e2c84961..ab8eb06838 100644 --- a/spec/bundler/commands/cache_spec.rb +++ b/spec/bundler/commands/cache_spec.rb @@ -3,8 +3,8 @@ RSpec.describe "bundle cache" do it "doesn't update the cache multiple times, even if it already exists" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle :cache @@ -17,14 +17,14 @@ RSpec.describe "bundle cache" do context "with --gemfile" do it "finds the gemfile" do gemfile bundled_app("NotGemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle "cache --gemfile=NotGemfile" ENV["BUNDLE_GEMFILE"] = "NotGemfile" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end @@ -32,15 +32,15 @@ RSpec.describe "bundle cache" do context "without a gemspec" do it "caches all dependencies except bundler itself" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' gem 'bundler' D bundle "config set cache_all true" bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + 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 @@ -63,15 +63,15 @@ RSpec.describe "bundle cache" do it "caches all dependencies except bundler and the gemspec specified gem" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' gemspec D bundle "config set cache_all true" bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + 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 @@ -95,15 +95,15 @@ RSpec.describe "bundle cache" do it "caches all dependencies except bundler and the gemspec specified gem" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' gemspec D bundle "config set cache_all true" bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + 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 @@ -139,8 +139,8 @@ RSpec.describe "bundle cache" do it "caches all dependencies except bundler and the gemspec specified gems" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' gemspec :name => 'mygem' gemspec :name => 'mygem_test' D @@ -148,7 +148,7 @@ RSpec.describe "bundle cache" do bundle "config set cache_all true" bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + 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 @@ -161,13 +161,13 @@ RSpec.describe "bundle cache" do context "with --path", bundler: "< 3" do it "sets root directory for gems" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' D bundle "cache --path #{bundled_app("test")}" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(bundled_app("test/vendor/cache/")).to exist end end @@ -175,60 +175,60 @@ RSpec.describe "bundle cache" do context "with --no-install" do it "puts the gems in vendor/cache but does not install them" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' D bundle "cache --no-install" - expect(the_bundle).not_to include_gems "rack 1.0.0" - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + 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 "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' D bundle "cache --no-install" bundle "install" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "does not prevent installing gems with bundle update" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" D bundle "cache --no-install" bundle "update --all" - expect(the_bundle).to include_gems "rack 1.0.0" + 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", bundler: ">= 2.4.0" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack', :platforms => [:ruby_20, :windows_20] + source "https://gem.repo1" + gem 'myrack', :platforms => [:ruby_20, :windows_20] D bundle "cache --all-platforms" - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + 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", bundler: ">= 2.4.0" do gemfile <<-D - source "#{file_uri_for(gem_repo1)}" - gem 'rack', :platforms => [:ruby_20, :x64_mingw_20] + source "https://gem.repo1" + gem 'myrack', :platforms => [:ruby_20, :x64_mingw_20] D bundle "cache --all-platforms" - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end it "does not attempt to install gems in without groups" do @@ -241,39 +241,39 @@ RSpec.describe "bundle cache" do end bundle "config set --local without wo" - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + install_gemfile <<-G, artifice: "compact_index_extra_api" + source "https://main.repo" + gem "myrack" group :wo do gem "weakling" - gem "uninstallable", :source => "#{file_uri_for(gem_repo4)}" + gem "uninstallable", :source => "https://main.repo/extra" end G - bundle :cache, "all-platforms" => true + 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 "rack 1.0" + 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 - expect(the_bundle).to include_gem "rack 1.0" - expect(the_bundle).not_to include_gems "weakling", "uninstallable" + 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://my.gem.repo.1" - gem "rack" + source "https://gem.repo1" + gem "myrack" group :wo do gem "weakling" end G - bundle :lock, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } - bundle :cache, "all-platforms" => true, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } + bundle :lock + bundle :cache, "all-platforms" => true expect(bundled_app("vendor/cache/weakling-0.0.3.gem")).to exist end end @@ -281,8 +281,8 @@ RSpec.describe "bundle cache" do context "with frozen configured" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "install" end @@ -295,15 +295,15 @@ RSpec.describe "bundle cache" do it "tries to install with frozen" do bundle "config set deployment true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + 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("* rack-obama") + expect(err).to include("* myrack-obama") bundle "env" expect(out).to include("frozen").or include("deployment") end @@ -315,12 +315,12 @@ RSpec.describe "bundle cache" do build_gem "racc", "2.0" do |s| s.add_dependency "rake" s.extensions << "Rakefile" - s.write "Rakefile", "task(:default) { puts 'INSTALLING rack' }" + s.write "Rakefile", "task(:default) { puts 'INSTALLING myrack' }" end end gemfile <<~G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "racc" G @@ -339,8 +339,8 @@ RSpec.describe "bundle install with gem sources" do it "does not hit the remote at all" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" G bundle :cache @@ -348,14 +348,14 @@ RSpec.describe "bundle install with gem sources" do FileUtils.rm_rf gem_repo2 bundle "install --local" - expect(the_bundle).to include_gems "rack 1.0.0" + 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 "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" G bundle :cache @@ -365,14 +365,14 @@ RSpec.describe "bundle install with gem sources" do bundle "config set --local deployment true" bundle "config set --local path vendor/bundle" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0" + 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 "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" G bundle :cache @@ -383,29 +383,89 @@ RSpec.describe "bundle install with gem sources" do bundle "config set --local path vendor/bundle" bundle "install --local" expect(out).not_to include("Fetching gem metadata") - expect(the_bundle).to include_gems "rack 1.0.0" + 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 } + + build_repo4 do + # simulate removal of all remote gems + end + + # delete compact index cache + FileUtils.rm_rf 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 "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle :cache - build_gem "rack", "1.0.0", path: bundled_app("vendor/cache") do |s| - s.write "lib/rack.rb", "raise 'omg'" + 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 "rack 1.0" + 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 "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G bundle :cache @@ -416,17 +476,16 @@ RSpec.describe "bundle install with gem sources" do bundle "config set --local force_ruby_platform true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G - run "require 'platform_specific' ; puts PLATFORM_SPECIFIC" - expect(out).to eq("1.0.0 RUBY") + expect(the_bundle).to include_gems("platform_specific 1.0 ruby") end it "does not update the cache if --no-cache is passed" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundled_app("vendor/cache").mkpath expect(bundled_app("vendor/cache").children).to be_empty diff --git a/spec/bundler/commands/check_spec.rb b/spec/bundler/commands/check_spec.rb index 02f9bb5b7a..18c4b2d89f 100644 --- a/spec/bundler/commands/check_spec.rb +++ b/spec/bundler/commands/check_spec.rb @@ -3,7 +3,7 @@ RSpec.describe "bundle check" do it "returns success when the Gemfile is satisfied" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -13,7 +13,7 @@ RSpec.describe "bundle check" do it "works with the --gemfile flag when not in the directory" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -23,7 +23,7 @@ RSpec.describe "bundle check" do it "creates a Gemfile.lock by default if one does not exist" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -36,7 +36,7 @@ RSpec.describe "bundle check" do it "does not create a Gemfile.lock if --dry-run was passed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -51,7 +51,7 @@ RSpec.describe "bundle check" do system_gems ["rails-2.3.2"] gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -61,7 +61,7 @@ RSpec.describe "bundle check" do it "prints a generic error if a Gemfile.lock does not exist and a toplevel dependency does not exist" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -70,6 +70,17 @@ RSpec.describe "bundle check" do expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.") end + it "prints a generic error if gem git source is not checked out" do + gemfile <<-G + source "https://gem.repo1" + gem "rails", git: "git@github.com:rails/rails.git" + G + + bundle :check, raise_on_error: false + expect(exitstatus).to eq 1 + expect(err).to include("Bundler can't satisfy your Gemfile's dependencies.") + end + it "prints a generic message if you changed your lockfile" do build_repo2 do build_gem "rails_pinned_to_old_activesupport" do |s| @@ -78,12 +89,12 @@ RSpec.describe "bundle check" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'rails' G gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" gem "rails_pinned_to_old_activesupport" G @@ -94,9 +105,9 @@ RSpec.describe "bundle check" do it "remembers --without option from install", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :foo do - gem "rack" + gem "myrack" end G @@ -108,9 +119,9 @@ RSpec.describe "bundle check" do it "uses the without setting" do bundle "config set without foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :foo do - gem "rack" + gem "myrack" end G @@ -120,63 +131,63 @@ RSpec.describe "bundle check" do it "ensures that gems are actually installed and not just cached" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :group => :foo + source "https://gem.repo1" + gem "myrack", :group => :foo G bundle "config set --local without foo" bundle :install gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "check", raise_on_error: false - expect(err).to include("* rack (1.0.0)") + expect(err).to include("* myrack (1.0.0)") expect(exitstatus).to eq(1) end it "ensures that gems are actually installed and not just cached in applications' cache" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set --local path vendor/bundle" bundle :cache - gem_command "uninstall rack", env: { "GEM_HOME" => vendored_gems.to_s } + gem_command "uninstall myrack", env: { "GEM_HOME" => vendored_gems.to_s } bundle "check", raise_on_error: false - expect(err).to include("* rack (1.0.0)") + expect(err).to include("* myrack (1.0.0)") expect(exitstatus).to eq(1) end it "ignores missing gems restricted to other platforms" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" platforms :#{not_local_tag} do gem "activesupport" end G - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: activesupport (2.3.5) - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{generic_local_platform} #{not_local} DEPENDENCIES - rack + myrack activesupport G @@ -186,28 +197,28 @@ RSpec.describe "bundle check" do it "works with env conditionals" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" env :NOT_GOING_TO_BE_SET do gem "activesupport" end G - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: activesupport (2.3.5) - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{generic_local_platform} #{not_local} DEPENDENCIES - rack + myrack activesupport G @@ -229,7 +240,7 @@ RSpec.describe "bundle check" do it "fails when there's no lock file and frozen is set" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G @@ -245,7 +256,7 @@ RSpec.describe "bundle check" do context "after installing gems in the proper directory" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G bundle "install --path vendor/bundle" @@ -267,7 +278,7 @@ RSpec.describe "bundle check" do context "after installing gems on a different directory" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -283,10 +294,10 @@ RSpec.describe "bundle check" do describe "when locked" do before :each do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0" + source "https://gem.repo1" + gem "myrack", "1.0" G end @@ -300,26 +311,26 @@ RSpec.describe "bundle check" do simulate_new_machine bundle :check, raise_on_error: false expect(err).to match(/The following gems are missing/) - expect(err).to include("* rack (1.0") + expect(err).to include("* myrack (1.0") end end describe "when locked with multiple dependents with different requirements" do before :each do build_repo4 do - build_gem "depends_on_rack" do |s| - s.add_dependency "rack", ">= 1.0" + build_gem "depends_on_myrack" do |s| + s.add_dependency "myrack", ">= 1.0" end - build_gem "also_depends_on_rack" do |s| - s.add_dependency "rack", "~> 1.0" + build_gem "also_depends_on_myrack" do |s| + s.add_dependency "myrack", "~> 1.0" end - build_gem "rack" + build_gem "myrack" end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "depends_on_rack" - gem "also_depends_on_rack" + source "https://gem.repo4" + gem "depends_on_myrack" + gem "also_depends_on_myrack" G bundle "lock" @@ -328,33 +339,33 @@ RSpec.describe "bundle check" do it "shows what is missing with the current Gemfile without duplications" do bundle :check, raise_on_error: false expect(err).to match(/The following gems are missing/) - expect(err).to include("* rack (1.0").once + expect(err).to include("* myrack (1.0").once end end describe "when locked under multiple platforms" do before :each do build_repo4 do - build_gem "rack" + build_gem "myrack" end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS ruby #{local_platform} DEPENDENCIES - rack + myrack BUNDLED WITH #{Bundler::VERSION} @@ -364,22 +375,22 @@ RSpec.describe "bundle check" do it "shows what is missing with the current Gemfile without duplications" do bundle :check, raise_on_error: false expect(err).to match(/The following gems are missing/) - expect(err).to include("* rack (1.0").once + expect(err).to include("* myrack (1.0").once end end describe "when using only scoped rubygems sources" do before do gemfile <<~G - source "#{file_uri_for(gem_repo2)}" - source "#{file_uri_for(gem_repo1)}" do - gem "rack" + source "https://gem.repo2" + source "https://gem.repo1" do + gem "myrack" end G end it "returns success when the Gemfile is satisfied" do - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path bundle :check expect(out).to include("The Gemfile's dependencies are satisfied") end @@ -388,48 +399,48 @@ RSpec.describe "bundle check" do describe "when using only scoped rubygems sources with indirect dependencies" do before do build_repo4 do - build_gem "depends_on_rack" do |s| - s.add_dependency "rack" + build_gem "depends_on_myrack" do |s| + s.add_dependency "myrack" end - build_gem "rack" + build_gem "myrack" end gemfile <<~G - source "#{file_uri_for(gem_repo1)}" - source "#{file_uri_for(gem_repo4)}" do - gem "depends_on_rack" + source "https://gem.repo1" + source "https://gem.repo4" do + gem "depends_on_myrack" end G end it "returns success when the Gemfile is satisfied and generates a correct lockfile" do - system_gems "depends_on_rack-1.0", "rack-1.0", gem_repo: gem_repo4, path: default_bundle_path + system_gems "depends_on_myrack-1.0", "myrack-1.0", gem_repo: gem_repo4, path: default_bundle_path bundle :check - checksums = checksums_section_when_existing do |c| - c.no_checksum "depends_on_rack", "1.0" - c.no_checksum "rack", "1.0" + checksums = checksums_section_when_enabled do |c| + c.no_checksum "depends_on_myrack", "1.0" + c.no_checksum "myrack", "1.0" end expect(out).to include("The Gemfile's dependencies are satisfied") expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - depends_on_rack (1.0) - rack - rack (1.0) + depends_on_myrack (1.0) + myrack + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - depends_on_rack! + depends_on_myrack! #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -447,7 +458,7 @@ RSpec.describe "bundle check" do build_gem "dex-dispatch-engine" end - build_lib("bundle-check-issue", path: tmp.join("bundle-check-issue")) do |s| + build_lib("bundle-check-issue", path: tmp("bundle-check-issue")) do |s| s.write "Gemfile", <<-G source "https://localgemserver.test" @@ -461,22 +472,24 @@ RSpec.describe "bundle check" do s.add_dependency "awesome_print" end - bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, dir: tmp.join("bundle-check-issue") + bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, dir: tmp("bundle-check-issue") end it "does not corrupt lockfile when changing version" do - version_file = tmp.join("bundle-check-issue/bundle-check-issue.gemspec") + version_file = tmp("bundle-check-issue/bundle-check-issue.gemspec") File.write(version_file, File.read(version_file).gsub(/s\.version = .+/, "s.version = '9999'")) - bundle "check --verbose", dir: tmp.join("bundle-check-issue") + bundle "check --verbose", dir: tmp("bundle-check-issue") - checksums = checksums_section_when_existing do |c| + lockfile = File.read(tmp("bundle-check-issue/Gemfile.lock")) + + checksums = checksums_section_when_enabled(lockfile) do |c| c.checksum gem_repo4, "awesome_print", "1.0" c.no_checksum "bundle-check-issue", "9999" c.checksum gem_repo2, "dex-dispatch-engine", "1.0" end - expect(File.read(tmp.join("bundle-check-issue/Gemfile.lock"))).to eq <<~L + expect(lockfile).to eq <<~L PATH remote: . specs: @@ -510,15 +523,15 @@ RSpec.describe "bundle check" do def lock_with(bundler_version = nil) lock = <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack L if bundler_version @@ -532,8 +545,8 @@ RSpec.describe "bundle check" do bundle "config set --local path vendor/bundle" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end diff --git a/spec/bundler/commands/clean_spec.rb b/spec/bundler/commands/clean_spec.rb index 0b559a87c8..c27766835e 100644 --- a/spec/bundler/commands/clean_spec.rb +++ b/spec/bundler/commands/clean_spec.rb @@ -19,7 +19,7 @@ RSpec.describe "bundle clean" do it "removes unused gems that are different" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "foo" @@ -30,7 +30,7 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" G @@ -40,17 +40,17 @@ RSpec.describe "bundle clean" do expect(out).to include("Removing foo (1.0)") - should_have_gems "thin-1.0", "rack-1.0.0" + should_have_gems "thin-1.0", "myrack-1.0.0" should_not_have_gems "foo-1.0" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "removes old version of gem if unused" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "0.9.1" + gem "myrack", "0.9.1" gem "foo" G @@ -59,28 +59,28 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" gem "foo" G bundle "install" bundle :clean - expect(out).to include("Removing rack (0.9.1)") + expect(out).to include("Removing myrack (0.9.1)") - should_have_gems "foo-1.0", "rack-1.0.0" - should_not_have_gems "rack-0.9.1" + should_have_gems "foo-1.0", "myrack-1.0.0" + should_not_have_gems "myrack-0.9.1" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "removes new version of gem if unused" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" gem "foo" G @@ -89,31 +89,31 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "0.9.1" + gem "myrack", "0.9.1" gem "foo" G - bundle "update rack" + bundle "update myrack" bundle :clean - expect(out).to include("Removing rack (1.0.0)") + expect(out).to include("Removing myrack (1.0.0)") - should_have_gems "foo-1.0", "rack-0.9.1" - should_not_have_gems "rack-1.0.0" + should_have_gems "foo-1.0", "myrack-0.9.1" + should_not_have_gems "myrack-1.0.0" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "removes gems in bundle without groups" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" group :test_group do - gem "rack", "1.0.0" + gem "myrack", "1.0.0" end G @@ -123,12 +123,12 @@ RSpec.describe "bundle clean" do bundle "install" bundle :clean - expect(out).to include("Removing rack (1.0.0)") + expect(out).to include("Removing myrack (1.0.0)") should_have_gems "foo-1.0" - should_not_have_gems "rack-1.0.0" + should_not_have_gems "myrack-1.0.0" - expect(vendored_gems("bin/rackup")).to_not exist + expect(vendored_gems("bin/myrackup")).to_not exist end it "does not remove cached git dir if it's being used" do @@ -137,9 +137,9 @@ RSpec.describe "bundle clean" do git_path = lib_path("foo-1.0") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" git "#{git_path}", :ref => "#{revision}" do gem "foo" end @@ -161,9 +161,9 @@ RSpec.describe "bundle clean" do revision = revision_for(git_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" git "#{git_path}", :ref => "#{revision}" do gem "foo" end @@ -173,9 +173,9 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G bundle "install" @@ -183,14 +183,14 @@ RSpec.describe "bundle clean" do expect(out).to include("Removing foo (#{revision[0..11]})") - expect(vendored_gems("gems/rack-1.0.0")).to exist + expect(vendored_gems("gems/myrack-1.0.0")).to exist expect(vendored_gems("bundler/gems/foo-#{revision[0..11]}")).not_to exist digest = Digest(:SHA1).hexdigest(git_path.to_s) expect(vendored_gems("cache/bundler/git/foo-#{digest}")).not_to exist - expect(vendored_gems("specifications/rack-1.0.0.gemspec")).to exist + expect(vendored_gems("specifications/myrack-1.0.0.gemspec")).to exist - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "keeps used git gems even if installed to a symlinked location" do @@ -199,9 +199,9 @@ RSpec.describe "bundle clean" do revision = revision_for(git_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" git "#{git_path}", :ref => "#{revision}" do gem "foo" end @@ -225,9 +225,9 @@ RSpec.describe "bundle clean" do revision = revision_for(lib_path("foo-bar")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" git "#{lib_path("foo-bar")}" do gem "foo-bar" end @@ -244,13 +244,13 @@ RSpec.describe "bundle clean" do expect(out).to include("Removing foo-bar (#{revision[0..11]})") - expect(vendored_gems("gems/rack-1.0.0")).to exist + expect(vendored_gems("gems/myrack-1.0.0")).to exist expect(vendored_gems("bundler/gems/foo-bar-#{revision[0..11]}")).not_to exist expect(vendored_gems("bundler/gems/foo-bar-#{revision2[0..11]}")).to exist - expect(vendored_gems("specifications/rack-1.0.0.gemspec")).to exist + expect(vendored_gems("specifications/myrack-1.0.0.gemspec")).to exist - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "does not remove nested gems in a git repo" do @@ -261,7 +261,7 @@ RSpec.describe "bundle clean" do revision = revision_for(lib_path("rails")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", :git => "#{lib_path("rails")}", :ref => '#{revision}' G @@ -279,9 +279,9 @@ RSpec.describe "bundle clean" do revision = revision_for(git_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" group :test do git "#{git_path}", :ref => "#{revision}" do gem "foo" @@ -302,9 +302,9 @@ RSpec.describe "bundle clean" do it "does not blow up when using without groups" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" group :development do gem "foo" @@ -321,9 +321,9 @@ RSpec.describe "bundle clean" do it "displays an error when used without --path" do bundle "config set path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G bundle :clean, raise_on_error: false @@ -335,7 +335,7 @@ RSpec.describe "bundle clean" do # handling bundle clean upgrade path from the pre's it "removes .gem/.gemspec file even if there's no corresponding gem dir" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "foo" @@ -345,63 +345,63 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G bundle "install" - FileUtils.rm(vendored_gems("bin/rackup")) + FileUtils.rm(vendored_gems("bin/myrackup")) FileUtils.rm_rf(vendored_gems("gems/thin-1.0")) - FileUtils.rm_rf(vendored_gems("gems/rack-1.0.0")) + FileUtils.rm_rf(vendored_gems("gems/myrack-1.0.0")) bundle :clean - should_not_have_gems "thin-1.0", "rack-1.0" + should_not_have_gems "thin-1.0", "myrack-1.0" should_have_gems "foo-1.0" - expect(vendored_gems("bin/rackup")).not_to exist + expect(vendored_gems("bin/myrackup")).not_to exist end it "does not call clean automatically when using system gems" do bundle "config set path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" - gem "rack" + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G gem_command :list - expect(out).to include("rack (1.0.0)").and include("thin (1.0)") + expect(out).to include("myrack (1.0.0)").and include("thin (1.0)") end it "--clean should override the bundle setting on install", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" - gem "rack" + gem "myrack" G bundle "config set path vendor/bundle" bundle "config set clean false" bundle "install --clean true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G bundle "install" - should_have_gems "rack-1.0.0" + should_have_gems "myrack-1.0.0" should_not_have_gems "thin-1.0" end @@ -409,7 +409,7 @@ RSpec.describe "bundle clean" do build_repo2 gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "foo" G @@ -431,7 +431,7 @@ RSpec.describe "bundle clean" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "foo" G @@ -453,29 +453,29 @@ RSpec.describe "bundle clean" do it "does not clean automatically on --path" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" - gem "rack" + gem "myrack" G bundle "config set path vendor/bundle" bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G bundle "install" - should_have_gems "rack-1.0.0", "thin-1.0" + should_have_gems "myrack-1.0.0", "thin-1.0" end it "does not clean on bundle update with --path" do build_repo2 gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "foo" G @@ -496,7 +496,7 @@ RSpec.describe "bundle clean" do build_repo2 gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "foo" G @@ -515,17 +515,17 @@ RSpec.describe "bundle clean" do bundle "config set path.system true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" - gem "rack" + gem "myrack" G bundle :install gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G bundle :install bundle "clean --force" @@ -533,7 +533,7 @@ RSpec.describe "bundle clean" do expect(out).to include("Removing foo (1.0)") gem_command :list expect(out).not_to include("foo (1.0)") - expect(out).to include("rack (1.0.0)") + expect(out).to include("myrack (1.0.0)") end describe "when missing permissions", :permissions do @@ -544,17 +544,17 @@ RSpec.describe "bundle clean" do end it "returns a helpful error message" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" - gem "rack" + gem "myrack" G bundle :install gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G bundle :install @@ -567,7 +567,7 @@ RSpec.describe "bundle clean" do gem_command :list expect(out).to include("foo (1.0)") - expect(out).to include("rack (1.0.0)") + expect(out).to include("myrack (1.0.0)") end end @@ -576,7 +576,7 @@ RSpec.describe "bundle clean" do revision = revision_for(lib_path("foo-1.0")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -612,7 +612,7 @@ RSpec.describe "bundle clean" do end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "bindir" G @@ -637,7 +637,7 @@ RSpec.describe "bundle clean" do realworld_system_gems "tsort --version 0.1.0", "pathname --version 0.1.0", "set --version 1.0.1" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" G bundle "clean --force", env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } @@ -654,7 +654,7 @@ RSpec.describe "bundle clean" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" gem "bar", "1.0", :path => "#{relative_path}" @@ -667,7 +667,7 @@ RSpec.describe "bundle clean" do it "doesn't remove gems in dry-run mode with path set" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "foo" @@ -678,7 +678,7 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" G @@ -690,14 +690,14 @@ RSpec.describe "bundle clean" do expect(out).not_to include("Removing foo (1.0)") expect(out).to include("Would have removed foo (1.0)") - should_have_gems "thin-1.0", "rack-1.0.0", "foo-1.0" + should_have_gems "thin-1.0", "myrack-1.0.0", "foo-1.0" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "doesn't remove gems in dry-run mode with no path set" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "foo" @@ -708,7 +708,7 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" G @@ -720,14 +720,14 @@ RSpec.describe "bundle clean" do expect(out).not_to include("Removing foo (1.0)") expect(out).to include("Would have removed foo (1.0)") - should_have_gems "thin-1.0", "rack-1.0.0", "foo-1.0" + should_have_gems "thin-1.0", "myrack-1.0.0", "foo-1.0" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "doesn't store dry run as a config setting" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "foo" @@ -739,7 +739,7 @@ RSpec.describe "bundle clean" do bundle "config set dry_run false" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" G @@ -751,15 +751,15 @@ RSpec.describe "bundle clean" do expect(out).to include("Removing foo (1.0)") expect(out).not_to include("Would have removed foo (1.0)") - should_have_gems "thin-1.0", "rack-1.0.0" + should_have_gems "thin-1.0", "myrack-1.0.0" should_not_have_gems "foo-1.0" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "foo" @@ -770,7 +770,7 @@ RSpec.describe "bundle clean" do bundle "install" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "weakling" @@ -779,7 +779,7 @@ RSpec.describe "bundle clean" do bundle "config set auto_install 1" bundle :clean expect(out).to include("Installing weakling 0.0.3") - should_have_gems "thin-1.0", "rack-1.0.0", "weakling-0.0.3" + should_have_gems "thin-1.0", "myrack-1.0.0", "weakling-0.0.3" should_not_have_gems "foo-1.0" end @@ -789,7 +789,7 @@ RSpec.describe "bundle clean" do revision = revision_for(lib_path("very_simple_git_binary-1.0")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}" G @@ -808,7 +808,7 @@ RSpec.describe "bundle clean" do it "removes extension directories" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "very_simple_binary" @@ -828,7 +828,7 @@ RSpec.describe "bundle clean" do expect(simple_binary_extensions_dir).to exist gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "simple_binary" @@ -849,7 +849,7 @@ RSpec.describe "bundle clean" do short_revision = revision[0..11] gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}" @@ -864,7 +864,7 @@ RSpec.describe "bundle clean" do expect(very_simple_binary_extensions_dir).to exist gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}" G @@ -874,7 +874,7 @@ RSpec.describe "bundle clean" do expect(very_simple_binary_extensions_dir).to exist gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G bundle "install" @@ -891,7 +891,7 @@ RSpec.describe "bundle clean" do short_revision = revision[0..11] gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :development do gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}", :ref => "#{revision}" diff --git a/spec/bundler/commands/config_spec.rb b/spec/bundler/commands/config_spec.rb index 547fd2d869..1392b17315 100644 --- a/spec/bundler/commands/config_spec.rb +++ b/spec/bundler/commands/config_spec.rb @@ -38,8 +38,8 @@ RSpec.describe ".bundle/config" do describe "location with a gemfile" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G end @@ -56,7 +56,7 @@ RSpec.describe ".bundle/config" do expect(bundled_app(".bundle")).not_to exist expect(tmp("foo/bar/config")).to exist - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "can provide a relative path with the environment variable" do @@ -68,7 +68,7 @@ RSpec.describe ".bundle/config" do expect(bundled_app(".bundle")).not_to exist expect(bundled_app("../foo/config")).to exist - expect(the_bundle).to include_gems "rack 1.0.0", dir: bundled_app("omg") + expect(the_bundle).to include_gems "myrack 1.0.0", dir: bundled_app("omg") end end @@ -79,6 +79,14 @@ RSpec.describe ".bundle/config" do expect(home(".bundle/config")).to exist end + it "does not list global settings as local" do + bundle "config set --global foo bar" + bundle "config list", dir: home + + expect(out).to include("for the current user") + expect(out).not_to include("for your local app") + end + it "works with an absolute path" do ENV["BUNDLE_APP_CONFIG"] = tmp("foo/bar").to_s bundle "config set --local path vendor/bundle" @@ -115,8 +123,8 @@ RSpec.describe ".bundle/config" do describe "global" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G end @@ -207,8 +215,8 @@ RSpec.describe ".bundle/config" do describe "local" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G end @@ -263,8 +271,8 @@ RSpec.describe ".bundle/config" do describe "env" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G end @@ -336,8 +344,8 @@ RSpec.describe ".bundle/config" do describe "gem mirrors" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G end @@ -350,10 +358,16 @@ end E expect(out).to eq("http://gems.example.org/ => http://gem-mirror.example.org/") end + + it "allows configuring fallback timeout for each mirror, and does not duplicate configs", rubygems: ">= 3.5.12" do + bundle "config set --global mirror.https://rubygems.org.fallback_timeout 1" + bundle "config set --global mirror.https://rubygems.org.fallback_timeout 2" + expect(File.read(home(".bundle/config"))).to include("BUNDLE_MIRROR").once + end end describe "quoting" do - before(:each) { gemfile "source \"#{file_uri_for(gem_repo1)}\"" } + before(:each) { gemfile "source 'https://gem.repo1'" } let(:long_string) do "--with-xml2-include=/usr/pkg/include/libxml2 --with-xml2-lib=/usr/pkg/lib " \ "--with-xslt-dir=/usr/pkg" @@ -403,8 +417,8 @@ E describe "very long lines" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G end @@ -439,7 +453,7 @@ E it "does not make bundler crash and ignores the configuration" do bundle "config list --parseable" - expect(out).to eq("#mirror.https://rails-assets.org/=http://localhost:9292") + expect(out).to be_empty expect(err).to be_empty ruby(<<~RUBY) @@ -566,8 +580,8 @@ RSpec.describe "setting gemfile via config" do context "when only the non-default Gemfile exists" do it "persists the gemfile location to .bundle/config" do gemfile bundled_app("NotGemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle "config set --local gemfile #{bundled_app("NotGemfile")}" diff --git a/spec/bundler/commands/console_spec.rb b/spec/bundler/commands/console_spec.rb index a41432b88a..8b02e7aa1b 100644 --- a/spec/bundler/commands/console_spec.rb +++ b/spec/bundler/commands/console_spec.rb @@ -38,16 +38,16 @@ RSpec.describe "bundle console", bundler: "< 3", readline: true do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development G end it "starts IRB with the default group loaded" do bundle "console" do |input, _, _| - input.puts("puts RACK") + input.puts("puts MYRACK") input.puts("exit") end expect(out).to include("0.9.1") @@ -63,7 +63,7 @@ RSpec.describe "bundle console", bundler: "< 3", readline: true do it "starts another REPL if configured as such" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "pry" G bundle "config set console pry" @@ -105,7 +105,7 @@ RSpec.describe "bundle console", bundler: "< 3", readline: true do it "loads the default group" do bundle "console test" do |input, _, _| - input.puts("puts RACK") + input.puts("puts MYRACK") input.puts("exit") end expect(out).to include("0.9.1") @@ -113,7 +113,7 @@ RSpec.describe "bundle console", bundler: "< 3", readline: true do it "doesn't load other groups" do bundle "console test" do |input, _, _| - input.puts("puts RACK_MIDDLEWARE") + input.puts("puts MYRACK_MIDDLEWARE") input.puts("exit") end expect(out).to include("NameError") @@ -122,10 +122,10 @@ RSpec.describe "bundle console", bundler: "< 3", readline: true do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development gem "foo" G diff --git a/spec/bundler/commands/doctor_spec.rb b/spec/bundler/commands/doctor_spec.rb index 666b23a141..744510cd40 100644 --- a/spec/bundler/commands/doctor_spec.rb +++ b/spec/bundler/commands/doctor_spec.rb @@ -8,8 +8,8 @@ require "bundler/cli/doctor" RSpec.describe "bundle doctor" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G @stdout = StringIO.new @@ -52,7 +52,7 @@ RSpec.describe "bundle doctor" do it "exits with no message if the installed gem's C extension dylib breakage is fine" do doctor = Bundler::CLI::Doctor.new({}) - expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"] + expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/myrack/myrack.bundle"] expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/lib/libSystem.dylib"] allow(Fiddle).to receive(:dlopen).with("/usr/lib/libSystem.dylib").and_return(true) expect { doctor.run }.not_to raise_error @@ -61,13 +61,13 @@ RSpec.describe "bundle doctor" do it "exits with a message if one of the linked libraries is missing" do doctor = Bundler::CLI::Doctor.new({}) - expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/rack/rack.bundle"] + expect(doctor).to receive(:bundles_for_gem).exactly(2).times.and_return ["/path/to/myrack/myrack.bundle"] expect(doctor).to receive(:dylibs).exactly(2).times.and_return ["/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib"] allow(Fiddle).to receive(:dlopen).with("/usr/local/opt/icu4c/lib/libicui18n.57.1.dylib").and_raise(Fiddle::DLError) expect { doctor.run }.to raise_error(Bundler::ProductionError, <<~E.strip), @stdout.string The following gems are missing OS dependencies: * bundler: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib - * rack: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib + * myrack: /usr/local/opt/icu4c/lib/libicui18n.57.1.dylib E end end diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb index d59b690d2f..ca8ef26344 100644 --- a/spec/bundler/commands/exec_spec.rb +++ b/spec/bundler/commands/exec_spec.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true RSpec.describe "bundle exec" do - let(:system_gems_to_install) { %w[rack-1.0.0 rack-0.9.1] } + let(:system_gems_to_install) { %w[myrack-1.0.0 myrack-0.9.1] } it "works with --gemfile flag" do system_gems(system_gems_to_install, path: default_bundle_path) - create_file "CustomGemfile", <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + gemfile "CustomGemfile", <<-G + source "https://gem.repo1" + gem "myrack", "1.0.0" G - bundle "exec --gemfile CustomGemfile rackup" + bundle "exec --gemfile CustomGemfile myrackup" expect(out).to eq("1.0.0") end @@ -19,11 +19,11 @@ RSpec.describe "bundle exec" do system_gems(system_gems_to_install, path: default_bundle_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G - bundle "exec rackup" + bundle "exec myrackup" expect(out).to eq("0.9.1") end @@ -31,86 +31,69 @@ RSpec.describe "bundle exec" do system_gems(system_gems_to_install, path: default_bundle_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G - bundle "exec rackup", env: { "HOME" => "/" } + bundle "exec myrackup", env: { "HOME" => "/" } expect(out).to eq("0.9.1") expect(err).to be_empty end it "works when the bins are in ~/.bundle" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "exec rackup" + bundle "exec myrackup" expect(out).to eq("1.0.0") end it "works when running from a random directory" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "exec 'cd #{tmp("gems")} && rackup'" + bundle "exec 'cd #{tmp("gems")} && myrackup'" expect(out).to eq("1.0.0") end it "works when exec'ing something else" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" bundle "exec echo exec" expect(out).to eq("exec") end it "works when exec'ing to ruby" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" bundle "exec ruby -e 'puts %{hi}'" expect(out).to eq("hi") end it "works when exec'ing to rubygems" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" bundle "exec #{gem_cmd} --version" expect(out).to eq(Gem::VERSION) end it "works when exec'ing to rubygems through sh -c" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" bundle "exec sh -c '#{gem_cmd} --version'" expect(out).to eq(Gem::VERSION) end - it "works when exec'ing back to bundler with a lockfile that doesn't include the current platform" do + it "works when exec'ing back to bundler to run a remote resolve" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G - # simulate lockfile generated with old version not including specific platform - lockfile <<-L - GEM - remote: #{file_uri_for(gem_repo1)}/ - specs: - rack (0.9.1) + bundle "exec bundle lock", env: { "BUNDLER_VERSION" => Bundler::VERSION } - PLATFORMS - RUBY - - DEPENDENCIES - rack (= 0.9.1) - - BUNDLED WITH - 2.1.4 - L - - bundle "exec bundle cache", env: { "BUNDLER_VERSION" => Bundler::VERSION } - - expect(out).to include("Updating files in vendor/cache") + expect(out).to include("Writing lockfile") end it "respects custom process title when loading through ruby" do @@ -120,20 +103,20 @@ RSpec.describe "bundle exec" do Process.setproctitle("1-2-3-4-5-6-7") puts `ps -ocommand= -p#{$$}` RUBY - create_file "Gemfile", "source \"#{file_uri_for(gem_repo1)}\"" + gemfile "Gemfile", "source \"https://gem.repo1\"" create_file "a.rb", script_that_changes_its_own_title_and_checks_if_picked_up_by_ps_unix_utility bundle "exec ruby a.rb" expect(out).to eq("1-2-3-4-5-6-7") end it "accepts --verbose" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" bundle "exec --verbose echo foobar" expect(out).to eq("foobar") end it "passes --verbose to command if it is given after the command" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" bundle "exec echo --verbose" expect(out).to eq("--verbose") end @@ -157,7 +140,7 @@ RSpec.describe "bundle exec" do end G - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source \"https://gem.repo1\"" sys_exec "#{Gem.ruby} #{command.path}" expect(out).to be_empty @@ -165,7 +148,7 @@ RSpec.describe "bundle exec" do end it "accepts --keep-file-descriptors" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source \"https://gem.repo1\"" bundle "exec --keep-file-descriptors echo foobar" expect(err).to be_empty @@ -174,7 +157,7 @@ RSpec.describe "bundle exec" do it "can run a command named --verbose" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"; gem \"rack\"" + install_gemfile "source \"https://gem.repo1\"; gem \"myrack\"" File.open(bundled_app("--verbose"), "w") do |f| f.puts "#!/bin/sh" f.puts "echo foobar" @@ -188,26 +171,26 @@ RSpec.describe "bundle exec" do it "handles different versions in different bundles" do build_repo2 do - build_gem "rack_two", "1.0.0" do |s| - s.executables = "rackup" + build_gem "myrack_two", "1.0.0" do |s| + s.executables = "myrackup" end end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2 - source "#{file_uri_for(gem_repo2)}" - gem "rack_two", "1.0.0" + source "https://gem.repo2" + gem "myrack_two", "1.0.0" G - bundle "exec rackup" + bundle "exec myrackup" expect(out).to eq("0.9.1") - bundle "exec rackup", dir: bundled_app2 + bundle "exec myrackup", dir: bundled_app2 expect(out).to eq("1.0.0") end @@ -218,7 +201,7 @@ RSpec.describe "bundle exec" do before do skip "irb isn't a default gem" if default_irb_version.empty? - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source \"https://gem.repo1\"" end it "uses version provided by ruby" do @@ -241,7 +224,7 @@ RSpec.describe "bundle exec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "irb", "#{specified_irb_version}" G end @@ -271,7 +254,7 @@ RSpec.describe "bundle exec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "gem_depending_on_old_irb" G @@ -287,54 +270,54 @@ RSpec.describe "bundle exec" do it "warns about executable conflicts" do build_repo2 do - build_gem "rack_two", "1.0.0" do |s| - s.executables = "rackup" + build_gem "myrack_two", "1.0.0" do |s| + s.executables = "myrackup" end end bundle "config set --global path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2 - source "#{file_uri_for(gem_repo2)}" - gem "rack_two", "1.0.0" + source "https://gem.repo2" + gem "myrack_two", "1.0.0" G - bundle "exec rackup" + bundle "exec myrackup" expect(last_command.stderr).to eq( - "Bundler is using a binstub that was created for a different gem (rack).\n" \ - "You should run `bundle binstub rack_two` to work around a system/bundle conflict." + "Bundler is using a binstub that was created for a different gem (myrack).\n" \ + "You should run `bundle binstub myrack_two` to work around a system/bundle conflict." ) end it "handles gems installed with --without" do bundle "config set --local without middleware" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" # rack 0.9.1 and 1.0 exist + source "https://gem.repo1" + gem "myrack" # myrack 0.9.1 and 1.0 exist group :middleware do - gem "rack_middleware" # rack_middleware depends on rack 0.9.1 + gem "myrack_middleware" # myrack_middleware depends on myrack 0.9.1 end G - bundle "exec rackup" + bundle "exec myrackup" expect(out).to eq("0.9.1") - expect(the_bundle).not_to include_gems "rack_middleware 1.0" + expect(the_bundle).not_to include_gems "myrack_middleware 1.0" end it "does not duplicate already exec'ed RUBYOPT" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundler_setup_opt = "-r#{lib_dir}/bundler/setup" @@ -352,8 +335,8 @@ RSpec.describe "bundle exec" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G rubylib = ENV["RUBYLIB"] @@ -369,8 +352,8 @@ RSpec.describe "bundle exec" do it "errors nicely when the argument doesn't exist" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "exec foobarbaz", raise_on_error: false @@ -381,8 +364,8 @@ RSpec.describe "bundle exec" do it "errors nicely when the argument is not executable" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "exec touch foo" @@ -393,8 +376,8 @@ RSpec.describe "bundle exec" do it "errors nicely when no arguments are passed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "exec", raise_on_error: false @@ -405,15 +388,15 @@ RSpec.describe "bundle exec" do it "raises a helpful error when exec'ing to something outside of the bundle" do system_gems(system_gems_to_install, path: default_bundle_path) - bundle "config set clean false" # want to keep the rackup binstub + bundle "config set clean false" # want to keep the myrackup binstub install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G [true, false].each do |l| bundle "config set disable_exec_load #{l}" - bundle "exec rackup", raise_on_error: false - expect(err).to include "can't find executable rackup for gem rack. rack is not currently included in the bundle, perhaps you meant to add it to your Gemfile?" + bundle "exec myrackup", raise_on_error: false + expect(err).to include "can't find executable myrackup for gem myrack. myrack is not currently included in the bundle, perhaps you meant to add it to your Gemfile?" end end @@ -427,8 +410,8 @@ RSpec.describe "bundle exec" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G create_file("print_args", <<-'RUBY') @@ -512,19 +495,19 @@ RSpec.describe "bundle exec" do describe "run from a random directory" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end it "works when unlocked" do - bundle "exec 'cd #{tmp("gems")} && rackup'" + bundle "exec 'cd #{tmp("gems")} && myrackup'" expect(out).to eq("1.0.0") end it "works when locked" do expect(the_bundle).to be_locked - bundle "exec 'cd #{tmp("gems")} && rackup'" + bundle "exec 'cd #{tmp("gems")} && myrackup'" expect(out).to eq("1.0.0") end end @@ -536,7 +519,7 @@ RSpec.describe "bundle exec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "fizz", :path => "#{File.expand_path(home("fizz"))}" G end @@ -561,7 +544,7 @@ RSpec.describe "bundle exec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "fizz_git", :git => "#{lib_path("fizz_git-1.0")}" G end @@ -585,7 +568,7 @@ RSpec.describe "bundle exec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "fizz_no_gemspec", "1.0", :git => "#{lib_path("fizz_no_gemspec-1.0")}" G end @@ -605,13 +588,13 @@ RSpec.describe "bundle exec" do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" gem "foo" G bundle "config set auto_install 1" - bundle "exec rackup" + bundle "exec myrackup" expect(out).to include("Installing foo 1.0") end @@ -620,14 +603,14 @@ RSpec.describe "bundle exec" do s.executables = "foo" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" gem "foo", :git => "#{lib_path("foo-1.0")}" G bundle "config set auto_install 1" bundle "exec foo" - expect(out).to include("Fetching rack 0.9.1") + expect(out).to include("Fetching myrack 0.9.1") expect(out).to include("Fetching #{lib_path("foo-1.0")}") expect(out.lines).to end_with("1.0") end @@ -653,7 +636,7 @@ RSpec.describe "bundle exec" do bundle "config set --local path vendor/bundle" gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "fastlane" G @@ -674,19 +657,20 @@ RSpec.describe "bundle exec" do s.version = '1.0' s.summary = 'TODO: Add summary' s.authors = 'Me' + s.rubygems_version = nil end G end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo-1.0")}" G bundle "exec irb", raise_on_error: false expect(err).to match("The gemspec at #{lib_path("foo-1.0").join("foo.gemspec")} is not valid") - expect(err).to match('"TODO" is not a summary') + expect(err).to match(/missing value for attribute rubygems_version|rubygems_version must not be nil/) end end @@ -695,7 +679,7 @@ RSpec.describe "bundle exec" do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" module Monkey def bin_path(a,b,c) @@ -711,16 +695,35 @@ RSpec.describe "bundle exec" do end end + describe "bundle exec gem uninstall" do + before do + build_repo4 do + build_gem "foo" + end + + install_gemfile <<-G + source "https://gem.repo4" + + gem "foo" + G + end + + it "works" do + bundle "exec #{gem_cmd} uninstall foo" + expect(out).to eq("Successfully uninstalled foo-1.0") + end + end + context "`load`ing a ruby file instead of `exec`ing" do let(:path) { bundled_app("ruby_executable") } let(:shebang) { "#!/usr/bin/env ruby" } let(:executable) { <<~RUBY.strip } #{shebang} - require "rack" + require "myrack" puts "EXEC: \#{caller.grep(/load/).empty? ? 'exec' : 'load'}" puts "ARGS: \#{$0} \#{ARGV.join(' ')}" - puts "RACK: \#{RACK}" + puts "MYRACK: \#{MYRACK}" process_title = `ps -o args -p \#{Process.pid}`.split("\n", 2).last.strip puts "PROCESS: \#{process_title}" RUBY @@ -732,21 +735,21 @@ RSpec.describe "bundle exec" do bundled_app(path).chmod(0o755) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end let(:exec) { "EXEC: load" } let(:args) { "ARGS: #{path} arg1 arg2" } - let(:rack) { "RACK: 1.0.0" } + let(:myrack) { "MYRACK: 1.0.0" } let(:process) do title = "PROCESS: #{path}" title += " arg1 arg2" title end let(:exit_code) { 0 } - let(:expected) { [exec, args, rack, process].join("\n") } + let(:expected) { [exec, args, myrack, process].join("\n") } let(:expected_err) { "" } subject { bundle "exec #{path} arg1 arg2", raise_on_error: false } @@ -876,8 +879,8 @@ RSpec.describe "bundle exec" do context "when Bundler.setup fails", bundler: "< 3" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', '2' + source "https://gem.repo1" + gem 'myrack', '2' G ENV["BUNDLER_FORCE_TTY"] = "true" end @@ -885,11 +888,11 @@ RSpec.describe "bundle exec" do let(:exit_code) { Bundler::GemNotFound.new.status_code } let(:expected) { "" } let(:expected_err) { <<-EOS.strip } -Could not find gem 'rack (= 2)' in cached gems or installed locally. +Could not find gem 'myrack (= 2)' in locally installed gems. -The source contains the following gems matching 'rack': - * rack-0.9.1 - * rack-1.0.0 +The source contains the following gems matching 'myrack': + * myrack-0.9.1 + * myrack-1.0.0 Run `bundle install` to install missing gems. EOS @@ -906,8 +909,8 @@ Run `bundle install` to install missing gems. context "when Bundler.setup fails", bundler: "3" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', '2' + source "https://gem.repo1" + gem 'myrack', '2' G ENV["BUNDLER_FORCE_TTY"] = "true" end @@ -915,10 +918,10 @@ Run `bundle install` to install missing gems. let(:exit_code) { Bundler::GemNotFound.new.status_code } let(:expected) { "" } let(:expected_err) { <<-EOS.strip } -Could not find gem 'rack (= 2)' in cached gems or installed locally. +Could not find gem 'myrack (= 2)' in locally installed gems. -The source contains the following gems matching 'rack': - * rack-1.0.0 +The source contains the following gems matching 'myrack': + * myrack-1.0.0 Run `bundle install` to install missing gems. EOS @@ -934,9 +937,9 @@ Run `bundle install` to install missing gems. context "when Bundler.setup fails and Gemfile is not the default" do before do - create_file "CustomGemfile", <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', '2' + gemfile "CustomGemfile", <<-G + source "https://gem.repo1" + gem 'myrack', '2' G ENV["BUNDLER_FORCE_TTY"] = "true" ENV["BUNDLE_GEMFILE"] = "CustomGemfile" @@ -1098,8 +1101,8 @@ __FILE__: #{path.to_s.inspect} skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set path vendor/bundler" bundle :install @@ -1121,7 +1124,7 @@ __FILE__: #{path.to_s.inspect} before do skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source \"https://gem.repo1\"" end it "does not undo the monkeypatches" do @@ -1171,18 +1174,18 @@ __FILE__: #{path.to_s.inspect} end bundle "config set path vendor/bundle" - bundle "config set gemfile gemfiles/rack_6_1.gemfile" + bundle "config set gemfile gemfiles/myrack_6_1.gemfile" - create_file(bundled_app("gemfiles/rack_6_1.gemfile"), <<~RUBY) - source "#{file_uri_for(gem_repo2)}" + gemfile(bundled_app("gemfiles/myrack_6_1.gemfile"), <<~RUBY) + source "https://gem.repo2" gem "rails", "6.1.0" RUBY # A Gemfile needs to be in the root to trick bundler's root resolution - create_file(bundled_app("Gemfile"), "source \"#{file_uri_for(gem_repo1)}\"") + gemfile "source 'https://gem.repo1'" - bundle "install" + bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } end it "can still find gems after a nested subprocess" do @@ -1211,7 +1214,7 @@ __FILE__: #{path.to_s.inspect} skip "https://github.com/rubygems/rubygems/issues/3351" if Gem.win_platform? skip "openssl isn't a default gem" if expected.empty? - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" # must happen before installing the broken system gem + install_gemfile "source \"https://gem.repo1\"" # must happen before installing the broken system gem build_repo4 do build_gem "openssl", openssl_version do |s| @@ -1252,7 +1255,7 @@ __FILE__: #{path.to_s.inspect} build_git "simple_git_binary", &:add_c_extension bundle "config set --local path .bundle" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "simple_git_binary", :git => '#{lib_path("simple_git_binary-1.0")}' G end diff --git a/spec/bundler/commands/fund_spec.rb b/spec/bundler/commands/fund_spec.rb index 5415b88eeb..6f4e61da30 100644 --- a/spec/bundler/commands/fund_spec.rb +++ b/spec/bundler/commands/fund_spec.rb @@ -30,22 +30,22 @@ RSpec.describe "bundle fund" do it "prints fund information for all gems in the bundle" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding_and_other_metadata' gem 'has_funding' - gem 'rack-obama' + gem 'myrack-obama' G bundle "fund" expect(out).to include("* has_funding_and_other_metadata (1.0)\n Funding: https://example.com/has_funding_and_other_metadata/funding") expect(out).to include("* has_funding (1.2.3)\n Funding: https://example.com/has_funding/funding") - expect(out).to_not include("rack-obama") + expect(out).to_not include("myrack-obama") end it "does not consider fund information for gem dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'gem_with_dependent_funding' G @@ -55,10 +55,46 @@ RSpec.describe "bundle fund" do expect(out).to_not include("gem_with_dependent_funding") end + it "does not consider fund information for uninstalled optional dependencies" do + install_gemfile <<-G + source "https://gem.repo2" + group :whatever, optional: true do + gem 'has_funding_and_other_metadata' + end + gem 'has_funding' + gem 'myrack-obama' + G + + bundle "fund" + + expect(out).to include("* has_funding (1.2.3)\n Funding: https://example.com/has_funding/funding") + expect(out).to_not include("has_funding_and_other_metadata") + expect(out).to_not include("myrack-obama") + end + + it "considers fund information for installed optional dependencies" do + bundle "config set with whatever" + + install_gemfile <<-G + source "https://gem.repo2" + group :whatever, optional: true do + gem 'has_funding_and_other_metadata' + end + gem 'has_funding' + gem 'myrack-obama' + G + + bundle "fund" + + expect(out).to include("* has_funding_and_other_metadata (1.0)\n Funding: https://example.com/has_funding_and_other_metadata/funding") + expect(out).to include("* has_funding (1.2.3)\n Funding: https://example.com/has_funding/funding") + expect(out).to_not include("myrack-obama") + end + it "prints message if none of the gems have fund information" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack-obama' + source "https://gem.repo2" + gem 'myrack-obama' G bundle "fund" @@ -69,7 +105,7 @@ RSpec.describe "bundle fund" do describe "with --group option" do it "prints fund message for only specified group gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding_and_other_metadata', :group => :development gem 'has_funding' G diff --git a/spec/bundler/commands/info_spec.rb b/spec/bundler/commands/info_spec.rb index a5a09bc147..42f288a1d8 100644 --- a/spec/bundler/commands/info_spec.rb +++ b/spec/bundler/commands/info_spec.rb @@ -18,7 +18,7 @@ RSpec.describe "bundle info" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" gem "has_metadata" gem "thin" @@ -127,9 +127,9 @@ RSpec.describe "bundle info" do context "when gem has a reverse dependency on any version" do it "prints the details" do - bundle "info rack" + bundle "info myrack" - expect(out).to include("Reverse Dependencies: \n\t\tthin (1.0) depends on rack (>= 0)") + expect(out).to include("Reverse Dependencies: \n\t\tthin (1.0) depends on myrack (>= 0)") end end @@ -157,7 +157,7 @@ RSpec.describe "bundle info" do it "prints out git info" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G expect(the_bundle).to include_gems "foo 1.0" @@ -173,7 +173,7 @@ RSpec.describe "bundle info" do @revision = revision_for(lib_path("foo-1.0"))[0...6] install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg" G expect(the_bundle).to include_gems "foo 1.0.omg" @@ -185,7 +185,7 @@ RSpec.describe "bundle info" do it "doesn't print the branch when tied to a ref" do sha = revision_for(lib_path("foo-1.0")) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{sha}" G @@ -196,7 +196,7 @@ RSpec.describe "bundle info" do it "handles when a version is a '-' prerelease" do @git = build_git("foo", "1.0.0-beta.1", path: lib_path("foo")) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.0.0-beta.1", :git => "#{lib_path("foo")}" G expect(the_bundle).to include_gems "foo 1.0.0.pre.beta.1" @@ -209,20 +209,20 @@ RSpec.describe "bundle info" do context "with a valid regexp for gem name" do it "presents alternatives", :readline do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G bundle "info rac" - expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>.*)?\z/) + expect(out).to match(/\A1 : myrack\n2 : myrack-obama\n0 : - exit -(\n>|\z)/) end end context "with an invalid regexp for gem name" do it "does not find the gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -238,7 +238,7 @@ RSpec.describe "bundle info" do bundle "config without test" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails", group: :test G diff --git a/spec/bundler/commands/init_spec.rb b/spec/bundler/commands/init_spec.rb index 0a1336572a..538e61fd47 100644 --- a/spec/bundler/commands/init_spec.rb +++ b/spec/bundler/commands/init_spec.rb @@ -32,7 +32,7 @@ RSpec.describe "bundle init" do context "when a Gemfile already exists" do before do - create_file "Gemfile", <<-G + gemfile <<-G gem "rails" G end @@ -79,14 +79,14 @@ RSpec.describe "bundle init" do end context "given --gemspec option" do - let(:spec_file) { tmp.join("test.gemspec") } + let(:spec_file) { tmp("test.gemspec") } it "should generate from an existing gemspec" do File.open(spec_file, "w") do |file| file << <<-S Gem::Specification.new do |s| s.name = 'test' - s.add_dependency 'rack', '= 1.0.1' + s.add_dependency 'myrack', '= 1.0.1' s.add_development_dependency 'rspec', '1.2' end S @@ -96,7 +96,7 @@ RSpec.describe "bundle init" do gemfile = bundled_app_gemfile.read expect(gemfile).to match(%r{source 'https://rubygems.org'}) - expect(gemfile.scan(/gem "rack", "= 1.0.1"/).size).to eq(1) + expect(gemfile.scan(/gem "myrack", "= 1.0.1"/).size).to eq(1) expect(gemfile.scan(/gem "rspec", "= 1.2"/).size).to eq(1) expect(gemfile.scan(/group :development/).size).to eq(1) end @@ -129,7 +129,7 @@ RSpec.describe "bundle init" do context "when gems.rb already exists" do before do - create_file("gems.rb", <<-G) + gemfile("gems.rb", <<-G) gem "rails" G end @@ -160,14 +160,14 @@ RSpec.describe "bundle init" do end context "given --gemspec option" do - let(:spec_file) { tmp.join("test.gemspec") } + let(:spec_file) { tmp("test.gemspec") } before do File.open(spec_file, "w") do |file| file << <<-S Gem::Specification.new do |s| s.name = 'test' - s.add_dependency 'rack', '= 1.0.1' + s.add_dependency 'myrack', '= 1.0.1' s.add_development_dependency 'rspec', '1.2' end S @@ -179,7 +179,7 @@ RSpec.describe "bundle init" do gemfile = bundled_app("gems.rb").read expect(gemfile).to match(%r{source 'https://rubygems.org'}) - expect(gemfile.scan(/gem "rack", "= 1.0.1"/).size).to eq(1) + expect(gemfile.scan(/gem "myrack", "= 1.0.1"/).size).to eq(1) expect(gemfile.scan(/gem "rspec", "= 1.2"/).size).to eq(1) expect(gemfile.scan(/group :development/).size).to eq(1) end diff --git a/spec/bundler/commands/inject_spec.rb b/spec/bundler/commands/inject_spec.rb index 255a03c135..193806a02a 100644 --- a/spec/bundler/commands/inject_spec.rb +++ b/spec/bundler/commands/inject_spec.rb @@ -3,16 +3,16 @@ RSpec.describe "bundle inject", bundler: "< 3" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end context "without a lockfile" do it "locks with the injected gems" do expect(bundled_app_lock).not_to exist - bundle "inject 'rack-obama' '> 0'" - expect(bundled_app_lock.read).to match(/rack-obama/) + bundle "inject 'myrack-obama' '> 0'" + expect(bundled_app_lock.read).to match(/myrack-obama/) end end @@ -22,21 +22,21 @@ RSpec.describe "bundle inject", bundler: "< 3" do end it "adds the injected gems to the Gemfile" do - expect(bundled_app_gemfile.read).not_to match(/rack-obama/) - bundle "inject 'rack-obama' '> 0'" - expect(bundled_app_gemfile.read).to match(/rack-obama/) + expect(bundled_app_gemfile.read).not_to match(/myrack-obama/) + bundle "inject 'myrack-obama' '> 0'" + expect(bundled_app_gemfile.read).to match(/myrack-obama/) end it "locks with the injected gems" do - expect(bundled_app_lock.read).not_to match(/rack-obama/) - bundle "inject 'rack-obama' '> 0'" - expect(bundled_app_lock.read).to match(/rack-obama/) + expect(bundled_app_lock.read).not_to match(/myrack-obama/) + bundle "inject 'myrack-obama' '> 0'" + expect(bundled_app_lock.read).to match(/myrack-obama/) end end context "with injected gems already in the Gemfile" do it "doesn't add existing gems" do - bundle "inject 'rack' '> 0'", raise_on_error: false + bundle "inject 'myrack' '> 0'", raise_on_error: false expect(err).to match(/cannot specify the same gem twice/i) end end @@ -53,25 +53,25 @@ Usage: "bundle inject GEM VERSION" context "with source option" do it "add gem with source option in gemfile" do - bundle "inject 'foo' '>0' --source #{file_uri_for(gem_repo1)}" + bundle "inject 'foo' '>0' --source https://gem.repo1" gemfile = bundled_app_gemfile.read - str = "gem \"foo\", \"> 0\", :source => \"#{file_uri_for(gem_repo1)}\"" + str = "gem \"foo\", \"> 0\", :source => \"https://gem.repo1\"" expect(gemfile).to include str end end context "with group option" do it "add gem with group option in gemfile" do - bundle "inject 'rack-obama' '>0' --group=development" + bundle "inject 'myrack-obama' '>0' --group=development" gemfile = bundled_app_gemfile.read - str = "gem \"rack-obama\", \"> 0\", :group => :development" + str = "gem \"myrack-obama\", \"> 0\", :group => :development" expect(gemfile).to include str end it "add gem with multiple groups in gemfile" do - bundle "inject 'rack-obama' '>0' --group=development,test" + bundle "inject 'myrack-obama' '>0' --group=development,test" gemfile = bundled_app_gemfile.read - str = "gem \"rack-obama\", \"> 0\", :groups => [:development, :test]" + str = "gem \"myrack-obama\", \"> 0\", :groups => [:development, :test]" expect(gemfile).to include str end end @@ -87,31 +87,31 @@ Usage: "bundle inject GEM VERSION" end it "injects anyway" do - bundle "inject 'rack-obama' '> 0'" - expect(bundled_app_gemfile.read).to match(/rack-obama/) + bundle "inject 'myrack-obama' '> 0'" + expect(bundled_app_gemfile.read).to match(/myrack-obama/) end it "locks with the injected gems" do - expect(bundled_app_lock.read).not_to match(/rack-obama/) - bundle "inject 'rack-obama' '> 0'" - expect(bundled_app_lock.read).to match(/rack-obama/) + expect(bundled_app_lock.read).not_to match(/myrack-obama/) + bundle "inject 'myrack-obama' '> 0'" + expect(bundled_app_lock.read).to match(/myrack-obama/) end it "restores frozen afterwards" do - bundle "inject 'rack-obama' '> 0'" + bundle "inject 'myrack-obama' '> 0'" config = Psych.load(bundled_app(".bundle/config").read) expect(config["BUNDLE_DEPLOYMENT"] || config["BUNDLE_FROZEN"]).to eq("true") end it "doesn't allow Gemfile changes" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack-obama" G - bundle "inject 'rack' '> 0'", raise_on_error: false + bundle "inject 'myrack' '> 0'", raise_on_error: false expect(err).to match(/the lockfile can't be updated because frozen mode is set/) - expect(bundled_app_lock.read).not_to match(/rack-obama/) + expect(bundled_app_lock.read).not_to match(/myrack-obama/) end end end diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb index 1e57414377..19711045c2 100644 --- a/spec/bundler/commands/install_spec.rb +++ b/spec/bundler/commands/install_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "bundle install with gem sources" do describe "the simple case" do it "prints output and returns if no dependencies are specified" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G bundle :install @@ -22,8 +22,8 @@ RSpec.describe "bundle install with gem sources" do it "creates a Gemfile.lock" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G expect(bundled_app_lock).to exist @@ -31,8 +31,8 @@ RSpec.describe "bundle install with gem sources" do it "does not create ./.bundle by default", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle :install # can't use install_gemfile since it sets retry @@ -41,8 +41,8 @@ RSpec.describe "bundle install with gem sources" do it "does not create ./.bundle by default when installing to system gems" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle :install, env: { "BUNDLE_PATH__SYSTEM" => "true" } # can't use install_gemfile since it sets retry @@ -51,8 +51,8 @@ RSpec.describe "bundle install with gem sources" do it "creates lock files based on the Gemfile name" do gemfile bundled_app("OmgFile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0" + source "https://gem.repo1" + gem "myrack", "1.0" G bundle "install --gemfile OmgFile" @@ -62,8 +62,8 @@ RSpec.describe "bundle install with gem sources" do it "doesn't delete the lockfile if one already exists" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G lockfile = File.read(bundled_app_lock) @@ -77,8 +77,8 @@ RSpec.describe "bundle install with gem sources" do it "does not touch the lockfile if nothing changed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G expect { run "1" }.not_to change { File.mtime(bundled_app_lock) } @@ -86,60 +86,60 @@ RSpec.describe "bundle install with gem sources" do it "fetches gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G - expect(default_bundle_path("gems/rack-1.0.0")).to exist - expect(the_bundle).to include_gems("rack 1.0.0") + expect(default_bundle_path("gems/myrack-1.0.0")).to exist + expect(the_bundle).to include_gems("myrack 1.0.0") end it "auto-heals missing gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G - FileUtils.rm_rf(default_bundle_path("gems/rack-1.0.0")) + FileUtils.rm_rf(default_bundle_path("gems/myrack-1.0.0")) bundle "install --verbose" - expect(out).to include("Installing rack 1.0.0") - expect(default_bundle_path("gems/rack-1.0.0")).to exist - expect(the_bundle).to include_gems("rack 1.0.0") + expect(out).to include("Installing myrack 1.0.0") + expect(default_bundle_path("gems/myrack-1.0.0")).to exist + expect(the_bundle).to include_gems("myrack 1.0.0") end it "fetches gems when multiple versions are specified" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', "> 0.9", "< 1.0" + source "https://gem.repo1" + gem 'myrack', "> 0.9", "< 1.0" G - expect(default_bundle_path("gems/rack-0.9.1")).to exist - expect(the_bundle).to include_gems("rack 0.9.1") + expect(default_bundle_path("gems/myrack-0.9.1")).to exist + expect(the_bundle).to include_gems("myrack 0.9.1") end it "fetches gems when multiple versions are specified take 2" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', "< 1.0", "> 0.9" + source "https://gem.repo1" + gem 'myrack', "< 1.0", "> 0.9" G - expect(default_bundle_path("gems/rack-0.9.1")).to exist - expect(the_bundle).to include_gems("rack 0.9.1") + expect(default_bundle_path("gems/myrack-0.9.1")).to exist + expect(the_bundle).to include_gems("myrack 0.9.1") end it "raises an appropriate error when gems are specified using symbols" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem :rack + source "https://gem.repo1" + gem :myrack G expect(exitstatus).to eq(4) end it "pulls in dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -148,11 +148,11 @@ RSpec.describe "bundle install with gem sources" do it "does the right version" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G - expect(the_bundle).to include_gems "rack 0.9.1" + expect(the_bundle).to include_gems "myrack 0.9.1" end it "does not install the development dependency" do @@ -163,7 +163,7 @@ RSpec.describe "bundle install with gem sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "with_development_dependency" G @@ -173,7 +173,7 @@ RSpec.describe "bundle install with gem sources" do it "resolves correctly" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activemerchant" gem "rails" G @@ -183,12 +183,12 @@ RSpec.describe "bundle install with gem sources" do it "activates gem correctly according to the resolved gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", "2.3.5" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activemerchant" gem "rails" G @@ -206,7 +206,7 @@ RSpec.describe "bundle install with gem sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activerecord", "2.3.2" G @@ -216,25 +216,23 @@ RSpec.describe "bundle install with gem sources" do it "works when the gemfile specifies gems that only exist in the system" do build_gem "foo", to_bundle: true install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "foo" G - expect(the_bundle).to include_gems "rack 1.0.0", "foo 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0", "foo 1.0.0" end it "prioritizes local gems over remote gems" do - build_gem "rack", "1.0.0", to_bundle: true do |s| - s.add_dependency "activesupport", "2.3.5" - end + build_gem "myrack", "9.0.0", to_bundle: true install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5" + expect(the_bundle).to include_gems "myrack 9.0.0" end it "loads env plugins" do @@ -242,8 +240,8 @@ RSpec.describe "bundle install with gem sources" do create_file "plugins/rubygems_plugin.rb", "puts '#{plugin_msg}'" rubylib = ENV["RUBYLIB"].to_s.split(File::PATH_SEPARATOR).unshift(bundled_app("plugins").to_s).join(File::PATH_SEPARATOR) install_gemfile <<-G, env: { "RUBYLIB" => rubylib } - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G expect(last_command.stdboth).to include(plugin_msg) @@ -251,102 +249,100 @@ RSpec.describe "bundle install with gem sources" do describe "with a gem that installs multiple platforms" do it "installs gems for the local platform as first choice" do - skip "version is 1.0, not 1.0.0" if Gem.win_platform? - - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "platform_specific" - G + simulate_platform "x86-darwin-100" do + install_gemfile <<-G + source "https://gem.repo1" + gem "platform_specific" + G - run "require 'platform_specific' ; puts PLATFORM_SPECIFIC" - expect(out).to eq("1.0.0 #{Bundler.local_platform}") + expect(the_bundle).to include_gems("platform_specific 1.0 x86-darwin-100") + end end it "falls back on plain ruby" do - simulate_platform "foo-bar-baz" - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "platform_specific" - G + simulate_platform "foo-bar-baz" do + install_gemfile <<-G + source "https://gem.repo1" + gem "platform_specific" + G - run "require 'platform_specific' ; puts PLATFORM_SPECIFIC" - expect(out).to eq("1.0.0 RUBY") + expect(the_bundle).to include_gems("platform_specific 1.0 ruby") + end end it "installs gems for java" do - simulate_platform "java" - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "platform_specific" - G + simulate_platform "java" do + install_gemfile <<-G + source "https://gem.repo1" + gem "platform_specific" + G - run "require 'platform_specific' ; puts PLATFORM_SPECIFIC" - expect(out).to eq("1.0.0 JAVA") + expect(the_bundle).to include_gems("platform_specific 1.0 java") + end end it "installs gems for windows" do - simulate_platform x86_mswin32 + simulate_platform x86_mswin32 do + install_gemfile <<-G + source "https://gem.repo1" + gem "platform_specific" + G - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "platform_specific" - G - - run "require 'platform_specific' ; puts PLATFORM_SPECIFIC" - expect(out).to eq("1.0 x86-mswin32") + expect(the_bundle).to include_gems("platform_specific 1.0 x86-mswin32") + end end end describe "doing bundle install foo" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end it "works" do bundle "config set --local path vendor" bundle "install" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end it "allows running bundle install --system without deleting foo", bundler: "< 3" do bundle "install --path vendor" bundle "install --system" FileUtils.rm_rf(bundled_app("vendor")) - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end it "allows running bundle install --system after deleting foo", bundler: "< 3" do bundle "install --path vendor" FileUtils.rm_rf(bundled_app("vendor")) bundle "install --system" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end it "finds gems in multiple sources", bundler: "< 3" do build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end end - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, artifice: "compact_index_extra" + source "https://gemserver.test" + source "https://gemserver.test/extra" gem "activesupport", "1.2.3" - gem "rack", "1.2" + gem "myrack", "1.2" G - expect(the_bundle).to include_gems "rack 1.2", "activesupport 1.2.3" + expect(the_bundle).to include_gems "myrack 1.2", "activesupport 1.2.3" end it "gives a useful error if no sources are set" do install_gemfile <<-G, raise_on_error: false - gem "rack" + gem "myrack" G expect(err).to include("This Gemfile does not include an explicit global source. " \ @@ -357,7 +353,7 @@ RSpec.describe "bundle install with gem sources" do it "creates a Gemfile.lock on a blank Gemfile" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G expect(File.exist?(bundled_app_lock)).to eq(true) @@ -367,12 +363,12 @@ RSpec.describe "bundle install with gem sources" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" - gem "rack" + source "https://gem.repo2" + gem "myrack" + gem "myrack" G - expect(err).to include("Your Gemfile lists the gem rack (>= 0) more than once.") + expect(err).to include("Your Gemfile lists the gem myrack (>= 0) more than once.") expect(err).to include("Remove any duplicate entries and specify the gem only once.") expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.") end @@ -381,12 +377,12 @@ RSpec.describe "bundle install with gem sources" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", "1.0" - gem "rack", "1.0" + source "https://gem.repo2" + gem "myrack", "1.0" + gem "myrack", "1.0" G - expect(err).to include("Your Gemfile lists the gem rack (= 1.0) more than once.") + expect(err).to include("Your Gemfile lists the gem myrack (= 1.0) more than once.") expect(err).to include("Remove any duplicate entries and specify the gem only once.") expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.") end @@ -395,14 +391,14 @@ RSpec.describe "bundle install with gem sources" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", :platform => :jruby - gem "rack" + source "https://gem.repo2" + gem "myrack", :platform => :jruby + gem "myrack" G bundle "install" - expect(err).to include("Your Gemfile lists the gem rack (>= 0) more than once.") + expect(err).to include("Your Gemfile lists the gem myrack (>= 0) more than once.") expect(err).to include("Remove any duplicate entries and specify the gem only once.") expect(err).to include("While it's not a problem now, it could cause errors if you change the version of one of them later.") end @@ -417,7 +413,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<~G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gemspec @@ -441,7 +437,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec @@ -461,8 +457,8 @@ RSpec.describe "bundle install with gem sources" do end it "includes the gem without warning if two gemspecs add it with the same requirement" do - gem1 = tmp.join("my-gem-1") - gem2 = tmp.join("my-gem-2") + gem1 = tmp("my-gem-1") + gem2 = tmp("my-gem-2") build_lib "my-gem", path: gem1 do |s| s.add_development_dependency "rubocop", "~> 1.36.0" @@ -477,7 +473,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec path: "#{gem1}" gemspec path: "#{gem2}" @@ -499,7 +495,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rails", "~> 7.0.8" @@ -530,11 +526,11 @@ RSpec.describe "bundle install with gem sources" do build_git "activesupport", "1.0", path: lib_path("activesupport") install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec - gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}" + gem "activesupport", :git => "#{lib_path("activesupport")}" G expect(err).to be_empty @@ -542,9 +538,9 @@ RSpec.describe "bundle install with gem sources" do # if the Gemfile dependency is specified first install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" - gem "activesupport", :git => "#{file_uri_for(lib_path("activesupport"))}" + gem "activesupport", :git => "#{lib_path("activesupport")}" gemspec G @@ -564,7 +560,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec @@ -579,31 +575,31 @@ RSpec.describe "bundle install with gem sources" do it "throws an error if a gem is added twice in Gemfile when version of one dependency is not specified" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" - gem "rack" - gem "rack", "1.0" + source "https://gem.repo2" + gem "myrack" + gem "myrack", "1.0" G expect(err).to include("You cannot specify the same gem twice with different version requirements") - expect(err).to include("You specified: rack (>= 0) and rack (= 1.0).") + expect(err).to include("You specified: myrack (>= 0) and myrack (= 1.0).") end it "throws an error if a gem is added twice in Gemfile when different versions of both dependencies are specified" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" - gem "rack", "1.0" - gem "rack", "1.1" + source "https://gem.repo2" + gem "myrack", "1.0" + gem "myrack", "1.1" G expect(err).to include("You cannot specify the same gem twice with different version requirements") - expect(err).to include("You specified: rack (= 1.0) and rack (= 1.1).") + expect(err).to include("You specified: myrack (= 1.0) and myrack (= 1.1).") end it "gracefully handles error when rubygems server is unavailable" do skip "networking issue" if Gem.win_platform? install_gemfile <<-G, artifice: nil, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" source "http://0.0.0.0:9384" do gem 'foo' end @@ -627,7 +623,7 @@ RSpec.describe "bundle install with gem sources" do end install_gemfile <<-G, full_index: true, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "ajp-rails", "0.0.0" G @@ -642,7 +638,7 @@ RSpec.describe "bundle install with gem sources" do FileUtils.touch(bundled_app(".bundle/config")) install_gemfile(<<-G) - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo' G @@ -653,7 +649,7 @@ RSpec.describe "bundle install with gem sources" do FileUtils.touch("#{Bundler.rubygems.user_home}/.bundle/config") install_gemfile(<<-G) - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo' G @@ -665,7 +661,7 @@ RSpec.describe "bundle install with gem sources" do it "prints an error" do install_gemfile <<-G, raise_on_error: false ruby '~> 1.2' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G expect(err).to include("Your Ruby version is #{Gem.ruby_version}, but your Gemfile specified ~> 1.2") end @@ -675,15 +671,15 @@ RSpec.describe "bundle install with gem sources" do before do install_gemfile <<-G ruby '~> #{Gem.ruby_version}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end it "writes current Ruby version to Gemfile.lock" do - checksums = checksums_section_when_existing + checksums = checksums_section_when_enabled expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -702,14 +698,14 @@ RSpec.describe "bundle install with gem sources" do it "updates Gemfile.lock with updated yet still compatible ruby version" do install_gemfile <<-G ruby '~> #{current_ruby_minor}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G - checksums = checksums_section_when_existing + checksums = checksums_section_when_enabled expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -727,7 +723,7 @@ RSpec.describe "bundle install with gem sources" do it "does not crash when unlocking" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby '>= 2.1.0' G @@ -746,7 +742,7 @@ RSpec.describe "bundle install with gem sources" do build_lib "foo" gemfile = <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "#{lib_path("foo-1.0")}" G File.open("#{root_dir}/Gemfile", "w") do |file| @@ -763,7 +759,7 @@ RSpec.describe "bundle install with gem sources" do build_lib "foo", path: root_dir gemfile = <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G File.open("#{root_dir}/Gemfile", "w") do |file| @@ -779,8 +775,8 @@ RSpec.describe "bundle install with gem sources" do bundle "config set force_ruby_platform true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle :install, quiet: true @@ -809,7 +805,7 @@ RSpec.describe "bundle install with gem sources" do RUBY gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'non-existing-gem' G @@ -820,14 +816,14 @@ RSpec.describe "bundle install with gem sources" do end end - describe "when bundle path does not have write access", :permissions do + describe "when bundle path does not have cd permission", :permissions do let(:bundle_path) { bundled_app("vendor") } before do FileUtils.mkdir_p(bundle_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G end @@ -841,14 +837,14 @@ RSpec.describe "bundle install with gem sources" do end end - describe "when bundle gems path does not have write access", :permissions do + describe "when bundle gems path does not have cd permission", :permissions do let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") } before do FileUtils.mkdir_p(gems_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G end @@ -865,19 +861,79 @@ RSpec.describe "bundle install with gem sources" do expect(err).not_to include("ERROR REPORT TEMPLATE") expect(err).to include( - "There was an error while trying to create `#{gems_path.join("rack-1.0.0")}`. " \ + "There was an error while trying to create `#{gems_path.join("myrack-1.0.0")}`. " \ "It is likely that you need to grant executable permissions for all parent directories and write permissions for `#{gems_path}`." ) end end + describe "when bundle bin dir does not have cd permission", :permissions do + let(:bin_dir) { bundled_app("vendor/#{Bundler.ruby_scope}/bin") } + + before do + FileUtils.mkdir_p(bin_dir) + gemfile <<-G + source "https://gem.repo1" + gem 'myrack' + G + end + + it "should display a proper message to explain the problem" do + FileUtils.chmod("-x", bin_dir) + bundle "config set --local path vendor" + + begin + bundle :install, raise_on_error: false + ensure + FileUtils.chmod("+x", bin_dir) + end + + expect(err).not_to include("ERROR REPORT TEMPLATE") + + expect(err).to include( + "There was an error while trying to write to `#{bin_dir}`. " \ + "It is likely that you need to grant write permissions for that path." + ) + end + end + + describe "when bundle bin dir does not have write access", :permissions do + let(:bin_dir) { bundled_app("vendor/#{Bundler.ruby_scope}/bin") } + + before do + FileUtils.mkdir_p(bin_dir) + gemfile <<-G + source "https://gem.repo1" + gem "myrack" + G + end + + it "should display a proper message to explain the problem" do + FileUtils.chmod("-w", bin_dir) + bundle "config set --local path vendor" + + begin + bundle :install, raise_on_error: false + ensure + FileUtils.chmod("+w", bin_dir) + end + + expect(err).not_to include("ERROR REPORT TEMPLATE") + + expect(err).to include( + "There was an error while trying to write to `#{bin_dir}`. " \ + "It is likely that you need to grant write permissions for that path." + ) + end + end + describe "when bundle extensions path does not have write access", :permissions do let(:extensions_path) { bundled_app("vendor/#{Bundler.ruby_scope}/extensions/#{Gem::Platform.local}/#{Gem.extension_api_version}") } before do FileUtils.mkdir_p(extensions_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'simple_binary' G end @@ -901,7 +957,7 @@ RSpec.describe "bundle install with gem sources" do end end - describe "when the path of a specific gem is not writable", :permissions do + describe "when the path of a specific gem does not have cd permission", :permissions do let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") } let(:foo_path) { gems_path.join("foo-1.0.0") } @@ -913,7 +969,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo' G end @@ -949,7 +1005,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo' G end @@ -984,7 +1040,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo' G end @@ -999,7 +1055,35 @@ RSpec.describe "bundle install with gem sources" do bundle "install --redownload", raise_on_error: false - expect(err).to include("The installation path is insecure. Bundler cannot continue.") + expect(err).to include("Bundler cannot reinstall foo-1.0.0 because there's a previous installation of it at #{gems_path}/foo-1.0.0 that is unsafe to remove") + end + end + + describe "when gems path is world writable (no sticky bit set), but previous install is just an empty dir (like it happens with default gems)", :permissions do + let(:gems_path) { bundled_app("vendor/#{Bundler.ruby_scope}/gems") } + let(:full_path) { gems_path.join("foo-1.0.0") } + + before do + build_repo4 do + build_gem "foo", "1.0.0" do |s| + s.write "CHANGELOG.md", "foo" + end + end + + gemfile <<-G + source "https://gem.repo4" + gem 'foo' + G + end + + it "does not try to remove the directory and thus don't abort with an error about unsafe directory removal" do + bundle "config set --local path vendor" + + FileUtils.mkdir_p(gems_path) + FileUtils.chmod(0o777, gems_path) + Dir.mkdir(full_path) + + bundle "install" end end @@ -1009,8 +1093,8 @@ RSpec.describe "bundle install with gem sources" do before do FileUtils.mkdir_p(cache_path) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G end @@ -1025,12 +1109,12 @@ RSpec.describe "bundle install with gem sources" do end describe "when gemspecs are unreadable", :permissions do - let(:gemspec_path) { vendored_gems("specifications/rack-1.0.0.gemspec") } + let(:gemspec_path) { vendored_gems("specifications/myrack-1.0.0.gemspec") } before do gemfile <<~G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle "config path vendor/bundle" bundle :install @@ -1050,16 +1134,16 @@ RSpec.describe "bundle install with gem sources" do context "after installing with --standalone" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set --local path bundle" bundle "install", standalone: true end it "includes the standalone path" do - bundle "binstubs rack", standalone: true - standalone_line = File.read(bundled_app("bin/rackup")).each_line.find {|line| line.include? "$:.unshift" }.strip + bundle "binstubs myrack", standalone: true + standalone_line = File.read(bundled_app("bin/myrackup")).each_line.find {|line| line.include? "$:.unshift" }.strip expect(standalone_line).to eq %($:.unshift File.expand_path "../bundle", __dir__) end end @@ -1080,23 +1164,27 @@ RSpec.describe "bundle install with gem sources" do end end - context "in a frozen bundle" do - before do + context "when current platform not included in the lockfile" do + around do |example| build_repo4 do build_gem "libv8", "8.4.255.0" do |s| s.platform = "x86_64-darwin-19" end + + build_gem "libv8", "8.4.255.0" do |s| + s.platform = "x86_64-linux" + end end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "libv8" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: libv8 (8.4.255.0-x86_64-darwin-19) @@ -1110,11 +1198,36 @@ RSpec.describe "bundle install with gem sources" do #{Bundler::VERSION} L - bundle "config set --local deployment true" + simulate_platform("x86_64-linux", &example) end - it "should fail loudly if the lockfile platforms don't include the current platform" do - simulate_platform(Gem::Platform.new("x86_64-linux")) { bundle "install", raise_on_error: false } + it "adds the current platform to the lockfile" do + bundle "install --verbose" + + expect(out).to include("re-resolving dependencies because your lockfile does not include the current platform") + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + libv8 (8.4.255.0-x86_64-darwin-19) + libv8 (8.4.255.0-x86_64-linux) + + PLATFORMS + x86_64-darwin-19 + x86_64-linux + + DEPENDENCIES + libv8 + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "fails loudly if frozen mode set" do + bundle "config set --local deployment true" + bundle "install", raise_on_error: false expect(err).to eq( "Your bundle only supports platforms [\"x86_64-darwin-19\"] but your local platform is x86_64-linux. " \ @@ -1130,19 +1243,19 @@ RSpec.describe "bundle install with gem sources" do build_gem "nokogiri", "1.12.4" do |s| s.platform = "x86_64-darwin" - s.add_runtime_dependency "racca", "~> 1.4" + s.add_dependency "racca", "~> 1.4" end build_gem "nokogiri", "1.12.4" do |s| s.platform = "x86_64-linux" - s.add_runtime_dependency "racca", "~> 1.4" + s.add_dependency "racca", "~> 1.4" end build_gem "crass", "1.0.6" build_gem "loofah", "2.12.0" do |s| - s.add_runtime_dependency "crass", "~> 1.0.2" - s.add_runtime_dependency "nokogiri", ">= 1.5.9" + s.add_dependency "crass", "~> 1.0.2" + s.add_dependency "nokogiri", ">= 1.5.9" end end @@ -1195,7 +1308,7 @@ RSpec.describe "bundle install with gem sources" do bundle "install", artifice: "compact_index" end - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "crass", "1.0.6" c.checksum gem_repo4, "loofah", "2.12.0" c.checksum gem_repo4, "nokogiri", "1.12.4", "x86_64-darwin" @@ -1235,15 +1348,15 @@ RSpec.describe "bundle install with gem sources" do context "with --local flag" do before do - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path end it "respects installed gems without fetching any remote sources" do install_gemfile <<-G, local: true - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" source "https://not-existing-source" do - gem "rack" + gem "myrack" end G @@ -1258,14 +1371,14 @@ RSpec.describe "bundle install with gem sources" do it "installs only gems of the specified groups" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" - gem "rack", group: :a + gem "myrack", group: :a gem "rake", group: :b gem "yard", group: :c G - expect(out).to include("Installing rack") + expect(out).to include("Installing myrack") expect(out).to include("Installing rake") expect(out).not_to include("Installing yard") end @@ -1277,14 +1390,22 @@ RSpec.describe "bundle install with gem sources" do build_gem "foo", "1.0.1" build_gem "foo", "1.0.0" build_gem "bar", "1.0.0" + + build_gem "a", "1.0.0" do |s| + s.add_dependency "foo", "~> 1.0.0" + end + + build_gem "b", "1.0.0" do |s| + s.add_dependency "foo", "~> 1.0.1" + end end system_gems "foo-1.0.0", path: default_bundle_path, gem_repo: gem_repo4 end - it "fetches remote sources only when not available locally" do + it "fetches remote sources when not available locally" do install_gemfile <<-G, "prefer-local": true, verbose: true - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "foo" gem "bar" @@ -1293,6 +1414,40 @@ RSpec.describe "bundle install with gem sources" do expect(out).to include("Using foo 1.0.0").and include("Fetching bar 1.0.0").and include("Installing bar 1.0.0") expect(last_command).to be_success end + + it "fetches remote sources when local version does not match requirements" do + install_gemfile <<-G, "prefer-local": true, verbose: true + source "https://gem.repo4" + + gem "foo", "1.0.1" + gem "bar" + G + + expect(out).to include("Fetching foo 1.0.1").and include("Installing foo 1.0.1").and include("Fetching bar 1.0.0").and include("Installing bar 1.0.0") + expect(last_command).to be_success + end + + it "uses the locally available version for sub-dependencies when possible" do + install_gemfile <<-G, "prefer-local": true, verbose: true + source "https://gem.repo4" + + gem "a" + G + + expect(out).to include("Using foo 1.0.0").and include("Fetching a 1.0.0").and include("Installing a 1.0.0") + expect(last_command).to be_success + end + + it "fetches remote sources for sub-dependencies when the locally available version does not satisfy the requirement" do + install_gemfile <<-G, "prefer-local": true, verbose: true + source "https://gem.repo4" + + gem "b" + G + + expect(out).to include("Fetching foo 1.0.1").and include("Installing foo 1.0.1").and include("Fetching b 1.0.0").and include("Installing b 1.0.0") + expect(last_command).to be_success + end end context "with a symlinked configured as bundle path and a gem with symlinks" do @@ -1321,7 +1476,7 @@ RSpec.describe "bundle install with gem sources" do it "installs fine" do install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "binman" G @@ -1343,7 +1498,7 @@ RSpec.describe "bundle install with gem sources" do it "does not crash unexpectedly" do gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "autobuild", "1.10.rc2" G @@ -1366,7 +1521,7 @@ RSpec.describe "bundle install with gem sources" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "aaa" gem "zzz" @@ -1374,7 +1529,7 @@ RSpec.describe "bundle install with gem sources" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: aaa (0.2.0) zzz (< 0.2.0) @@ -1400,11 +1555,53 @@ RSpec.describe "bundle install with gem sources" do context "when --jobs option given" do before do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", jobs: 1 + install_gemfile "source 'https://gem.repo1'", jobs: 1 end it "does not save the flag to config" do expect(bundled_app(".bundle/config")).not_to exist end end + + context "when bundler installation is corrupt" do + before do + system_gems "bundler-9.99.8" + + replace_version_file("9.99.9", dir: system_gem_path("gems/bundler-9.99.8")) + end + + it "shows a proper error" do + lockfile <<~L + GEM + remote: https://gem.repo1/ + specs: + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + + BUNDLED WITH + 9.99.8 + L + + install_gemfile "source \"https://gem.repo1\"", env: { "BUNDLER_VERSION" => "9.99.8" }, raise_on_error: false + + expect(err).not_to include("ERROR REPORT TEMPLATE") + expect(err).to include("The running version of Bundler (9.99.9) does not match the version of the specification installed for it (9.99.8)") + end + end + + it "only installs executable files in bin" do + bundle "config set --local path vendor/bundle" + + install_gemfile <<~G + source "https://gem.repo1" + gem "myrack" + G + + expected_executables = [vendored_gems("bin/myrackup").to_s] + expected_executables << vendored_gems("bin/myrackup.bat").to_s if Gem.win_platform? + expect(Dir.glob(vendored_gems("bin/*"))).to eq(expected_executables) + end end diff --git a/spec/bundler/commands/issue_spec.rb b/spec/bundler/commands/issue_spec.rb index 143f6333ce..346cdedc42 100644 --- a/spec/bundler/commands/issue_spec.rb +++ b/spec/bundler/commands/issue_spec.rb @@ -3,7 +3,7 @@ RSpec.describe "bundle issue" do it "exits with a message" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G diff --git a/spec/bundler/commands/licenses_spec.rb b/spec/bundler/commands/licenses_spec.rb index a203984890..bfec938efd 100644 --- a/spec/bundler/commands/licenses_spec.rb +++ b/spec/bundler/commands/licenses_spec.rb @@ -9,7 +9,7 @@ RSpec.describe "bundle licenses" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" gem "with_license" G @@ -24,7 +24,7 @@ RSpec.describe "bundle licenses" do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" gem "with_license" gem "foo" diff --git a/spec/bundler/commands/list_spec.rb b/spec/bundler/commands/list_spec.rb index 5ac2077d81..cc0db9169d 100644 --- a/spec/bundler/commands/list_spec.rb +++ b/spec/bundler/commands/list_spec.rb @@ -20,9 +20,9 @@ RSpec.describe "bundle list" do describe "with without-group option" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" gem "rspec", :group => [:test] gem "rails", :group => [:production] G @@ -32,7 +32,7 @@ RSpec.describe "bundle list" do it "prints the gems not in the specified group" do bundle "list --without-group test" - expect(out).to include(" * rack (1.0.0)") + expect(out).to include(" * myrack (1.0.0)") expect(out).to include(" * rails (2.3.2)") expect(out).not_to include(" * rspec (1.2.7)") end @@ -50,7 +50,7 @@ RSpec.describe "bundle list" do it "prints the gems not in the specified groups" do bundle "list --without-group test production" - expect(out).to include(" * rack (1.0.0)") + expect(out).to include(" * myrack (1.0.0)") expect(out).not_to include(" * rails (2.3.2)") expect(out).not_to include(" * rspec (1.2.7)") end @@ -60,9 +60,9 @@ RSpec.describe "bundle list" do describe "with only-group option" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" gem "rspec", :group => [:test] gem "rails", :group => [:production] G @@ -72,7 +72,7 @@ RSpec.describe "bundle list" do it "prints the gems in the specified group" do bundle "list --only-group default" - expect(out).to include(" * rack (1.0.0)") + expect(out).to include(" * myrack (1.0.0)") expect(out).not_to include(" * rspec (1.2.7)") end end @@ -89,7 +89,7 @@ RSpec.describe "bundle list" do it "prints the gems in the specified groups" do bundle "list --only-group default production" - expect(out).to include(" * rack (1.0.0)") + expect(out).to include(" * myrack (1.0.0)") expect(out).to include(" * rails (2.3.2)") expect(out).not_to include(" * rspec (1.2.7)") end @@ -99,9 +99,9 @@ RSpec.describe "bundle list" do context "with name-only option" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" gem "rspec", :group => [:test] G end @@ -109,7 +109,7 @@ RSpec.describe "bundle list" do it "prints only the name of the gems in the bundle" do bundle "list --name-only" - expect(out).to include("rack") + expect(out).to include("myrack") expect(out).to include("rspec") end end @@ -117,8 +117,8 @@ RSpec.describe "bundle list" do context "with paths option" do before do build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "bar" @@ -126,23 +126,23 @@ RSpec.describe "bundle list" do build_git "git_test", "1.0.0", path: lib_path("git_test") - build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s| + build_lib("gemspec_test", path: tmp("gemspec_test")) do |s| s.add_dependency "bar", "=1.0.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" gem "rails" gem "git_test", :git => "#{lib_path("git_test")}" - gemspec :path => "#{tmp.join("gemspec_test")}" + gemspec :path => "#{tmp("gemspec_test")}" G end it "prints the path of each gem in the bundle" do bundle "list --paths" expect(out).to match(%r{.*\/rails\-2\.3\.2}) - expect(out).to match(%r{.*\/rack\-1\.2}) + expect(out).to match(%r{.*\/myrack\-1\.2}) expect(out).to match(%r{.*\/git_test\-\w}) expect(out).to match(%r{.*\/gemspec_test}) end @@ -151,7 +151,7 @@ RSpec.describe "bundle list" do context "when no gems are in the gemfile" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end @@ -164,25 +164,25 @@ RSpec.describe "bundle list" do context "without options" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" gem "rspec", :group => [:test] G end it "lists gems installed in the bundle" do bundle "list" - expect(out).to include(" * rack (1.0.0)") + expect(out).to include(" * myrack (1.0.0)") end end context "when using the ls alias" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" gem "rspec", :group => [:test] G end diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb index c6bb0f58af..5e2a6e7e8f 100644 --- a/spec/bundler/commands/lock_spec.rb +++ b/spec/bundler/commands/lock_spec.rb @@ -1,31 +1,22 @@ # frozen_string_literal: true RSpec.describe "bundle lock" do - let(:repo) { gem_repo1 } - - before :each do - gemfile <<-G - source "#{file_uri_for(repo)}" - gem "rails" - gem "weakling" - gem "foo" - G - - checksums = checksums_section_when_existing do |c| - c.checksum repo, "actionmailer", "2.3.2" - c.checksum repo, "actionpack", "2.3.2" - c.checksum repo, "activerecord", "2.3.2" - c.checksum repo, "activeresource", "2.3.2" - c.checksum repo, "activesupport", "2.3.2" - c.checksum repo, "foo", "1.0" - c.checksum repo, "rails", "2.3.2" - c.checksum repo, "rake", rake_version - c.checksum repo, "weakling", "0.0.3" + let(:expected_lockfile) do + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "actionmailer", "2.3.2" + c.checksum gem_repo4, "actionpack", "2.3.2" + c.checksum gem_repo4, "activerecord", "2.3.2" + c.checksum gem_repo4, "activeresource", "2.3.2" + c.checksum gem_repo4, "activesupport", "2.3.2" + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "rails", "2.3.2" + c.checksum gem_repo4, "rake", rake_version + c.checksum gem_repo4, "weakling", "0.0.3" end - @lockfile = <<~L + <<~L GEM - remote: #{file_uri_for(repo)}/ + remote: https://gem.repo4/ specs: actionmailer (2.3.2) activesupport (= 2.3.2) @@ -59,44 +50,136 @@ RSpec.describe "bundle lock" do L end + let(:outdated_lockfile) do + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "actionmailer", "2.3.1" + c.checksum gem_repo4, "actionpack", "2.3.1" + c.checksum gem_repo4, "activerecord", "2.3.1" + c.checksum gem_repo4, "activeresource", "2.3.1" + c.checksum gem_repo4, "activesupport", "2.3.1" + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "rails", "2.3.1" + c.checksum gem_repo4, "rake", rake_version + c.checksum gem_repo4, "weakling", "0.0.3" + end + + <<~L + GEM + remote: https://gem.repo4/ + specs: + actionmailer (2.3.1) + activesupport (= 2.3.1) + actionpack (2.3.1) + activesupport (= 2.3.1) + activerecord (2.3.1) + activesupport (= 2.3.1) + activeresource (2.3.1) + activesupport (= 2.3.1) + activesupport (2.3.1) + foo (1.0) + rails (2.3.1) + actionmailer (= 2.3.1) + actionpack (= 2.3.1) + activerecord (= 2.3.1) + activeresource (= 2.3.1) + rake (= #{rake_version}) + rake (#{rake_version}) + weakling (0.0.3) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + foo + rails + weakling + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + + before :each do + build_repo4 do + FileUtils.cp rake_path, "#{gem_repo4}/gems/" + + build_gem "rake", "10.0.1" + + %w[2.3.1 2.3.2].each do |version| + build_gem "rails", version do |s| + s.executables = "rails" + s.add_dependency "rake", version == "2.3.1" ? "10.0.1" : rake_version + s.add_dependency "actionpack", version + s.add_dependency "activerecord", version + s.add_dependency "actionmailer", version + s.add_dependency "activeresource", version + end + build_gem "actionpack", version do |s| + s.add_dependency "activesupport", version + end + build_gem "activerecord", version do |s| + s.add_dependency "activesupport", version + end + build_gem "actionmailer", version do |s| + s.add_dependency "activesupport", version + end + build_gem "activeresource", version do |s| + s.add_dependency "activesupport", version + end + build_gem "activesupport", version + end + + build_gem "weakling", "0.0.3" + + build_gem "foo" + end + + gemfile <<-G + source "https://gem.repo4" + gem "rails" + gem "weakling" + gem "foo" + G + end + it "prints a lockfile when there is no existing lockfile with --print" do bundle "lock --print" - expect(out).to eq(@lockfile.chomp) + expect(out).to eq(expected_lockfile.chomp) end it "prints a lockfile when there is an existing lockfile with --print" do - lockfile remove_checksums_section_from_lockfile(@lockfile) + lockfile expected_lockfile bundle "lock --print" - expect(out).to eq(remove_checksums_section_from_lockfile(@lockfile).chomp) + expect(out).to eq(expected_lockfile.chomp) end it "prints a lockfile when there is an existing checksums lockfile with --print" do - lockfile @lockfile + lockfile expected_lockfile bundle "lock --print" - expect(out).to eq(@lockfile.chomp) + expect(out).to eq(expected_lockfile.chomp) end it "writes a lockfile when there is no existing lockfile" do bundle "lock" - expect(read_lockfile).to eq(@lockfile) + expect(read_lockfile).to eq(expected_lockfile) end it "prints a lockfile without fetching new checksums if the existing lockfile had no checksums" do - lockfile remove_checksums_from_lockfile(@lockfile) + lockfile expected_lockfile bundle "lock --print" - expect(out).to eq(remove_checksums_from_lockfile(@lockfile).chomp) + expect(out).to eq(expected_lockfile.chomp) end it "touches the lockfile when there is an existing lockfile that does not need changes" do - lockfile @lockfile + lockfile expected_lockfile expect do bundle "lock" @@ -104,7 +187,7 @@ RSpec.describe "bundle lock" do end it "does not touch lockfile with --print" do - lockfile @lockfile + lockfile expected_lockfile expect do bundle "lock --print" @@ -112,56 +195,68 @@ RSpec.describe "bundle lock" do end it "writes a lockfile when there is an outdated lockfile using --update" do - lockfile remove_checksums_from_lockfile(@lockfile.gsub("2.3.2", "2.3.1"), " (2.3.1)") + lockfile outdated_lockfile bundle "lock --update" - expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile)) + expect(read_lockfile).to eq(expected_lockfile) end - it "writes a lockfile with checksums on --update when checksums exist" do - lockfile @lockfile.gsub("2.3.2", "2.3.1") + it "prints an updated lockfile when there is an outdated lockfile using --print --update" do + lockfile outdated_lockfile - bundle "lock --update" + bundle "lock --print --update" - expect(read_lockfile).to eq(@lockfile) + expect(out).to eq(expected_lockfile.rstrip) + end + + it "emits info messages to stderr when updating an outdated lockfile using --print --update" do + lockfile outdated_lockfile + + bundle "lock --print --update" + + expect(err).to eq(<<~STDERR.rstrip) + Fetching gem metadata from https://gem.repo4/... + Resolving dependencies... + STDERR end it "writes a lockfile when there is an outdated lockfile and bundle is frozen" do - lockfile @lockfile.gsub("2.3.2", "2.3.1") + lockfile outdated_lockfile bundle "lock --update", env: { "BUNDLE_FROZEN" => "true" } - expect(read_lockfile).to eq(@lockfile) + expect(read_lockfile).to eq(expected_lockfile) end it "does not fetch remote specs when using the --local option" do bundle "lock --update --local", raise_on_error: false - expect(err).to match(/cached gems or installed locally/) + expect(err).to match(/locally installed gems/) end it "does not fetch remote checksums with --local" do - lockfile remove_checksums_from_lockfile(@lockfile) + lockfile expected_lockfile bundle "lock --print --local" - # No checksums because --local prevents fetching them - expect(out).to eq(remove_checksums_from_lockfile(@lockfile).chomp) + expect(out).to eq(expected_lockfile.chomp) end it "works with --gemfile flag" do - create_file "CustomGemfile", <<-G - source "#{file_uri_for(repo)}" + gemfile "CustomGemfile", <<-G + source "https://gem.repo4" gem "foo" G - checksums = checksums_section_when_existing do |c| - c.no_checksum "foo", "1.0" + bundle "lock --gemfile CustomGemfile" + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "foo", "1.0" end lockfile = <<~L GEM - remote: #{file_uri_for(repo)}/ + remote: https://gem.repo4/ specs: foo (1.0) @@ -174,8 +269,6 @@ RSpec.describe "bundle lock" do BUNDLED WITH #{Bundler::VERSION} L - bundle "lock --gemfile CustomGemfile" - expect(out).to match(/Writing lockfile to.+CustomGemfile\.lock/) expect(read_lockfile("CustomGemfile.lock")).to eq(lockfile) expect { read_lockfile }.to raise_error(Errno::ENOENT) @@ -185,7 +278,7 @@ RSpec.describe "bundle lock" do bundle "lock --lockfile=lock" expect(out).to match(/Writing lockfile to.+lock/) - expect(read_lockfile("lock")).to eq(remove_checksums_from_lockfile(@lockfile)) + expect(read_lockfile("lock")).to eq(expected_lockfile) expect { read_lockfile }.to raise_error(Errno::ENOENT) end @@ -193,21 +286,21 @@ RSpec.describe "bundle lock" do bundle "install" bundle "lock --lockfile=lock" - checksums = checksums_section_when_existing do |c| - c.checksum repo, "actionmailer", "2.3.2" - c.checksum repo, "actionpack", "2.3.2" - c.checksum repo, "activerecord", "2.3.2" - c.checksum repo, "activeresource", "2.3.2" - c.checksum repo, "activesupport", "2.3.2" - c.checksum repo, "foo", "1.0" - c.checksum repo, "rails", "2.3.2" - c.checksum repo, "rake", rake_version - c.checksum repo, "weakling", "0.0.3" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "actionmailer", "2.3.2" + c.checksum gem_repo4, "actionpack", "2.3.2" + c.checksum gem_repo4, "activerecord", "2.3.2" + c.checksum gem_repo4, "activeresource", "2.3.2" + c.checksum gem_repo4, "activesupport", "2.3.2" + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "rails", "2.3.2" + c.checksum gem_repo4, "rake", rake_version + c.checksum gem_repo4, "weakling", "0.0.3" end lockfile = <<~L GEM - remote: #{file_uri_for(repo)}/ + remote: https://gem.repo4/ specs: actionmailer (2.3.2) activesupport (= 2.3.2) @@ -245,11 +338,58 @@ RSpec.describe "bundle lock" do end it "update specific gems using --update" do - lockfile @lockfile.gsub("2.3.2", "2.3.1").gsub(rake_version, "10.0.1") + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "actionmailer", "2.3.1" + c.checksum gem_repo4, "actionpack", "2.3.1" + c.checksum gem_repo4, "activerecord", "2.3.1" + c.checksum gem_repo4, "activeresource", "2.3.1" + c.checksum gem_repo4, "activesupport", "2.3.1" + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "rails", "2.3.1" + c.checksum gem_repo4, "rake", "10.0.1" + c.checksum gem_repo4, "weakling", "0.0.3" + end + + lockfile_with_outdated_rails_and_rake = <<~L + GEM + remote: https://gem.repo4/ + specs: + actionmailer (2.3.1) + activesupport (= 2.3.1) + actionpack (2.3.1) + activesupport (= 2.3.1) + activerecord (2.3.1) + activesupport (= 2.3.1) + activeresource (2.3.1) + activesupport (= 2.3.1) + activesupport (2.3.1) + foo (1.0) + rails (2.3.1) + actionmailer (= 2.3.1) + actionpack (= 2.3.1) + activerecord (= 2.3.1) + activeresource (= 2.3.1) + rake (= 10.0.1) + rake (10.0.1) + weakling (0.0.3) + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + foo + rails + weakling + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + + lockfile lockfile_with_outdated_rails_and_rake bundle "lock --update rails rake" - expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile, "(2.3.2)", "(#{rake_version})")) + expect(read_lockfile).to eq(expected_lockfile) end it "updates specific gems using --update, even if that requires unlocking other top level gems" do @@ -275,7 +415,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "tapioca" gem "ruby-lsp" @@ -283,7 +423,7 @@ RSpec.describe "bundle lock" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: prism (0.15.1) ruby-lsp (0.12.0) @@ -338,7 +478,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "tapioca" gem "ruby-lsp" @@ -347,7 +487,7 @@ RSpec.describe "bundle lock" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: other-prism-dependent (1.0.0) prism (>= 0.15.1) @@ -375,7 +515,7 @@ RSpec.describe "bundle lock" do end it "preserves unknown checksum algorithms" do - lockfile @lockfile.gsub(/(sha256=[a-f0-9]+)$/, "constant=true,\\1,xyz=123") + lockfile expected_lockfile.gsub(/(sha256=[a-f0-9]+)$/, "constant=true,\\1,xyz=123") previous_lockfile = read_lockfile @@ -388,14 +528,14 @@ RSpec.describe "bundle lock" do build_git("foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo-1.0")}" G # Change uri format to end with "/" and reinstall install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}/" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo-1.0")}/" G expect(out).to include("using resolution from the lockfile") @@ -406,21 +546,21 @@ RSpec.describe "bundle lock" do ref = build_git("foo").ref_for("HEAD") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" - gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :branch => "deadbeef" + gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "deadbeef" G lockfile <<~L GIT - remote: #{file_uri_for(lib_path("foo-1.0"))} + remote: #{lib_path("foo-1.0")} revision: #{ref} branch: deadbeef specs: foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: rake (10.0.1) @@ -441,20 +581,20 @@ RSpec.describe "bundle lock" do end it "errors when updating a missing specific gems using --update" do - lockfile @lockfile + lockfile expected_lockfile bundle "lock --update blahblah", raise_on_error: false expect(err).to eq("Could not find gem 'blahblah'.") - expect(read_lockfile).to eq(@lockfile) + expect(read_lockfile).to eq(expected_lockfile) end it "can lock without downloading gems" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "thin" - gem "rack_middleware", :group => "test" + gem "myrack_middleware", :group => "test" G bundle "config set without test" bundle "config set path vendor/bundle" @@ -485,7 +625,7 @@ RSpec.describe "bundle lock" do # establish a lockfile set to 1.4.3 install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo', '1.4.3' gem 'bar', '2.0.3' gem 'qux', '1.0.0' @@ -494,7 +634,7 @@ RSpec.describe "bundle lock" do # remove 1.4.3 requirement and bar altogether # to setup update specs below gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo' gem 'qux' G @@ -517,7 +657,7 @@ RSpec.describe "bundle lock" do it "shows proper error when Gemfile changes forbid patch upgrades, and --patch --strict is given" do # force next minor via Gemfile gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo', '1.5.0' gem 'qux' G @@ -568,13 +708,13 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'sequel' G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sequel (5.71.0) @@ -606,7 +746,7 @@ RSpec.describe "bundle lock" do system_gems "bundler-55", gem_repo: gem_repo4 install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } - source "https://gems.repo4" + source "https://gem.repo4" G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2') @@ -629,10 +769,66 @@ RSpec.describe "bundle lock" do expect(lockfile.platforms).to match_array(default_platform_list(java, x86_mingw32)) end + it "supports adding new platforms, when most specific locked platform is not the current platform, and current resolve is not compatible with the target platform" do + simulate_platform "arm64-darwin-23" do + build_repo4 do + build_gem "foo" do |s| + s.platform = "arm64-darwin" + end + + build_gem "foo" do |s| + s.platform = "java" + end + end + + gemfile <<-G + source "https://gem.repo4" + + gem "foo" + G + + lockfile <<-L + GEM + remote: https://gem.repo4/ + specs: + foo (1.0-arm64-darwin) + + PLATFORMS + arm64-darwin + + DEPENDENCIES + foo + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "lock --add-platform java" + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + foo (1.0-arm64-darwin) + foo (1.0-java) + + PLATFORMS + arm64-darwin + java + + DEPENDENCIES + foo + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + it "supports adding new platforms with force_ruby_platform = true" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: platform_specific (1.0) platform_specific (1.0-x86-64_linux) @@ -661,9 +857,10 @@ RSpec.describe "bundle lock" do expect(lockfile.platforms).to match_array(default_platform_list("ruby")) end - it "warns when adding an unknown platform" do - bundle "lock --add-platform foobarbaz" - expect(err).to include("The platform `foobarbaz` is unknown to RubyGems and adding it will likely lead to resolution errors") + it "fails when adding an unknown platform" do + bundle "lock --add-platform foobarbaz", raise_on_error: false + expect(err).to include("The platform `foobarbaz` is unknown to RubyGems and can't be added to the lockfile") + expect(last_command).to be_failure end it "allows removing platforms" do @@ -687,14 +884,14 @@ RSpec.describe "bundle lock" do end end - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.12.0" c.checksum gem_repo4, "nokogiri", "1.12.0", "x86_64-darwin" end simulate_platform "x86_64-darwin-22" do install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" G @@ -702,7 +899,7 @@ RSpec.describe "bundle lock" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.12.0) nokogiri (1.12.0-x86_64-darwin) @@ -726,7 +923,7 @@ RSpec.describe "bundle lock" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.12.0-x86_64-darwin) @@ -777,24 +974,24 @@ RSpec.describe "bundle lock" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "mixlib-shellout" gem "gssapi" G - checksums = checksums_section_when_existing do |c| - c.no_checksum "ffi", "1.9.14", "x86-mingw32" - c.no_checksum "gssapi", "1.2.0" - c.no_checksum "mixlib-shellout", "2.2.6", "universal-mingw32" - c.no_checksum "win32-process", "0.8.3" - end - simulate_platform(x86_mingw32) { bundle :lock } + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "ffi", "1.9.14", "x86-mingw32" + c.checksum gem_repo4, "gssapi", "1.2.0" + c.checksum gem_repo4, "mixlib-shellout", "2.2.6", "universal-mingw32" + c.checksum gem_repo4, "win32-process", "0.8.3" + end + expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: ffi (1.9.14-x86-mingw32) gssapi (1.2.0) @@ -818,12 +1015,12 @@ RSpec.describe "bundle lock" do bundle "config set --local force_ruby_platform true" bundle :lock - checksums.no_checksum "ffi", "1.9.14" - checksums.no_checksum "mixlib-shellout", "2.2.6" + checksums.checksum gem_repo4, "ffi", "1.9.14" + checksums.checksum gem_repo4, "mixlib-shellout", "2.2.6" expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: ffi (1.9.14) ffi (1.9.14-x86-mingw32) @@ -861,14 +1058,14 @@ RSpec.describe "bundle lock" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "libv8" G lockfile <<-G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: libv8 (8.4.255.0) libv8 (8.4.255.0-x86_64-darwin-19) @@ -884,7 +1081,7 @@ RSpec.describe "bundle lock" do #{Bundler::VERSION} G - simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock --update" } + simulate_platform("x86_64-darwin-19") { bundle "lock --update" } expect(out).to match(/Writing lockfile to.+Gemfile\.lock/) end @@ -901,21 +1098,21 @@ RSpec.describe "bundle lock" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "libv8" G - simulate_platform(Gem::Platform.new("x86_64-darwin-19")) { bundle "lock" } + simulate_platform("x86_64-darwin-19") { bundle "lock" } - checksums = checksums_section_when_existing do |c| - c.no_checksum "libv8", "8.4.255.0", "x86_64-darwin-19" - c.no_checksum "libv8", "8.4.255.0", "x86_64-darwin-20" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-19" + c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-20" end expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: libv8 (8.4.255.0-x86_64-darwin-19) libv8 (8.4.255.0-x86_64-darwin-20) @@ -943,20 +1140,20 @@ RSpec.describe "bundle lock" do end end - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-19" c.checksum gem_repo4, "libv8", "8.4.255.0", "x86_64-darwin-20" end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "libv8" G lockfile <<-G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: libv8 (8.4.255.0-x86_64-darwin-19) libv8 (8.4.255.0-x86_64-darwin-20) @@ -974,7 +1171,7 @@ RSpec.describe "bundle lock" do previous_lockfile = lockfile %w[x86_64-darwin-19 x86_64-darwin-20].each do |platform| - simulate_platform(Gem::Platform.new(platform)) do + simulate_platform(platform) do bundle "lock" expect(lockfile).to eq(previous_lockfile) @@ -1008,14 +1205,14 @@ RSpec.describe "bundle lock" do end gemfile <<-G - source "https://localgemserver.test" + source "https://gem.repo4" gem "raygun-apm" G lockfile <<-L GEM - remote: https://localgemserver.test/ + remote: https://gem.repo4/ specs: raygun-apm (1.0.78-universal-darwin) @@ -1029,7 +1226,61 @@ RSpec.describe "bundle lock" do #{Bundler::VERSION} L - bundle "lock --add-platform x86_64-linux", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "lock --add-platform x86_64-linux" + end + + it "adds platform specific gems as necessary, even when adding the current platform" do + build_repo4 do + build_gem "nokogiri", "1.16.0" + + build_gem "nokogiri", "1.16.0" do |s| + s.platform = "x86_64-linux" + end + end + + gemfile <<-G + source "https://gem.repo4" + + gem "nokogiri" + G + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.16.0) + + PLATFORMS + ruby + + DEPENDENCIES + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + + simulate_platform "x86_64-linux" do + bundle "lock --add-platform x86_64-linux" + end + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.16.0) + nokogiri (1.16.0-x86_64-linux) + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L end it "does not crash on conflicting ruby requirements between platform versions in two different gems" do @@ -1121,35 +1372,32 @@ RSpec.describe "bundle lock" do end context "when an update is available" do - let(:repo) do - build_repo2 do + before do + update_repo4 do build_gem "foo", "2.0" end - gem_repo2 - end - before do - lockfile(@lockfile) + lockfile(expected_lockfile) end it "does not implicitly update" do bundle "lock" - checksums = checksums_section_when_existing do |c| - c.checksum repo, "actionmailer", "2.3.2" - c.checksum repo, "actionpack", "2.3.2" - c.checksum repo, "activerecord", "2.3.2" - c.checksum repo, "activeresource", "2.3.2" - c.checksum repo, "activesupport", "2.3.2" - c.checksum repo, "foo", "1.0" - c.checksum repo, "rails", "2.3.2" - c.checksum repo, "rake", rake_version - c.checksum repo, "weakling", "0.0.3" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "actionmailer", "2.3.2" + c.checksum gem_repo4, "actionpack", "2.3.2" + c.checksum gem_repo4, "activerecord", "2.3.2" + c.checksum gem_repo4, "activeresource", "2.3.2" + c.checksum gem_repo4, "activesupport", "2.3.2" + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "rails", "2.3.2" + c.checksum gem_repo4, "rake", rake_version + c.checksum gem_repo4, "weakling", "0.0.3" end expected_lockfile = <<~L GEM - remote: #{file_uri_for(repo)}/ + remote: https://gem.repo4/ specs: actionmailer (2.3.2) activesupport (= 2.3.2) @@ -1189,21 +1437,21 @@ RSpec.describe "bundle lock" do gemfile gemfile.gsub('"foo"', '"foo", "2.0"') bundle "lock" - checksums = checksums_section_when_existing do |c| - c.checksum repo, "actionmailer", "2.3.2" - c.checksum repo, "actionpack", "2.3.2" - c.checksum repo, "activerecord", "2.3.2" - c.checksum repo, "activeresource", "2.3.2" - c.checksum repo, "activesupport", "2.3.2" - c.no_checksum "foo", "2.0" - c.checksum repo, "rails", "2.3.2" - c.checksum repo, "rake", rake_version - c.checksum repo, "weakling", "0.0.3" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "actionmailer", "2.3.2" + c.checksum gem_repo4, "actionpack", "2.3.2" + c.checksum gem_repo4, "activerecord", "2.3.2" + c.checksum gem_repo4, "activeresource", "2.3.2" + c.checksum gem_repo4, "activesupport", "2.3.2" + c.checksum gem_repo4, "foo", "2.0" + c.checksum gem_repo4, "rails", "2.3.2" + c.checksum gem_repo4, "rake", rake_version + c.checksum gem_repo4, "weakling", "0.0.3" end expected_lockfile = <<~L GEM - remote: #{file_uri_for(repo)}/ + remote: https://gem.repo4/ specs: actionmailer (2.3.2) activesupport (= 2.3.2) @@ -1262,14 +1510,19 @@ RSpec.describe "bundle lock" do it "respects the existing lockfile, even when reresolving" do gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "debug" G + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "debug", "1.6.3" + c.checksum gem_repo4, "irb", "1.5.0" + end + lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: debug (1.6.3) irb (>= 1.3.6) @@ -1280,7 +1533,7 @@ RSpec.describe "bundle lock" do DEPENDENCIES debug - #{checksums_section} + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -1289,14 +1542,9 @@ RSpec.describe "bundle lock" do bundle "lock" end - checksums = checksums_section do |c| - c.no_checksum "debug", "1.6.3" - c.no_checksum "irb", "1.5.0" - end - expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: debug (1.6.3) irb (>= 1.3.6) @@ -1335,7 +1583,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rails", ">= 7.0.3.1" gem "activeadmin", "2.13.1" @@ -1349,7 +1597,7 @@ RSpec.describe "bundle lock" do Because rails >= 7.0.4 depends on railties = 7.0.4 and rails < 7.0.4 depends on railties = 7.0.3.1, railties = 7.0.3.1 OR = 7.0.4 is required. - So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally, + So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository https://gem.repo4/ or installed locally, version solving has failed. ERR end @@ -1390,7 +1638,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rails", ">= 7.0.2.3" gem "activeadmin", "= 2.13.1" @@ -1398,7 +1646,7 @@ RSpec.describe "bundle lock" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: activeadmin (2.13.1) ransack (= 3.1.0) @@ -1416,54 +1664,34 @@ RSpec.describe "bundle lock" do #{Bundler::VERSION} L - bundle "lock", raise_on_error: false - - expect(err).to eq <<~ERR.strip + expected_error = <<~ERR.strip Could not find compatible versions - Because every version of activemodel depends on activesupport = 6.0.4 - and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3, - every version of activemodel is incompatible with rails >= 7.0.2.3, < 7.0.3.1. - And because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3, - rails >= 7.0.2.3, < 7.0.3.1 cannot be used. - (1) So, because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1 - and rails >= 7.0.4 depends on activemodel = 7.0.4, - rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4. + Because rails >= 7.0.4 depends on activemodel = 7.0.4 + and rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1, + rails >= 7.0.3.1 requires activemodel = 7.0.3.1 OR = 7.0.4. + (1) So, because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3 + and every version of activemodel depends on activesupport = 6.0.4, + rails >= 7.0.2.3 requires activesupport = 6.0.4. - Because rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3 + Because rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3 and rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1, - rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 or activesupport = 7.0.3.1. - And because rails >= 7.0.4 depends on activesupport = 7.0.4 - and every version of activemodel depends on activesupport = 6.0.4, - activemodel != 7.0.2.3 is incompatible with rails >= 7.0.2.3. - And because rails >= 7.0.2.3 requires activemodel = 7.0.3.1 OR = 7.0.4 (1), + rails >= 7.0.2.3, < 7.0.4 requires activesupport = 7.0.2.3 OR = 7.0.3.1. + And because rails >= 7.0.4 depends on activesupport = 7.0.4, + rails >= 7.0.2.3 requires activesupport = 7.0.2.3 OR = 7.0.3.1 OR = 7.0.4. + And because rails >= 7.0.2.3 requires activesupport = 6.0.4 (1), rails >= 7.0.2.3 cannot be used. So, because Gemfile depends on rails >= 7.0.2.3, version solving has failed. ERR - lockfile lockfile.gsub(/PLATFORMS\n #{local_platform}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}") - bundle "lock", raise_on_error: false + expect(err).to eq(expected_error) - expect(err).to eq <<~ERR.strip - Could not find compatible versions + lockfile lockfile.gsub(/PLATFORMS\n #{local_platform}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}") - Because rails >= 7.0.3.1, < 7.0.4 depends on activemodel = 7.0.3.1 - and rails >= 7.0.2.3, < 7.0.3.1 depends on activemodel = 7.0.2.3, - rails >= 7.0.2.3, < 7.0.4 requires activemodel = 7.0.2.3 OR = 7.0.3.1. - And because every version of activemodel depends on activesupport = 6.0.4, - rails >= 7.0.2.3, < 7.0.4 requires activesupport = 6.0.4. - Because rails >= 7.0.3.1, < 7.0.4 depends on activesupport = 7.0.3.1 - and rails >= 7.0.2.3, < 7.0.3.1 depends on activesupport = 7.0.2.3, - rails >= 7.0.2.3, < 7.0.4 requires activesupport = 7.0.2.3 OR = 7.0.3.1. - Thus, rails >= 7.0.2.3, < 7.0.4 cannot be used. - And because rails >= 7.0.4 depends on activemodel = 7.0.4, - rails >= 7.0.2.3 requires activemodel = 7.0.4. - So, because activemodel = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally - and Gemfile depends on rails >= 7.0.2.3, - version solving has failed. - ERR + bundle "lock", raise_on_error: false + expect(err).to eq(expected_error) end it "does not accidentally resolves to prereleases" do @@ -1483,7 +1711,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "autoproj", ">= 2.0.0" G @@ -1508,7 +1736,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rails" G @@ -1531,7 +1759,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "activerecord", "6.0.6" gem "activerecord-jdbc-adapter", "61.0" G @@ -1557,7 +1785,7 @@ RSpec.describe "bundle lock" do it "does not end up including gems scoped to other platforms in the lockfile" do gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rails" gem "tzinfo-data", platform: :windows G @@ -1584,15 +1812,16 @@ RSpec.describe "bundle lock" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec G end - it "locks ruby specs" do - checksums = checksums_section_when_existing do |c| + it "locks both ruby and platform specific specs" do + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" - c.no_checksum "nokogiri", "1.14.2" + c.checksum gem_repo4, "nokogiri", "1.14.2" + c.checksum gem_repo4, "nokogiri", "1.14.2", "x86_64-linux" end simulate_platform "x86_64-linux" do @@ -1607,12 +1836,14 @@ RSpec.describe "bundle lock" do nokogiri GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.2) + nokogiri (1.14.2-x86_64-linux) PLATFORMS - #{lockfile_platforms} + ruby + x86_64-linux DEPENDENCIES foo! @@ -1621,6 +1852,73 @@ RSpec.describe "bundle lock" do #{Bundler::VERSION} L end + + context "and a lockfile with platform specific gems only already exists" do + before do + checksums = checksums_section_when_enabled do |c| + c.no_checksum "foo", "1.0" + c.checksum gem_repo4, "nokogiri", "1.14.2", "x86_64-linux" + end + + lockfile <<~L + PATH + remote: . + specs: + foo (1.0) + nokogiri + + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.14.2-x86_64-linux) + + PLATFORMS + x86_64-linux + + DEPENDENCIES + foo! + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "keeps platform specific gems" do + checksums = checksums_section_when_enabled do |c| + c.no_checksum "foo", "1.0" + c.checksum gem_repo4, "nokogiri", "1.14.2" + c.checksum gem_repo4, "nokogiri", "1.14.2", "x86_64-linux" + end + + simulate_platform "x86_64-linux" do + bundle "install" + end + + expect(lockfile).to eq <<~L + PATH + remote: . + specs: + foo (1.0) + nokogiri + + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.14.2) + nokogiri (1.14.2-x86_64-linux) + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + foo! + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + end end context "when adding a new gem that requires unlocking other transitive deps" do @@ -1644,7 +1942,7 @@ RSpec.describe "bundle lock" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "govuk_app_config" gem "activesupport", "7.0.4.3" @@ -1655,7 +1953,7 @@ RSpec.describe "bundle lock" do # version lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: actionpack (7.0.4.1) activesupport (7.0.4.1) @@ -1677,7 +1975,7 @@ RSpec.describe "bundle lock" do end it "does not downgrade top level dependencies" do - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "actionpack", "7.0.4.3" c.no_checksum "activesupport", "7.0.4.3" c.no_checksum "govuk_app_config", "4.13.0" @@ -1690,7 +1988,7 @@ RSpec.describe "bundle lock" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: actionpack (7.0.4.3) activesupport (7.0.4.3) @@ -1712,4 +2010,64 @@ RSpec.describe "bundle lock" do L end end + + context "when lockfile has incorrectly indented platforms" do + before do + build_repo4 do + build_gem "ffi", "1.1.0" do |s| + s.platform = "x86_64-linux" + end + + build_gem "ffi", "1.1.0" do |s| + s.platform = "arm64-darwin" + end + end + + gemfile <<~G + source "https://gem.repo4" + + gem "ffi" + G + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + ffi (1.1.0-arm64-darwin) + + PLATFORMS + arm64-darwin + + DEPENDENCIES + ffi + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + it "does not remove any gems" do + simulate_platform "x86_64-linux" do + bundle "lock --update" + end + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + ffi (1.1.0-arm64-darwin) + ffi (1.1.0-x86_64-linux) + + PLATFORMS + arm64-darwin + x86_64-linux + + DEPENDENCIES + ffi + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end end diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb index 199340b131..668bc0f95e 100644 --- a/spec/bundler/commands/newgem_spec.rb +++ b/spec/bundler/commands/newgem_spec.rb @@ -33,25 +33,28 @@ RSpec.describe "bundle gem" do let(:minitest_test_class_name) { "class TestMygem < Minitest::Test" } before do - sys_exec("git config --global user.name 'Bundler User'") - sys_exec("git config --global user.email user@example.com") - sys_exec("git config --global github.user bundleuser") + git("config --global user.name 'Bundler User'") + git("config --global user.email user@example.com") + git("config --global github.user bundleuser") + + global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false", + "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false" end describe "git repo initialization" do - it "generates a gem skeleton with a .git folder", :readline do + it "generates a gem skeleton with a .git folder" do bundle "gem #{gem_name}" gem_skeleton_assertions expect(bundled_app("#{gem_name}/.git")).to exist end - it "generates a gem skeleton with a .git folder when passing --git", :readline do + it "generates a gem skeleton with a .git folder when passing --git" do bundle "gem #{gem_name} --git" gem_skeleton_assertions expect(bundled_app("#{gem_name}/.git")).to exist end - it "generates a gem skeleton without a .git folder when passing --no-git", :readline do + it "generates a gem skeleton without a .git folder when passing --no-git" do bundle "gem #{gem_name} --no-git" gem_skeleton_assertions expect(bundled_app("#{gem_name}/.git")).not_to exist @@ -62,7 +65,9 @@ RSpec.describe "bundle gem" do Dir.mkdir(bundled_app("path with spaces")) end - it "properly initializes git repo", :readline do + it "properly initializes git repo" do + skip "path with spaces needs special handling on Windows" if Gem.win_platform? + bundle "gem #{gem_name}", dir: bundled_app("path with spaces") expect(bundled_app("path with spaces/#{gem_name}/.git")).to exist end @@ -104,7 +109,7 @@ RSpec.describe "bundle gem" do end it "generates the README with a section for the Code of Conduct, respecting the configured git default branch", git: ">= 2.28.0" do - sys_exec("git config --global init.defaultBranch main") + git("config --global init.defaultBranch main") bundle "gem #{gem_name} --coc" expect(bundled_app("#{gem_name}/README.md").read).to include("## Code of Conduct") @@ -131,7 +136,7 @@ RSpec.describe "bundle gem" do before do bundle "gem #{gem_name} --changelog" end - it "generates a gem skeleton with a CHANGELOG", :readline do + it "generates a gem skeleton with a CHANGELOG" do gem_skeleton_assertions expect(bundled_app("#{gem_name}/CHANGELOG.md")).to exist end @@ -141,7 +146,7 @@ RSpec.describe "bundle gem" do before do bundle "gem #{gem_name} --no-changelog" end - it "generates a gem skeleton without a CHANGELOG", :readline do + it "generates a gem skeleton without a CHANGELOG" do gem_skeleton_assertions expect(bundled_app("#{gem_name}/CHANGELOG.md")).to_not exist end @@ -150,6 +155,7 @@ RSpec.describe "bundle gem" do shared_examples_for "--rubocop flag" do context "is deprecated", bundler: "< 3" do before do + global_config "BUNDLE_GEM__LINTER" => nil bundle "gem #{gem_name} --rubocop" end @@ -263,11 +269,11 @@ RSpec.describe "bundle gem" do end end - shared_examples_for "--linter=none flag" do + shared_examples_for "--no-linter flag" do define_negated_matcher :exclude, :include before do - bundle "gem #{gem_name} --linter=none" + bundle "gem #{gem_name} --no-linter" end it "generates a gem skeleton without rubocop" do @@ -303,49 +309,49 @@ RSpec.describe "bundle gem" do end end - it "has no rubocop offenses when using --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? bundle "gem #{gem_name} --linter=rubocop" bundle_exec_rubocop expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=c and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=c and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? bundle "gem #{gem_name} --ext=c --linter=rubocop" bundle_exec_rubocop expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? bundle "gem #{gem_name} --ext=c --test=minitest --linter=rubocop" bundle_exec_rubocop expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? bundle "gem #{gem_name} --ext=c --test=rspec --linter=rubocop" bundle_exec_rubocop expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? bundle "gem #{gem_name} --ext=c --test=test-unit --linter=rubocop" bundle_exec_rubocop expect(last_command).to be_success end - it "has no standard offenses when using --linter=standard flag", :readline do + it "has no standard offenses when using --linter=standard flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? bundle "gem #{gem_name} --linter=standard" bundle_exec_standardrb expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version @@ -354,7 +360,7 @@ RSpec.describe "bundle gem" do expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version @@ -363,7 +369,7 @@ RSpec.describe "bundle gem" do expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version @@ -372,7 +378,7 @@ RSpec.describe "bundle gem" do expect(last_command).to be_success end - it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag", :readline do + it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag" do skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core? skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version @@ -399,7 +405,7 @@ RSpec.describe "bundle gem" do end end - context "README.md", :readline do + context "README.md" do context "git config github.user present" do before do bundle "gem #{gem_name}" @@ -413,7 +419,7 @@ RSpec.describe "bundle gem" do context "git config github.user is absent" do before do - sys_exec("git config --global --unset github.user") + git("config --global --unset github.user") bundle "gem #{gem_name}" end @@ -424,12 +430,12 @@ RSpec.describe "bundle gem" do end end - it "creates a new git repository", :readline do + it "creates a new git repository" do bundle "gem #{gem_name}" expect(bundled_app("#{gem_name}/.git")).to exist end - context "when git is not available", :readline do + context "when git is not available" do # This spec cannot have `git` available in the test env before do load_paths = [lib_dir, spec_dir] @@ -451,7 +457,7 @@ RSpec.describe "bundle gem" do end end - it "generates a valid gemspec", :readline, :ruby_repo do + it "generates a valid gemspec", :ruby_repo do bundle "gem newgem --bin" prepare_gemspec(bundled_app("newgem", "newgem.gemspec")) @@ -464,7 +470,7 @@ RSpec.describe "bundle gem" do expect(last_command.stdboth).not_to include("ERROR") end - context "gem naming with relative paths", :readline do + context "gem naming with relative paths" do it "resolves ." do create_temporary_dir("tmp") @@ -557,8 +563,12 @@ RSpec.describe "bundle gem" do expect(bundled_app("#{gem_name}/bin/setup")).to exist expect(bundled_app("#{gem_name}/bin/console")).to exist - expect(bundled_app("#{gem_name}/bin/setup")).to be_executable - expect(bundled_app("#{gem_name}/bin/console")).to be_executable + + unless Gem.win_platform? + expect(bundled_app("#{gem_name}/bin/setup")).to be_executable + expect(bundled_app("#{gem_name}/bin/console")).to be_executable + end + expect(bundled_app("#{gem_name}/bin/setup").read).to start_with("#!") expect(bundled_app("#{gem_name}/bin/console").read).to start_with("#!") end @@ -591,8 +601,8 @@ RSpec.describe "bundle gem" do context "git config user.{name,email} is not set" do before do - sys_exec("git config --global --unset user.name") - sys_exec("git config --global --unset user.email") + git("config --global --unset user.name") + git("config --global --unset user.email") bundle "gem #{gem_name}" end @@ -671,6 +681,9 @@ RSpec.describe "bundle gem" do it "builds exe skeleton" do expect(bundled_app("#{gem_name}/exe/#{gem_name}")).to exist + unless Gem.win_platform? + expect(bundled_app("#{gem_name}/exe/#{gem_name}")).to be_executable + end end it "requires the main file" do @@ -729,6 +742,30 @@ RSpec.describe "bundle gem" do end end + context "init_gems_rb setting to true" do + before do + bundle "config set init_gems_rb true" + bundle "gem #{gem_name}" + end + + it "generates gems.rb instead of Gemfile" do + expect(bundled_app("#{gem_name}/gems.rb")).to exist + expect(bundled_app("#{gem_name}/Gemfile")).to_not exist + end + end + + context "init_gems_rb setting to false" do + before do + bundle "config set init_gems_rb false" + bundle "gem #{gem_name}" + end + + it "generates Gemfile instead of gems.rb" do + expect(bundled_app("#{gem_name}/gems.rb")).to_not exist + expect(bundled_app("#{gem_name}/Gemfile")).to exist + end + end + context "gem.test setting set to rspec" do before do bundle "config set gem.test rspec" @@ -844,6 +881,17 @@ RSpec.describe "bundle gem" do end end + context "--test parameter set to an invalid value" do + before do + bundle "gem #{gem_name} --test=foo", raise_on_error: false + end + + it "fails loudly" do + expect(last_command).to be_failure + expect(err).to match(/Expected '--test' to be one of .*; got foo/) + end + end + context "gem.test setting set to test-unit" do before do bundle "config set gem.test test-unit" @@ -870,7 +918,7 @@ RSpec.describe "bundle gem" do end end - context "gem.test set to rspec and --test with no arguments", :hint_text do + context "gem.test set to rspec and --test with no arguments" do before do bundle "config set gem.test rspec" bundle "gem #{gem_name} --test" @@ -887,10 +935,12 @@ RSpec.describe "bundle gem" do end end - context "gem.test setting set to false and --test with no arguments", :hint_text do + context "gem.test setting set to false and --test with no arguments", :readline do before do bundle "config set gem.test false" - bundle "gem #{gem_name} --test" + bundle "gem #{gem_name} --test" do |input, _, _| + input.puts + end end it "asks to generate test files" do @@ -904,9 +954,12 @@ RSpec.describe "bundle gem" do it_behaves_like "test framework is absent" end - context "gem.test setting not set and --test with no arguments", :hint_text do + context "gem.test setting not set and --test with no arguments", :readline do before do - bundle "gem #{gem_name} --test" + global_config "BUNDLE_GEM__TEST" => nil + bundle "gem #{gem_name} --test" do |input, _, _| + input.puts + end end it "asks to generate test files" do @@ -922,6 +975,15 @@ RSpec.describe "bundle gem" do it_behaves_like "test framework is absent" end + context "gem.test setting set to a test framework and --no-test" do + before do + bundle "config set gem.test rspec" + bundle "gem #{gem_name} --no-test" + end + + it_behaves_like "test framework is absent" + end + context "--ci with no argument" do it "does not generate any CI config" do bundle "gem #{gem_name}" @@ -974,6 +1036,17 @@ RSpec.describe "bundle gem" do end end + context "--ci set to an invalid value" do + before do + bundle "gem #{gem_name} --ci=foo", raise_on_error: false + end + + it "fails loudly" do + expect(last_command).to be_failure + expect(err).to match(/Expected '--ci' to be one of .*; got foo/) + end + end + context "gem.ci setting set to none" do it "doesn't generate any CI config" do expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist @@ -1009,7 +1082,7 @@ RSpec.describe "bundle gem" do end end - context "gem.ci set to github and --ci with no arguments", :hint_text do + context "gem.ci set to github and --ci with no arguments" do before do bundle "config set gem.ci github" bundle "gem #{gem_name} --ci" @@ -1024,10 +1097,12 @@ RSpec.describe "bundle gem" do end end - context "gem.ci setting set to false and --ci with no arguments", :hint_text do + context "gem.ci setting set to false and --ci with no arguments", :readline do before do bundle "config set gem.ci false" - bundle "gem #{gem_name} --ci" + bundle "gem #{gem_name} --ci" do |input, _, _| + input.puts "github" + end end it "asks to setup CI" do @@ -1039,9 +1114,12 @@ RSpec.describe "bundle gem" do end end - context "gem.ci setting not set and --ci with no arguments", :hint_text do + context "gem.ci setting not set and --ci with no arguments", :readline do before do - bundle "gem #{gem_name} --ci" + global_config "BUNDLE_GEM__CI" => nil + bundle "gem #{gem_name} --ci" do |input, _, _| + input.puts "github" + end end it "asks to setup CI" do @@ -1055,6 +1133,19 @@ RSpec.describe "bundle gem" do end end + context "gem.ci setting set to a CI service and --no-ci" do + before do + bundle "config set gem.ci github" + bundle "gem #{gem_name} --no-ci" + end + + it "does not generate any CI config" do + expect(bundled_app("#{gem_name}/.github/workflows/main.yml")).to_not exist + expect(bundled_app("#{gem_name}/.gitlab-ci.yml")).to_not exist + expect(bundled_app("#{gem_name}/.circleci/config.yml")).to_not exist + end + end + context "--linter with no argument" do it "does not generate any linter config" do bundle "gem #{gem_name}" @@ -1082,6 +1173,17 @@ RSpec.describe "bundle gem" do end end + context "--linter set to an invalid value" do + before do + bundle "gem #{gem_name} --linter=foo", raise_on_error: false + end + + it "fails loudly" do + expect(last_command).to be_failure + expect(err).to match(/Expected '--linter' to be one of .*; got foo/) + end + end + context "gem.linter setting set to none" do it "doesn't generate any linter config" do bundle "gem #{gem_name}" @@ -1111,6 +1213,7 @@ RSpec.describe "bundle gem" do context "gem.rubocop setting set to true", bundler: "< 3" do before do + global_config "BUNDLE_GEM__LINTER" => nil bundle "config set gem.rubocop true" bundle "gem #{gem_name}" end @@ -1130,7 +1233,7 @@ RSpec.describe "bundle gem" do end end - context "gem.linter set to rubocop and --linter with no arguments", :hint_text do + context "gem.linter set to rubocop and --linter with no arguments" do before do bundle "config set gem.linter rubocop" bundle "gem #{gem_name} --linter" @@ -1145,10 +1248,12 @@ RSpec.describe "bundle gem" do end end - context "gem.linter setting set to false and --linter with no arguments", :hint_text do + context "gem.linter setting set to false and --linter with no arguments", :readline do before do bundle "config set gem.linter false" - bundle "gem #{gem_name} --linter" + bundle "gem #{gem_name} --linter" do |input, _, _| + input.puts "rubocop" + end end it "asks to setup a linter" do @@ -1160,9 +1265,12 @@ RSpec.describe "bundle gem" do end end - context "gem.linter setting not set and --linter with no arguments", :hint_text do + context "gem.linter setting not set and --linter with no arguments", :readline do before do - bundle "gem #{gem_name} --linter" + global_config "BUNDLE_GEM__LINTER" => nil + bundle "gem #{gem_name} --linter" do |input, _, _| + input.puts "rubocop" + end end it "asks to setup a linter" do @@ -1176,6 +1284,18 @@ RSpec.describe "bundle gem" do end end + context "gem.linter setting set to a linter and --no-linter" do + before do + bundle "config set gem.linter rubocop" + bundle "gem #{gem_name} --no-linter" + end + + it "does not generate any linter config" do + expect(bundled_app("#{gem_name}/.rubocop.yml")).to_not exist + expect(bundled_app("#{gem_name}/.standard.yml")).to_not exist + end + end + context "--edit option" do it "opens the generated gemspec in the user's text editor" do output = bundle "gem #{gem_name} --edit=echo" @@ -1185,7 +1305,7 @@ RSpec.describe "bundle gem" do end end - context "testing --mit and --coc options against bundle config settings", :readline do + context "testing --mit and --coc options against bundle config settings" do let(:gem_name) { "test-gem" } let(:require_path) { "test/gem" } @@ -1228,7 +1348,7 @@ RSpec.describe "bundle gem" do end it_behaves_like "--linter=rubocop flag" it_behaves_like "--linter=standard flag" - it_behaves_like "--linter=none flag" + it_behaves_like "--no-linter flag" it_behaves_like "--rubocop flag" it_behaves_like "--no-rubocop flag" end @@ -1239,7 +1359,7 @@ RSpec.describe "bundle gem" do end it_behaves_like "--linter=rubocop flag" it_behaves_like "--linter=standard flag" - it_behaves_like "--linter=none flag" + it_behaves_like "--no-linter flag" it_behaves_like "--rubocop flag" it_behaves_like "--no-rubocop flag" end @@ -1250,7 +1370,7 @@ RSpec.describe "bundle gem" do end it_behaves_like "--linter=rubocop flag" it_behaves_like "--linter=standard flag" - it_behaves_like "--linter=none flag" + it_behaves_like "--no-linter flag" end context "with linter option in bundle config settings set to standard" do @@ -1259,7 +1379,7 @@ RSpec.describe "bundle gem" do end it_behaves_like "--linter=rubocop flag" it_behaves_like "--linter=standard flag" - it_behaves_like "--linter=none flag" + it_behaves_like "--no-linter flag" end context "with linter option in bundle config settings set to false" do @@ -1268,7 +1388,7 @@ RSpec.describe "bundle gem" do end it_behaves_like "--linter=rubocop flag" it_behaves_like "--linter=standard flag" - it_behaves_like "--linter=none flag" + it_behaves_like "--no-linter flag" end context "with changelog option in bundle config settings set to true" do @@ -1288,10 +1408,10 @@ RSpec.describe "bundle gem" do end end - context "testing --github-username option against git and bundle config settings", :readline do + context "testing --github-username option against git and bundle config settings" do context "without git config set" do before do - sys_exec("git config --global --unset github.user") + git("config --global --unset github.user") end context "with github-username option in bundle config settings set to some value" do before do @@ -1325,10 +1445,10 @@ RSpec.describe "bundle gem" do end end - context "testing github_username bundle config against git config settings", :readline do + context "testing github_username bundle config against git config settings" do context "without git config set" do before do - sys_exec("git config --global --unset github.user") + git("config --global --unset github.user") end it_behaves_like "github_username configuration" @@ -1339,7 +1459,7 @@ RSpec.describe "bundle gem" do end end - context "gem naming with underscore", :readline do + context "gem naming with underscore" do let(:gem_name) { "test_gem" } let(:require_path) { "test_gem" } @@ -1485,7 +1605,7 @@ RSpec.describe "bundle gem" do end end - context "gem naming with dashed", :readline do + context "gem naming with dashed" do let(:gem_name) { "test-gem" } let(:require_path) { "test/gem" } @@ -1506,7 +1626,7 @@ RSpec.describe "bundle gem" do end describe "uncommon gem names" do - it "can deal with two dashes", :readline do + it "can deal with two dashes" do bundle "gem a--a" expect(bundled_app("a--a/a--a.gemspec")).to exist @@ -1536,7 +1656,7 @@ Usage: "bundle gem NAME [OPTIONS]" end end - describe "#ensure_safe_gem_name", :readline do + describe "#ensure_safe_gem_name" do before do bundle "gem #{subject}", raise_on_error: false end @@ -1564,7 +1684,7 @@ Usage: "bundle gem NAME [OPTIONS]" context "on first run", :readline do it "asks about test framework" do - global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false" + global_config "BUNDLE_GEM__TEST" => nil bundle "gem foobar" do |input, _, _| input.puts "rspec" @@ -1587,7 +1707,7 @@ Usage: "bundle gem NAME [OPTIONS]" end it "asks about CI service" do - global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false" + global_config "BUNDLE_GEM__CI" => nil bundle "gem foobar" do |input, _, _| input.puts "github" @@ -1597,7 +1717,7 @@ Usage: "bundle gem NAME [OPTIONS]" end it "asks about MIT license" do - global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false" + global_config "BUNDLE_GEM__MIT" => nil bundle "config list" @@ -1609,7 +1729,7 @@ Usage: "bundle gem NAME [OPTIONS]" end it "asks about CoC" do - global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false" + global_config "BUNDLE_GEM__COC" => nil bundle "gem foobar" do |input, _, _| input.puts "yes" @@ -1619,8 +1739,7 @@ Usage: "bundle gem NAME [OPTIONS]" end it "asks about CHANGELOG" do - global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false", - "BUNDLE_GEM__COC" => "false" + global_config "BUNDLE_GEM__CHANGELOG" => nil bundle "gem foobar" do |input, _, _| input.puts "yes" @@ -1630,7 +1749,7 @@ Usage: "bundle gem NAME [OPTIONS]" end end - context "on conflicts with a previously created file", :readline do + context "on conflicts with a previously created file" do it "should fail gracefully" do FileUtils.touch(bundled_app("conflict-foobar")) bundle "gem conflict-foobar", raise_on_error: false @@ -1639,7 +1758,7 @@ Usage: "bundle gem NAME [OPTIONS]" end end - context "on conflicts with a previously created directory", :readline do + context "on conflicts with a previously created directory" do it "should succeed" do FileUtils.mkdir_p(bundled_app("conflict-foobar/Gemfile")) bundle "gem conflict-foobar" diff --git a/spec/bundler/commands/open_spec.rb b/spec/bundler/commands/open_spec.rb index 97374f30c3..e0c79aa407 100644 --- a/spec/bundler/commands/open_spec.rb +++ b/spec/bundler/commands/open_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "bundle open" do context "when opening a regular gem" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G end @@ -39,12 +39,12 @@ RSpec.describe "bundle open" do ref = git.ref_for("main", 11) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{lib_path("foo-1.0")}" G bundle "open foo", env: { "EDITOR" => "echo editor", "VISUAL" => "", "BUNDLER_EDITOR" => "" } - expect(out).to include("editor #{default_bundle_path.join("bundler", "gems", "foo-1.0-#{ref}")}") + expect(out).to include("editor #{default_bundle_path("bundler", "gems", "foo-1.0-#{ref}")}") end it "suggests alternatives for similar-sounding gems" do @@ -134,7 +134,7 @@ RSpec.describe "bundle open" do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" gem "foo" G @@ -163,8 +163,7 @@ RSpec.describe "bundle open" do skip "No default gems available on this test run" if default_gems.empty? install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "json" + source "https://gem.repo1" G end diff --git a/spec/bundler/commands/outdated_spec.rb b/spec/bundler/commands/outdated_spec.rb index e7edc67e57..449fba5935 100644 --- a/spec/bundler/commands/outdated_spec.rb +++ b/spec/bundler/commands/outdated_spec.rb @@ -9,7 +9,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -46,7 +46,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "AAA", "1.0.0" G @@ -77,7 +77,7 @@ RSpec.describe "bundle outdated" do it "adds gem group to dependency output when repo is updated" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "terranova", '8' @@ -109,7 +109,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -126,14 +126,14 @@ RSpec.describe "bundle outdated" do update_repo2 { build_gem "terranova", "9" } install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "terranova", '9' gem 'activesupport', '2.3.5' G gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "terranova", '8' gem 'activesupport', '2.3.5' @@ -162,7 +162,7 @@ RSpec.describe "bundle outdated" do build_gem "vcr", "6.0.0" end - build_repo gem_repo3 do + build_repo3 do build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s| s.add_dependency "oj" end @@ -225,7 +225,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "weakling", "~> 0.0.1" gem "terranova", '8' @@ -251,6 +251,14 @@ RSpec.describe "bundle outdated" do expect(out).to end_with("Bundle up to date!") end + it "works when only out of date gems are not in given group" do + update_repo2 do + build_gem "terranova", "9" + end + bundle "outdated --group development" + expect(out).to end_with("Bundle up to date!") + end + it "returns a sorted list of outdated gems from one group => 'default'" do test_group_option("default") @@ -301,7 +309,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "bar_dependant", '7.0' G @@ -331,7 +339,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "weakling", "~> 0.0.1" gem "terranova", '8' @@ -375,7 +383,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "weakling", "~> 0.0.1" gem "terranova", '8' @@ -394,7 +402,7 @@ RSpec.describe "bundle outdated" do bundle "config set clean false" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.4" G @@ -428,7 +436,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -438,19 +446,40 @@ RSpec.describe "bundle outdated" do G end - it "outputs a sorted list of outdated gems with a more minimal format" do + it "outputs a sorted list of outdated gems with a more minimal format to stdout" do minimal_output = "activesupport (newest 3.0, installed 2.3.5, requested = 2.3.5)\n" \ "weakling (newest 0.2, installed 0.0.3, requested ~> 0.0.1)" subject expect(out).to eq(minimal_output) end + + it "outputs progress to stderr" do + subject + expect(err).to include("Fetching gem metadata") + end end context "and no gems are outdated" do - it "has empty output" do + before do + build_repo2 do + build_gem "activesupport", "3.0" + end + + install_gemfile <<-G + source "https://gem.repo2" + gem "activesupport", "3.0" + G + end + + it "does not output to stdout" do subject expect(out).to be_empty end + + it "outputs progress to stderr" do + subject + expect(err).to include("Fetching gem metadata") + end end end @@ -474,7 +503,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -507,7 +536,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -554,7 +583,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "3.0.0.beta.1" G @@ -578,7 +607,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -622,7 +651,7 @@ RSpec.describe "bundle outdated" do it "doesn't crash when some deps unused on the current platform" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", platforms: [:ruby_22] G @@ -633,8 +662,8 @@ RSpec.describe "bundle outdated" do it "only reports gem dependencies when they can actually be updated" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack_middleware", "1.0" + source "https://gem.repo2" + gem "myrack_middleware", "1.0" G bundle :outdated, "filter-strict": true @@ -645,7 +674,7 @@ RSpec.describe "bundle outdated" do describe "and filter options" do it "only reports gems that match requirement and patch filter level" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "~> 2.3" gem "weakling", ">= 0.0.1" G @@ -667,7 +696,7 @@ RSpec.describe "bundle outdated" do it "only reports gems that match requirement and minor filter level" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "~> 2.3" gem "weakling", ">= 0.0.1" G @@ -689,7 +718,7 @@ RSpec.describe "bundle outdated" do it "only reports gems that match requirement and major filter level" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "~> 2.3" gem "weakling", ">= 0.0.1" G @@ -719,7 +748,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -742,8 +771,8 @@ RSpec.describe "bundle outdated" do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" gem "foo" G @@ -757,9 +786,9 @@ RSpec.describe "bundle outdated" do build_repo2 gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack" + gem "myrack" gem "foo" G bundle :lock @@ -786,9 +815,9 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack" + gem "myrack" gem "foo" G bundle "config set --local deployment true" @@ -811,7 +840,7 @@ RSpec.describe "bundle outdated" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "laduradura", '= 5.15.2' G end @@ -829,7 +858,7 @@ RSpec.describe "bundle outdated" do it "reports that updates are available if the Ruby platform is used" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby] G @@ -839,7 +868,7 @@ RSpec.describe "bundle outdated" do it "reports that updates are available if the JRuby platform is used", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby] G @@ -872,7 +901,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -898,7 +927,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -928,7 +957,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -954,7 +983,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -987,7 +1016,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -1013,7 +1042,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -1039,7 +1068,7 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" @@ -1123,7 +1152,7 @@ RSpec.describe "bundle outdated" do # establish a lockfile set to 1.0.0 install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'patch', '1.0.0' gem 'minor', '1.0.0' gem 'major', '1.0.0' @@ -1131,7 +1160,7 @@ RSpec.describe "bundle outdated" do # remove all version requirements gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'patch' gem 'minor' gem 'major' @@ -1196,7 +1225,7 @@ RSpec.describe "bundle outdated" do # establish a lockfile set to 1.4.3 install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo', '1.4.3' gem 'bar', '2.0.3' gem 'qux', '1.0.0' @@ -1205,7 +1234,7 @@ RSpec.describe "bundle outdated" do # remove 1.4.3 requirement and bar altogether # to setup update specs below gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo' gem 'qux' G @@ -1246,13 +1275,13 @@ RSpec.describe "bundle outdated" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'weakling', '0.2' gem 'bar', '2.1' G gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'weakling' G @@ -1283,7 +1312,7 @@ RSpec.describe "bundle outdated" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.11.1) nokogiri (1.11.1-#{Bundler.local_platform}) @@ -1300,7 +1329,7 @@ RSpec.describe "bundle outdated" do L gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" G end @@ -1330,14 +1359,14 @@ RSpec.describe "bundle outdated" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "mini_portile2" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: mini_portile2 (2.5.2) net-ftp (~> 0.1) diff --git a/spec/bundler/commands/platform_spec.rb b/spec/bundler/commands/platform_spec.rb index 61e615acae..6e0a02bcf0 100644 --- a/spec/bundler/commands/platform_spec.rb +++ b/spec/bundler/commands/platform_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "bundle platform" do context "without flags" do it "returns all the output" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" #{ruby_version_correct} @@ -27,7 +27,7 @@ G it "returns all the output including the patchlevel" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" #{ruby_version_correct_patchlevel} @@ -50,7 +50,7 @@ G it "doesn't print ruby version requirement if it isn't specified" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G @@ -68,7 +68,7 @@ G it "doesn't match the ruby version requirement" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" #{ruby_version_incorrect} @@ -93,7 +93,7 @@ G context "--ruby" do it "returns ruby version when explicit" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.9.3", :engine => 'ruby', :engine_version => '1.9.3' gem "foo" @@ -106,7 +106,7 @@ G it "defaults to MRI" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.9.3" gem "foo" @@ -119,7 +119,7 @@ G it "handles jruby" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.8.7", :engine => 'jruby', :engine_version => '1.6.5' gem "foo" @@ -132,7 +132,7 @@ G it "handles rbx" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.8.7", :engine => 'rbx', :engine_version => '1.2.4' gem "foo" @@ -145,7 +145,7 @@ G it "handles truffleruby" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "2.5.1", :engine => 'truffleruby', :engine_version => '1.0.0-rc6' gem "foo" @@ -158,7 +158,7 @@ G it "raises an error if engine is used but engine version is not" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.8.7", :engine => 'rbx' gem "foo" @@ -171,7 +171,7 @@ G it "raises an error if engine_version is used but engine is not" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.8.7", :engine_version => '1.2.4' gem "foo" @@ -184,7 +184,7 @@ G it "raises an error if engine version doesn't match ruby version for MRI" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "1.8.7", :engine => 'ruby', :engine_version => '1.2.4' gem "foo" @@ -197,7 +197,7 @@ G it "should print if no ruby version is specified" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G @@ -209,13 +209,13 @@ G it "handles when there is a locked requirement" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "< 1.8.7" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -236,12 +236,12 @@ G it "handles when there is a lockfile with no requirement" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -259,7 +259,7 @@ G it "handles when there is a requirement in the gemfile" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= 1.8.7" G @@ -269,7 +269,7 @@ G it "handles when there are multiple requirements in the gemfile" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= 1.8.7", "< 2.0.0" G @@ -315,8 +315,8 @@ G context "bundle install" do it "installs fine when the ruby version matches" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_correct} G @@ -326,8 +326,8 @@ G it "installs fine with any engine", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_correct_engineless} G @@ -337,8 +337,8 @@ G it "installs fine when the patchlevel matches" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_correct_patchlevel} G @@ -348,8 +348,8 @@ G it "doesn't install when the ruby version doesn't match" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_incorrect} G @@ -360,8 +360,8 @@ G it "doesn't install when engine doesn't match" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{engine_incorrect} G @@ -372,8 +372,8 @@ G it "doesn't install when engine version doesn't match", :jruby_only do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{engine_version_incorrect} G @@ -384,8 +384,8 @@ G it "doesn't install when patchlevel doesn't match" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G @@ -398,13 +398,13 @@ G context "bundle check" do it "checks fine when the ruby version matches" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_correct} G @@ -415,13 +415,13 @@ G it "checks fine with any engine", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_correct_engineless} G @@ -432,13 +432,13 @@ G it "fails when ruby version doesn't match" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{ruby_version_incorrect} G @@ -449,13 +449,13 @@ G it "fails when engine doesn't match" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{engine_incorrect} G @@ -466,13 +466,13 @@ G it "fails when engine version doesn't match", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{engine_version_incorrect} G @@ -483,13 +483,13 @@ G it "fails when patchlevel doesn't match" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G @@ -504,57 +504,57 @@ G build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" G end it "updates successfully when the ruby version matches" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" #{ruby_version_correct} G update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" end bundle "update", all: true - expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0" + expect(the_bundle).to include_gems "myrack 1.2", "myrack-obama 1.0", "activesupport 3.0" end it "updates fine with any engine", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" #{ruby_version_correct_engineless} G update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" end bundle "update", all: true - expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0" + expect(the_bundle).to include_gems "myrack 1.2", "myrack-obama 1.0", "activesupport 3.0" end it "fails when ruby version doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" #{ruby_version_incorrect} G @@ -568,9 +568,9 @@ G it "fails when ruby engine doesn't match", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" #{engine_incorrect} G @@ -584,9 +584,9 @@ G it "fails when ruby engine version doesn't match", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" #{engine_version_incorrect} G @@ -600,8 +600,8 @@ G it "fails when patchlevel doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G @@ -617,14 +617,14 @@ G context "bundle info" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G end it "prints path if ruby version is correct" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" #{ruby_version_correct} @@ -636,7 +636,7 @@ G it "prints path if ruby version is correct for any engine", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" #{ruby_version_correct_engineless} @@ -648,7 +648,7 @@ G it "fails if ruby version doesn't match", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" #{ruby_version_incorrect} @@ -660,7 +660,7 @@ G it "fails if engine doesn't match", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" #{engine_incorrect} @@ -672,7 +672,7 @@ G it "fails if engine version doesn't match", bundler: "< 3", jruby_only: true do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" #{engine_version_incorrect} @@ -684,8 +684,8 @@ G it "fails when patchlevel doesn't match", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G @@ -701,39 +701,39 @@ G context "bundle cache" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G end it "copies the .gem file to vendor/cache when ruby version matches" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{ruby_version_correct} G bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end it "copies the .gem file to vendor/cache when ruby version matches for any engine", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{ruby_version_correct_engineless} G bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end it "fails if the ruby version doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{ruby_version_incorrect} G @@ -744,8 +744,8 @@ G it "fails if the engine doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{engine_incorrect} G @@ -756,8 +756,8 @@ G it "fails if the engine version doesn't match", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{engine_version_incorrect} G @@ -768,8 +768,8 @@ G it "fails when patchlevel doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G @@ -782,39 +782,39 @@ G context "bundle pack" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G end it "copies the .gem file to vendor/cache when ruby version matches" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{ruby_version_correct} G bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end it "copies the .gem file to vendor/cache when ruby version matches any engine", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{ruby_version_correct_engineless} G bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist end it "fails if the ruby version doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{ruby_version_incorrect} G @@ -825,8 +825,8 @@ G it "fails if the engine doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{engine_incorrect} G @@ -837,8 +837,8 @@ G it "fails if the engine version doesn't match", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' #{engine_version_incorrect} G @@ -849,8 +849,8 @@ G it "fails when patchlevel doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G @@ -863,78 +863,78 @@ G context "bundle exec" do before do ENV["BUNDLER_FORCE_TTY"] = "true" - system_gems "rack-1.0.0", "rack-0.9.1", path: default_bundle_path + system_gems "myrack-1.0.0", "myrack-0.9.1", path: default_bundle_path end it "activates the correct gem when ruby version matches" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" #{ruby_version_correct} G - bundle "exec rackup" + bundle "exec myrackup" expect(out).to include("0.9.1") end it "activates the correct gem when ruby version matches any engine", :jruby_only do - system_gems "rack-1.0.0", "rack-0.9.1", path: default_bundle_path + system_gems "myrack-1.0.0", "myrack-0.9.1", path: default_bundle_path gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" #{ruby_version_correct_engineless} G - bundle "exec rackup" + bundle "exec myrackup" expect(out).to include("0.9.1") end it "fails when the ruby version doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" #{ruby_version_incorrect} G - bundle "exec rackup", raise_on_error: false + bundle "exec myrackup", raise_on_error: false should_be_ruby_version_incorrect end it "fails when the engine doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" #{engine_incorrect} G - bundle "exec rackup", raise_on_error: false + bundle "exec myrackup", raise_on_error: false should_be_engine_incorrect end - # it "fails when the engine version doesn't match", :jruby_only do - # gemfile <<-G - # gem "rack", "0.9.1" - # - # #{engine_version_incorrect} - # G - # - # bundle "exec rackup" - # should_be_engine_version_incorrect - # end + it "fails when the engine version doesn't match", :jruby_only do + gemfile <<-G + gem "myrack", "0.9.1" + + #{engine_version_incorrect} + G + + bundle "exec myrackup", raise_on_error: false + should_be_engine_version_incorrect + end it "fails when patchlevel doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" #{patchlevel_incorrect} G - bundle "exec rackup", raise_on_error: false + bundle "exec myrackup", raise_on_error: false should_be_patchlevel_incorrect end end @@ -942,25 +942,25 @@ G context "bundle console", bundler: "< 3" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development G end it "starts IRB with the default group loaded when ruby version matches", :readline do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development #{ruby_version_correct} G bundle "console" do |input, _, _| - input.puts("puts RACK") + input.puts("puts MYRACK") input.puts("exit") end expect(out).to include("0.9.1") @@ -968,16 +968,16 @@ G it "starts IRB with the default group loaded when ruby version matches", :readline, :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development #{ruby_version_correct_engineless} G bundle "console" do |input, _, _| - input.puts("puts RACK") + input.puts("puts MYRACK") input.puts("exit") end expect(out).to include("0.9.1") @@ -985,10 +985,10 @@ G it "fails when ruby version doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development #{ruby_version_incorrect} G @@ -999,10 +999,10 @@ G it "fails when engine doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development #{engine_incorrect} G @@ -1013,10 +1013,10 @@ G it "fails when engine version doesn't match", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development #{engine_version_incorrect} G @@ -1027,10 +1027,10 @@ G it "fails when patchlevel doesn't match" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test - gem "rack_middleware", :group => :development + gem "myrack_middleware", :group => :development #{patchlevel_incorrect} G @@ -1043,9 +1043,9 @@ G context "Bundler.setup" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack", :group => :test + gem "myrack", :group => :test G ENV["BUNDLER_FORCE_TTY"] = "true" @@ -1053,9 +1053,9 @@ G it "makes a Gemfile.lock if setup succeeds" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack" + gem "myrack" #{ruby_version_correct} G @@ -1068,9 +1068,9 @@ G it "makes a Gemfile.lock if setup succeeds for any engine", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack" + gem "myrack" #{ruby_version_correct_engineless} G @@ -1083,9 +1083,9 @@ G it "fails when ruby version doesn't match" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack" + gem "myrack" #{ruby_version_incorrect} G @@ -1100,9 +1100,9 @@ G it "fails when engine doesn't match" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack" + gem "myrack" #{engine_incorrect} G @@ -1117,9 +1117,9 @@ G it "fails when engine version doesn't match", :jruby_only do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack" + gem "myrack" #{engine_version_incorrect} G @@ -1134,9 +1134,9 @@ G it "fails when patchlevel doesn't match" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack" + gem "myrack" #{patchlevel_incorrect} G @@ -1157,7 +1157,7 @@ G end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" G @@ -1170,7 +1170,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" @@ -1196,7 +1196,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" @@ -1221,7 +1221,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" @@ -1239,7 +1239,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" @@ -1257,7 +1257,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" @@ -1275,7 +1275,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" @@ -1293,7 +1293,7 @@ G end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", "2.3.5" gem "foo", :git => "#{lib_path("foo")}" diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb index 07fd5a79e9..8671504b25 100644 --- a/spec/bundler/commands/post_bundle_message_spec.rb +++ b/spec/bundler/commands/post_bundle_message_spec.rb @@ -3,13 +3,13 @@ RSpec.describe "post bundle message" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", "2.3.5", :group => [:emo, :test] group :test do gem "rspec" end - gem "rack-obama", :group => :obama + gem "myrack-obama", :group => :obama G end @@ -115,25 +115,25 @@ RSpec.describe "post bundle message" do it "should report a helpful error message" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "not-a-gem", :group => :development G expect(err).to include <<-EOS.strip -Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}/, cached gems or installed locally. +Could not find gem 'not-a-gem' in rubygems repository https://gem.repo1/ or installed locally. EOS end it "should report a helpful error message with reference to cache if available" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle :cache - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "not-a-gem", :group => :development G expect(err).to include("Could not find gem 'not-a-gem' in"). diff --git a/spec/bundler/commands/pristine_spec.rb b/spec/bundler/commands/pristine_spec.rb index 1aec37f850..547aa12b6c 100644 --- a/spec/bundler/commands/pristine_spec.rb +++ b/spec/bundler/commands/pristine_spec.rb @@ -19,7 +19,7 @@ RSpec.describe "bundle pristine" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "weakling" gem "very_simple_binary" gem "foo", :git => "#{lib_path("foo")}", :branch => "main" diff --git a/spec/bundler/commands/remove_spec.rb b/spec/bundler/commands/remove_spec.rb index 197fcde091..7ac2ea9b26 100644 --- a/spec/bundler/commands/remove_spec.rb +++ b/spec/bundler/commands/remove_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "bundle remove" do context "when no gems are specified" do it "throws error" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G bundle "remove", raise_on_error: false @@ -16,29 +16,29 @@ RSpec.describe "bundle remove" do context "after 'bundle install' is run" do describe "running 'bundle remove GEM_NAME'" do it "removes it from the lockfile" do - rack_dep = <<~L + myrack_dep = <<~L DEPENDENCIES - rack + myrack L gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G bundle "install" - expect(lockfile).to include(rack_dep) + expect(lockfile).to include(myrack_dep) - bundle "remove rack" + bundle "remove myrack" expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G - expect(lockfile).to_not include(rack_dep) + expect(lockfile).to_not include(myrack_dep) end end end @@ -46,15 +46,15 @@ RSpec.describe "bundle remove" do context "when --install flag is specified", bundler: "< 3" do it "removes gems from .bundle" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G - bundle "remove rack --install" + bundle "remove myrack --install" - expect(out).to include("rack was removed.") - expect(the_bundle).to_not include_gems "rack" + expect(out).to include("myrack was removed.") + expect(the_bundle).to_not include_gems "myrack" end end @@ -62,39 +62,39 @@ RSpec.describe "bundle remove" do context "when gem is present in gemfile" do it "shows success for removed gem" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") - expect(the_bundle).to_not include_gems "rack" + expect(out).to include("myrack was removed.") + expect(the_bundle).to_not include_gems "myrack" expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end context "when gem is specified in multiple lines" do it "shows success for removed gem" do - build_git "rack" + build_git "myrack" gemfile <<-G - source '#{file_uri_for(gem_repo1)}' + source 'https://gem.repo1' gem 'git' - gem 'rack', - git: "#{lib_path("rack-1.0")}", + gem 'myrack', + git: "#{lib_path("myrack-1.0")}", branch: 'main' gem 'nokogiri' G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source '#{file_uri_for(gem_repo1)}' + source 'https://gem.repo1' gem 'git' gem 'nokogiri' @@ -106,12 +106,12 @@ RSpec.describe "bundle remove" do context "when gem is not present in gemfile" do it "shows warning for gem that could not be removed" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G - bundle "remove rack", raise_on_error: false + bundle "remove myrack", raise_on_error: false - expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.") + expect(err).to include("`myrack` is not specified in #{bundled_app_gemfile} so it could not be removed.") end end end @@ -120,18 +120,18 @@ RSpec.describe "bundle remove" do context "when all gems are present in gemfile" do it "shows success fir all removed gems" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" gem "rails" G - bundle "remove rack rails" + bundle "remove myrack rails" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(out).to include("rails was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -139,18 +139,18 @@ RSpec.describe "bundle remove" do context "when some gems are not present in the gemfile" do it "shows warning for those not present and success for those that can be removed" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" gem "minitest" gem "rspec" G - bundle "remove rails rack minitest", raise_on_error: false + bundle "remove rails myrack minitest", raise_on_error: false - expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.") + expect(err).to include("`myrack` is not specified in #{bundled_app_gemfile} so it could not be removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" gem "minitest" @@ -163,16 +163,16 @@ RSpec.describe "bundle remove" do context "with inline groups" do it "removes the specified gem" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", :group => [:dev] + gem "myrack", :group => [:dev] G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -181,7 +181,7 @@ RSpec.describe "bundle remove" do context "when single group block with gem to be removed is present" do it "removes the group block" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do gem "rspec" @@ -192,7 +192,7 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -200,19 +200,19 @@ RSpec.describe "bundle remove" do context "when gem to be removed is outside block" do it "does not modify group" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" group :test do gem "coffee-script-source" end G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do gem "coffee-script-source" @@ -224,7 +224,7 @@ RSpec.describe "bundle remove" do context "when an empty block is also present" do it "removes all empty blocks" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do gem "rspec" @@ -238,7 +238,7 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -246,7 +246,7 @@ RSpec.describe "bundle remove" do context "when the gem belongs to multiple groups" do it "removes the groups" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test, :serioustest do gem "rspec" @@ -257,7 +257,7 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -265,7 +265,7 @@ RSpec.describe "bundle remove" do context "when the gem is present in multiple groups" do it "removes all empty blocks" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :one do gem "rspec" @@ -280,7 +280,7 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -290,7 +290,7 @@ RSpec.describe "bundle remove" do context "when all the groups will be empty after removal" do it "removes the empty nested blocks" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do group :serioustest do @@ -303,7 +303,7 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -311,10 +311,10 @@ RSpec.describe "bundle remove" do context "when outer group will not be empty after removal" do it "removes only empty blocks" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do - gem "rack-test" + gem "myrack-test" group :serioustest do gem "rspec" @@ -326,10 +326,10 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do - gem "rack-test" + gem "myrack-test" end G @@ -339,12 +339,12 @@ RSpec.describe "bundle remove" do context "when inner group will not be empty after removal" do it "removes only empty blocks" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do group :serioustest do gem "rspec" - gem "rack-test" + gem "myrack-test" end end G @@ -353,11 +353,11 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do group :serioustest do - gem "rack-test" + gem "myrack-test" end end G @@ -369,16 +369,16 @@ RSpec.describe "bundle remove" do context "when multiple gems are present in same line" do it "shows warning for gems not removed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack"; gem "rails" + source "https://gem.repo1" + gem "myrack"; gem "rails" G bundle "remove rails", raise_on_error: false - expect(err).to include("Gems could not be removed. rack (>= 0) would also have been removed.") + expect(err).to include("Gems could not be removed. myrack (>= 0) would also have been removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" - gem "rack"; gem "rails" + source "https://gem.repo1" + gem "myrack"; gem "rails" G end end @@ -386,21 +386,21 @@ RSpec.describe "bundle remove" do context "when some gems could not be removed" do it "shows warning for gems not removed and success for those removed" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - gem"rack" + source "https://gem.repo1" + gem"myrack" gem"rspec" gem "rails" gem "minitest" G - bundle "remove rails rack rspec minitest" + bundle "remove rails myrack rspec minitest" expect(out).to include("rails was removed.") expect(out).to include("minitest was removed.") - expect(out).to include("rack, rspec could not be removed.") + expect(out).to include("myrack, rspec could not be removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" - gem"rack" + source "https://gem.repo1" + gem"myrack" gem"rspec" G end @@ -409,18 +409,18 @@ RSpec.describe "bundle remove" do context "with sources" do before do - build_repo gem_repo3 do + build_repo3 do build_gem "rspec" end end it "removes gems and empty source blocks" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" - source "#{file_uri_for(gem_repo3)}" do + source "https://gem.repo3" do gem "rspec" end G @@ -431,9 +431,9 @@ RSpec.describe "bundle remove" do expect(out).to include("rspec was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G end end @@ -441,40 +441,40 @@ RSpec.describe "bundle remove" do describe "with eval_gemfile" do context "when gems are present in both gemfiles" do it "removes the gems" do - create_file "Gemfile-other", <<-G - gem "rack" + gemfile "Gemfile-other", <<-G + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" - gem "rack" + gem "myrack" G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") end end context "when gems are present in other gemfile" do it "removes the gems" do - create_file "Gemfile-other", <<-G - gem "rack" + gemfile "Gemfile-other", <<-G + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" G - bundle "remove rack" + bundle "remove myrack" - expect(bundled_app("Gemfile-other").read).to_not include("gem \"rack\"") - expect(out).to include("rack was removed.") + expect(bundled_app("Gemfile-other").read).to_not include("gem \"myrack\"") + expect(out).to include("myrack was removed.") end end @@ -486,36 +486,36 @@ RSpec.describe "bundle remove" do G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" G - bundle "remove rack", raise_on_error: false + bundle "remove myrack", raise_on_error: false - expect(err).to include("`rack` is not specified in #{bundled_app_gemfile} so it could not be removed.") + expect(err).to include("`myrack` is not specified in #{bundled_app_gemfile} so it could not be removed.") end end context "when the gem is present in parent file but not in gemfile specified by eval_gemfile" do it "removes the gem" do - create_file "Gemfile-other", <<-G + gemfile "Gemfile-other", <<-G gem "rails" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" - gem "rack" + gem "myrack" G - bundle "remove rack", raise_on_error: false + bundle "remove myrack", raise_on_error: false - expect(out).to include("rack was removed.") - expect(err).to include("`rack` is not specified in #{bundled_app("Gemfile-other")} so it could not be removed.") + expect(out).to include("myrack was removed.") + expect(err).to include("`myrack` is not specified in #{bundled_app("Gemfile-other")} so it could not be removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" G @@ -524,23 +524,23 @@ RSpec.describe "bundle remove" do context "when gems cannot be removed from other gemfile" do it "shows error" do - create_file "Gemfile-other", <<-G - gem "rails"; gem "rack" + gemfile "Gemfile-other", <<-G + gem "rails"; gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" - gem "rack" + gem "myrack" G - bundle "remove rack", raise_on_error: false + bundle "remove myrack", raise_on_error: false - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" G @@ -549,47 +549,47 @@ RSpec.describe "bundle remove" do context "when gems could not be removed from parent gemfile" do it "shows error" do - create_file "Gemfile-other", <<-G - gem "rack" + gemfile "Gemfile-other", <<-G + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" - gem "rails"; gem "rack" + gem "rails"; gem "myrack" G - bundle "remove rack", raise_on_error: false + bundle "remove myrack", raise_on_error: false expect(err).to include("Gems could not be removed. rails (>= 0) would also have been removed.") - expect(bundled_app("Gemfile-other").read).to include("gem \"rack\"") + expect(bundled_app("Gemfile-other").read).to include("gem \"myrack\"") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" - gem "rails"; gem "rack" + gem "rails"; gem "myrack" G end end context "when gem present in gemfiles but could not be removed from one from one of them" do it "removes gem which can be removed and shows warning for file from which it cannot be removed" do - create_file "Gemfile-other", <<-G - gem "rack" + gemfile "Gemfile-other", <<-G + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "Gemfile-other" - gem"rack" + gem"myrack" G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") - expect(bundled_app("Gemfile-other").read).to_not include("gem \"rack\"") + expect(out).to include("myrack was removed.") + expect(bundled_app("Gemfile-other").read).to_not include("gem \"myrack\"") end end end @@ -597,18 +597,18 @@ RSpec.describe "bundle remove" do context "with install_if" do it "removes gems inside blocks and empty blocks" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" install_if(lambda { false }) do - gem "rack" + gem "myrack" end G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -616,32 +616,32 @@ RSpec.describe "bundle remove" do context "with env" do it "removes gems inside blocks and empty blocks" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" env "BUNDLER_TEST" do - gem "rack" + gem "myrack" end G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end context "with gemspec" do it "should not remove the gem" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("foo.gemspec", "") - s.add_dependency "rack" + s.add_dependency "myrack" end install_gemfile(<<-G) - source "#{file_uri_for(gem_repo1)}" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo' + source "https://gem.repo1" + gemspec :path => '#{tmp("foo")}', :name => 'foo' G bundle "remove foo" @@ -654,19 +654,19 @@ RSpec.describe "bundle remove" do context "when comment is a separate line comment" do it "does not remove the line comment" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - # gem "rack" might be used in the future - gem "rack" + # gem "myrack" might be used in the future + gem "myrack" G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - # gem "rack" might be used in the future + # gem "myrack" might be used in the future G end end @@ -674,16 +674,16 @@ RSpec.describe "bundle remove" do context "when gem specified for removal has an inline comment" do it "removes the inline comment" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" # this can be removed + gem "myrack" # this can be removed G - bundle "remove rack" + bundle "remove myrack" - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end end @@ -691,19 +691,19 @@ RSpec.describe "bundle remove" do context "when gem specified for removal is mentioned in other gem's comment" do it "does not remove other gem" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "puma" # implements interface provided by gem "rack" + source "https://gem.repo1" + gem "puma" # implements interface provided by gem "myrack" - gem "rack" + gem "myrack" G - bundle "remove rack" + bundle "remove myrack" expect(out).to_not include("puma was removed.") - expect(out).to include("rack was removed.") + expect(out).to include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" - gem "puma" # implements interface provided by gem "rack" + source "https://gem.repo1" + gem "puma" # implements interface provided by gem "myrack" G end end @@ -711,20 +711,20 @@ RSpec.describe "bundle remove" do context "when gem specified for removal has a comment that mentions other gem" do it "does not remove other gem" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "puma" # implements interface provided by gem "rack" + source "https://gem.repo1" + gem "puma" # implements interface provided by gem "myrack" - gem "rack" + gem "myrack" G bundle "remove puma" expect(out).to include("puma was removed.") - expect(out).to_not include("rack was removed.") + expect(out).to_not include("myrack was removed.") expect(gemfile).to eq <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G end end diff --git a/spec/bundler/commands/show_spec.rb b/spec/bundler/commands/show_spec.rb index 2b6d4d2d00..7f32d0563b 100644 --- a/spec/bundler/commands/show_spec.rb +++ b/spec/bundler/commands/show_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "bundle show", bundler: "< 3" do context "with a standard Gemfile" do before :each do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G end @@ -155,7 +155,7 @@ RSpec.describe "bundle show", bundler: "< 3" do it "performs an automatic bundle install" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo" G @@ -167,20 +167,20 @@ RSpec.describe "bundle show", bundler: "< 3" do context "with a valid regexp for gem name" do it "presents alternatives", :readline do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G bundle "show rac" - expect(out).to match(/\A1 : rack\n2 : rack-obama\n0 : - exit -(\n>.*)?\z/) + expect(out).to match(/\A1 : myrack\n2 : myrack-obama\n0 : - exit -(\n>|\z)/) end end context "with an invalid regexp for gem name" do it "does not find the gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -199,7 +199,7 @@ RSpec.describe "bundle show", bundler: "< 3" do it "doesn't update gems to newer versions" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" G diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb index 8565e27ebf..1683827636 100644 --- a/spec/bundler/commands/update_spec.rb +++ b/spec/bundler/commands/update_spec.rb @@ -6,17 +6,17 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end it "updates the entire bundle" do update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" @@ -24,14 +24,14 @@ RSpec.describe "bundle update" do bundle "update" expect(out).to include("Bundle updated!") - expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0" + expect(the_bundle).to include_gems "myrack 1.2", "myrack-obama 1.0", "activesupport 3.0" end it "doesn't delete the Gemfile.lock file if something goes wrong" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" exit! G bundle "update", raise_on_error: false @@ -44,17 +44,17 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end it "updates the entire bundle" do update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" @@ -62,16 +62,16 @@ RSpec.describe "bundle update" do bundle "update", all: true expect(out).to include("Bundle updated!") - expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 3.0" + expect(the_bundle).to include_gems "myrack 1.2", "myrack-obama 1.0", "activesupport 3.0" end it "doesn't delete the Gemfile.lock file if something goes wrong" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" exit! G bundle "update", all: true, raise_on_error: false @@ -82,8 +82,8 @@ RSpec.describe "bundle update" do describe "with --gemfile" do it "creates lock files based on the Gemfile name" do gemfile bundled_app("OmgFile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0" + source "https://gem.repo1" + gem "myrack", "1.0" G bundle "update --gemfile OmgFile", all: true @@ -96,19 +96,19 @@ RSpec.describe "bundle update" do before { bundle "config set update_requires_all_flag true" } it "errors when passed nothing" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" bundle :update, raise_on_error: false expect(err).to eq("To update everything, pass the `--all` flag.") end it "errors when passed --all and another option" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" bundle "update --all foo", raise_on_error: false expect(err).to eq("Cannot specify --all along with specific options.") end it "updates everything when passed --all" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" bundle "update --all" expect(out).to include("Bundle updated!") end @@ -119,9 +119,9 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end @@ -137,24 +137,24 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end it "unlocks all child dependencies that are unrelated to other locked dependencies" do update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" end - bundle "update rack-obama" - expect(the_bundle).to include_gems "rack 1.2", "rack-obama 1.0", "activesupport 2.3.5" + bundle "update myrack-obama" + expect(the_bundle).to include_gems "myrack 1.2", "myrack-obama 1.0", "activesupport 2.3.5" end end @@ -163,9 +163,9 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end @@ -185,22 +185,22 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end it "should update the child dependency" do update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end end - bundle "update rack" - expect(the_bundle).to include_gems "rack 1.2" + bundle "update myrack" + expect(the_bundle).to include_gems "myrack 1.2" end end @@ -223,7 +223,7 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "slim-rails" gem "slim_lint" G @@ -269,20 +269,20 @@ RSpec.describe "bundle update" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "country_select" gem "countries" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum(gem_repo4, "countries", "3.1.0") c.checksum(gem_repo4, "country_select", "5.1.0") end lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: countries (3.1.0) country_select (5.1.0) @@ -331,7 +331,7 @@ RSpec.describe "bundle update" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "oauth2" gem "quickbooks-ruby" @@ -339,7 +339,7 @@ RSpec.describe "bundle update" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: faraday (2.5.2) multi_json (1.15.0) @@ -390,7 +390,7 @@ RSpec.describe "bundle update" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec @@ -404,7 +404,7 @@ RSpec.describe "bundle update" do specs: GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: rake (13.0.6) sneakers (2.11.0) @@ -440,7 +440,7 @@ RSpec.describe "bundle update" do end install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "a" G @@ -464,7 +464,7 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "a" gem "b" G @@ -472,7 +472,7 @@ RSpec.describe "bundle update" do expect(the_bundle).to include_gems("a 1.0", "b 2.0") gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "a" gem "b", "1.0" G @@ -497,27 +497,27 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "activesupport", "~> 6.1.0" G expect(the_bundle).to include_gems("activesupport 6.1.4.1", "tzinfo 2.0.4") gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "activesupport", "~> 6.0.0" G original_lockfile = lockfile - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "activesupport", "6.0.4.1" c.checksum gem_repo4, "tzinfo", "1.2.9" end expected_lockfile = <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: activesupport (6.0.4.1) tzinfo (~> 1.1) @@ -537,10 +537,6 @@ RSpec.describe "bundle update" do expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9") expect(lockfile).to eq(expected_lockfile) - # needed because regressing to versions already present on the system - # won't add a checksum - expected_lockfile = remove_checksums_from_lockfile(expected_lockfile) - lockfile original_lockfile bundle "update" expect(the_bundle).to include_gems("activesupport 6.0.4.1", "tzinfo 1.2.9") @@ -558,42 +554,44 @@ RSpec.describe "bundle update" do build_repo2 gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G - - lockfile <<~L - GEM - remote: #{file_uri_for(gem_repo2)}/ - specs: - activesupport (2.3.5) - platform_specific (1.0-#{local_platform}) - rack (1.0.0) - rack-obama (1.0) - rack - - PLATFORMS - #{local_platform} - - DEPENDENCIES - activesupport - platform_specific - rack-obama - - BUNDLED WITH - #{Bundler::VERSION} - L - - bundle "install" end it "doesn't hit repo2" do - FileUtils.rm_rf(gem_repo2) - - bundle "update --local --all" - expect(out).not_to include("Fetching source index") + simulate_platform "x86-darwin-100" do + lockfile <<~L + GEM + remote: https://gem.repo2/ + specs: + activesupport (2.3.5) + platform_specific (1.0-x86-darwin-100) + myrack (1.0.0) + myrack-obama (1.0) + myrack + + PLATFORMS + #{local_platform} + + DEPENDENCIES + activesupport + platform_specific + myrack-obama + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "install" + + FileUtils.rm_rf(gem_repo2) + + bundle "update --local --all" + expect(out).not_to include("Fetching source index") + end end end @@ -604,26 +602,26 @@ RSpec.describe "bundle update" do it "should update only specified group gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", :group => :development - gem "rack" + gem "myrack" G update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" end bundle "update --group development" expect(the_bundle).to include_gems "activesupport 3.0" - expect(the_bundle).not_to include_gems "rack 1.2" + expect(the_bundle).not_to include_gems "myrack 1.2" end context "when conservatively updating a group with non-group sub-deps" do it "should update only specified group gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activemerchant", :group => :development gem "activesupport" G @@ -641,7 +639,7 @@ RSpec.describe "bundle update" do before do build_git "foo", path: lib_path("activesupport") install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport", :group => :development gem "foo", :git => "#{lib_path("activesupport")}" G @@ -660,13 +658,13 @@ RSpec.describe "bundle update" do context "when bundler itself is a transitive dependency" do it "executes without error" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", :group => :development - gem "rack" + gem "myrack" G update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "activesupport", "3.0" @@ -674,7 +672,7 @@ RSpec.describe "bundle update" do bundle "update --group development" expect(the_bundle).to include_gems "activesupport 2.3.5" expect(the_bundle).to include_gems "bundler #{Bundler::VERSION}" - expect(the_bundle).not_to include_gems "rack 1.2" + expect(the_bundle).not_to include_gems "myrack 1.2" end end end @@ -684,9 +682,9 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" - gem "rack-obama" + gem "myrack-obama" gem "platform_specific" G end @@ -728,7 +726,7 @@ RSpec.describe "bundle update" do it "should not update gems not included in the source that happen to have the same name" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" G update_repo2 { build_gem "activesupport", "3.0" } @@ -739,7 +737,7 @@ RSpec.describe "bundle update" do it "should not update gems not included in the source that happen to have the same name" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" G update_repo2 { build_gem "activesupport", "3.0" } @@ -759,7 +757,7 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "harry" gem "fred" G @@ -791,7 +789,7 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "harry" gem "fred" G @@ -814,7 +812,7 @@ RSpec.describe "bundle update" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" G @@ -836,7 +834,7 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "bar" gem "foo" G @@ -849,13 +847,12 @@ RSpec.describe "bundle update" do end bundle "update", all: true - out.sub!("Removing foo (1.0)\n", "") - expect(out).to match(/Resolving dependencies\.\.\.\.*\nFetching foo 2\.0 \(was 1\.0\)\nInstalling foo 2\.0 \(was 1\.0\)\nBundle updated/) + expect(out.sub("Removing foo (1.0)\n", "")).to match(/Resolving dependencies\.\.\.\.*\nFetching foo 2\.0 \(was 1\.0\)\nInstalling foo 2\.0 \(was 1\.0\)\nBundle updated/) end it "shows error message when Gemfile.lock is not preset and gem is specified" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" G @@ -867,10 +864,10 @@ RSpec.describe "bundle update" do context "with multiple sources and caching enabled" do before do build_repo2 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" build_gem "request_store", "1.0.0" do |s| - s.add_dependency "rack", "1.0.0" + s.add_dependency "myrack", "1.0.0" end end @@ -879,24 +876,24 @@ RSpec.describe "bundle update" do end gemfile <<~G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "request_store" - source "#{file_uri_for(gem_repo4)}" do + source "https://gem.repo4" do end G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) request_store (1.0.0) - rack (= 1.0.0) + myrack (= 1.0.0) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: PLATFORMS @@ -916,7 +913,7 @@ RSpec.describe "bundle update" do update_repo2 do build_gem "request_store", "1.1.0" do |s| - s.add_dependency "rack", "1.0.0" + s.add_dependency "myrack", "1.0.0" end end @@ -926,14 +923,14 @@ RSpec.describe "bundle update" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) request_store (1.1.0) - rack (= 1.0.0) + myrack (= 1.0.0) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: PLATFORMS @@ -959,7 +956,7 @@ RSpec.describe "bundle update" do build_gem "vcr", "6.0.0" end - build_repo gem_repo3 do + build_repo3 do build_gem "pkg-gem-flowbyte-with-dep", "1.0.0" do |s| s.add_dependency "oj" end @@ -1018,49 +1015,49 @@ RSpec.describe "bundle update in more complicated situations" do it "will eagerly unlock dependencies of a specified gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "thin" - gem "rack-obama" + gem "myrack-obama" G update_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "thin", "2.0" do |s| - s.add_dependency "rack" + s.add_dependency "myrack" end end bundle "update thin" - expect(the_bundle).to include_gems "thin 2.0", "rack 1.2", "rack-obama 1.0" + expect(the_bundle).to include_gems "thin 2.0", "myrack 1.2", "myrack-obama 1.0" end it "will warn when some explicitly updated gems are not updated" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "thin" - gem "rack-obama" + gem "myrack-obama" G update_repo2 do - build_gem("thin", "2.0") {|s| s.add_dependency "rack" } - build_gem "rack", "10.0" + build_gem("thin", "2.0") {|s| s.add_dependency "myrack" } + build_gem "myrack", "10.0" end - bundle "update thin rack-obama" - expect(last_command.stdboth).to include "Bundler attempted to update rack-obama but its version stayed the same" - expect(the_bundle).to include_gems "thin 2.0", "rack 10.0", "rack-obama 1.0" + bundle "update thin myrack-obama" + expect(last_command.stdboth).to include "Bundler attempted to update myrack-obama but its version stayed the same" + expect(the_bundle).to include_gems "thin 2.0", "myrack 10.0", "myrack-obama 1.0" end it "will not warn when an explicitly updated git gem changes sha but not version" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => '#{lib_path("foo-1.0")}' G @@ -1074,28 +1071,28 @@ RSpec.describe "bundle update in more complicated situations" do end it "will not warn when changing gem sources but not versions" do - build_git "rack" + build_git "myrack" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", :git => '#{lib_path("rack-1.0")}' + source "https://gem.repo2" + gem "myrack", :git => '#{lib_path("myrack-1.0")}' G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "update rack" + bundle "update myrack" expect(last_command.stdboth).not_to include "attempted to update" end it "will update only from pinned source" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - source "#{file_uri_for(gem_repo1)}" do + source "https://gem.repo1" do gem "thin" end G @@ -1104,12 +1101,12 @@ RSpec.describe "bundle update in more complicated situations" do build_gem "thin", "2.0" end - bundle "update" + bundle "update", artifice: "compact_index" expect(the_bundle).to include_gems "thin 1.0" end context "when the lockfile is for a different platform" do - before do + around do |example| build_repo4 do build_gem("a", "0.9") build_gem("a", "0.9") {|s| s.platform = "java" } @@ -1118,13 +1115,13 @@ RSpec.describe "bundle update in more complicated situations" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "a" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: a (0.9-java) @@ -1135,7 +1132,7 @@ RSpec.describe "bundle update in more complicated situations" do a L - simulate_platform linux + simulate_platform linux, &example end it "allows updating" do @@ -1157,13 +1154,13 @@ RSpec.describe "bundle update in more complicated situations" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "a", platform: :jruby G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: a (0.9-java) @@ -1173,14 +1170,14 @@ RSpec.describe "bundle update in more complicated situations" do DEPENDENCIES a L - - simulate_platform linux end it "is not updated because it is not actually included in the bundle" do - bundle "update a" - expect(last_command.stdboth).to include "Bundler attempted to update a but it was not considered because it is for a different platform from the current one" - expect(the_bundle).to_not include_gem "a" + simulate_platform linux do + bundle "update a" + expect(last_command.stdboth).to include "Bundler attempted to update a but it was not considered because it is for a different platform from the current one" + expect(the_bundle).to_not include_gem "a" + end end end end @@ -1190,14 +1187,14 @@ RSpec.describe "bundle update without a Gemfile.lock" do build_repo2 gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack", "1.0" + gem "myrack", "1.0" G bundle "update", all: true - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end @@ -1205,14 +1202,14 @@ RSpec.describe "bundle update when a gem depends on a newer version of bundler" before do build_repo2 do build_gem "rails", "3.0.1" do |s| - s.add_dependency "bundler", Bundler::VERSION.succ + s.add_dependency "bundler", "9.9.9" end - build_gem "bundler", Bundler::VERSION.succ + build_gem "bundler", "9.9.9" end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0.1" G end @@ -1221,7 +1218,7 @@ RSpec.describe "bundle update when a gem depends on a newer version of bundler" bundle "update", all: true, raise_on_error: false expect(last_command.stdboth).not_to match(/in snapshot/i) expect(err).to match(/current Bundler version/i). - and match(/Install the necessary version with `gem install bundler:#{Bundler::VERSION.succ}`/i) + and match(/Install the necessary version with `gem install bundler:9\.9\.9`/i) end end @@ -1230,11 +1227,11 @@ RSpec.describe "bundle update --ruby" do before do install_gemfile <<-G ruby '~> #{Gem.ruby_version}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end @@ -1243,14 +1240,14 @@ RSpec.describe "bundle update --ruby" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS #{lockfile_platforms} DEPENDENCIES - + #{checksums_section_when_enabled} BUNDLED WITH #{Bundler::VERSION} L @@ -1261,12 +1258,12 @@ RSpec.describe "bundle update --ruby" do before do install_gemfile <<-G ruby '~> #{Gem.ruby_version}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G gemfile <<-G ruby '~> #{current_ruby_minor}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end @@ -1275,14 +1272,14 @@ RSpec.describe "bundle update --ruby" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS #{lockfile_platforms} DEPENDENCIES - + #{checksums_section_when_enabled} RUBY VERSION #{Bundler::RubyVersion.system} @@ -1296,12 +1293,12 @@ RSpec.describe "bundle update --ruby" do before do install_gemfile <<-G ruby '~> #{Gem.ruby_version}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G gemfile <<-G ruby '~> 2.1.0' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end it "shows a helpful error message" do @@ -1315,7 +1312,7 @@ RSpec.describe "bundle update --ruby" do before do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -1334,7 +1331,7 @@ RSpec.describe "bundle update --ruby" do gemfile <<-G ruby '~> #{Gem.ruby_version}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G end @@ -1343,7 +1340,7 @@ RSpec.describe "bundle update --ruby" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -1366,143 +1363,143 @@ end RSpec.describe "bundle update --bundler" do it "updates the bundler version in the lockfile" do build_repo4 do - build_gem "rack", "1.0" + build_gem "bundler", "2.5.9" + build_gem "myrack", "1.0" end - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo4, "rack", "1.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo4, "myrack", "1.0") end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" G expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} L lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, '\11.0.0\2') - bundle :update, bundler: true, artifice: "compact_index", verbose: true + bundle :update, bundler: true, verbose: true expect(out).to include("Using bundler #{Bundler::VERSION}") expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} L - expect(the_bundle).to include_gem "rack 1.0" + expect(the_bundle).to include_gem "myrack 1.0" end it "updates the bundler version in the lockfile without re-resolving if the highest version is already installed" do - system_gems "bundler-2.3.9" - build_repo4 do - build_gem "rack", "1.0" + build_gem "bundler", "2.3.9" + build_gem "myrack", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" G lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo4, "rack", "1.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo4, "myrack", "1.0") end - bundle :update, bundler: true, artifice: "compact_index", verbose: true + bundle :update, bundler: true, verbose: true expect(out).to include("Using bundler #{Bundler::VERSION}") expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} L - expect(the_bundle).to include_gem "rack 1.0" + expect(the_bundle).to include_gem "myrack 1.0" end it "updates the bundler version in the lockfile even if the latest version is not installed", :ruby_repo do - pristine_system_gems "bundler-2.3.9" + pristine_system_gems "bundler-2.99.9" build_repo4 do - build_gem "rack", "1.0" + build_gem "myrack", "1.0" build_bundler "999.0.0" end - install_gemfile <<-G, artifice: nil, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } - source "#{file_uri_for(gem_repo4)}" - gem "rack" + install_gemfile <<-G + source "https://gem.repo4" + gem "myrack" G - lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") + lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.99.9") - bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle :update, bundler: true, verbose: true, preserve_ruby_flags: true # Only updates properly on modern RubyGems. if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev") expect(out).to include("Updating bundler to 999.0.0") - expect(out).to include("Using bundler 999.0.0") - expect(out).not_to include("Installing Bundler 2.3.9 and restarting using that version.") + expect(out).to include("Running `bundle update --bundler \"> 0.a\" --verbose` with bundler 999.0.0") + expect(out).not_to include("Installing Bundler 2.99.9 and restarting using that version.") expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH 999.0.0 L expect(the_bundle).to include_gems "bundler 999.0.0" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" else # Old RubyGems versions do not trampoline but they still change BUNDLED # WITH to the latest bundler version. This means the below check fails # because it tries to use bundler 999.0.0 which did not get installed. # Workaround the bug by forcing the version we know is installed. - expect(the_bundle).to include_gems "rack 1.0", env: { "BUNDLER_VERSION" => "2.3.9" } + expect(the_bundle).to include_gems "myrack 1.0", env: { "BUNDLER_VERSION" => "2.99.9" } end end @@ -1510,27 +1507,27 @@ RSpec.describe "bundle update --bundler" do pristine_system_gems "bundler-2.99.0" build_repo4 do - build_gem "rack", "3.0.9.1" + build_gem "myrack", "3.0.9.1" build_bundler "2.99.0" end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (3.0.9.1) + myrack (3.0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH 2.99.0 @@ -1538,73 +1535,75 @@ RSpec.describe "bundle update --bundler" do bundle :cache, verbose: true - bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle :update, bundler: true, verbose: true expect(out).not_to include("Updating bundler to") end it "does not update the bundler version in the lockfile if the latest version is not compatible with current ruby", :ruby_repo do - pristine_system_gems "bundler-2.3.9" + pristine_system_gems "bundler-9.9.9" build_repo4 do - build_gem "rack", "1.0" + build_gem "myrack", "1.0" - build_bundler "2.3.9" + build_bundler "9.9.9" build_bundler "999.0.0" do |s| s.required_ruby_version = "> #{Gem.ruby_version}" end end - install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } - source "#{file_uri_for(gem_repo4)}" - gem "rack" + checksums = checksums_section do |c| + c.checksum(gem_repo4, "myrack", "1.0") + end + + install_gemfile <<-G + source "https://gem.repo4" + gem "myrack" G - lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") - bundle :update, bundler: true, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } + bundle :update, bundler: true, verbose: true - expect(out).to include("Using bundler 2.3.9") + expect(out).to include("Using bundler 9.9.9") expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack - + myrack + #{checksums} BUNDLED WITH - 2.3.9 + 9.9.9 L - expect(the_bundle).to include_gems "bundler 2.3.9" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "bundler 9.9.9" + expect(the_bundle).to include_gems "myrack 1.0" end it "errors if the explicit target version does not exist" do - pristine_system_gems "bundler-2.3.9" + pristine_system_gems "bundler-9.9.9" build_repo4 do - build_gem "rack", "1.0" + build_gem "myrack", "1.0" end - install_gemfile <<-G, env: { "BUNDLER_IGNORE_DEFAULT_GEM" => "true" } - source "#{file_uri_for(gem_repo4)}" - gem "rack" + install_gemfile <<-G + source "https://gem.repo4" + gem "myrack" G - lockfile lockfile.sub(/(^\s*)#{Bundler::VERSION}($)/, "2.3.9") - bundle :update, bundler: "999.999.999", artifice: "compact_index", raise_on_error: false + bundle :update, bundler: "999.999.999", raise_on_error: false # Only gives a meaningful error message on modern RubyGems. if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev") expect(last_command).to be_failure - expect(err).to include("The `bundle update --bundler` target version (999.999.999) does not exist") + expect(err).to eq("The `bundle update --bundler` target version (999.999.999) does not exist") end end @@ -1612,33 +1611,33 @@ RSpec.describe "bundle update --bundler" do system_gems "bundler-2.3.0.dev" build_repo4 do - build_gem "rack", "1.0" + build_gem "myrack", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" G bundle :update, bundler: "2.3.0.dev", verbose: "true" # Only updates properly on modern RubyGems. if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev") - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo4, "rack", "1.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo4, "myrack", "1.0") end expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH 2.3.0.dev @@ -1652,12 +1651,12 @@ RSpec.describe "bundle update --bundler" do system_gems "bundler-2.3.9" build_repo4 do - build_gem "rack", "1.0" + build_gem "myrack", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" G bundle :update, bundler: "2.3.9", verbose: true @@ -1665,22 +1664,22 @@ RSpec.describe "bundle update --bundler" do expect(out).not_to include("Fetching gem metadata from https://rubygems.org/") # Only updates properly on modern RubyGems. - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo4, "rack", "1.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo4, "myrack", "1.0") end if Gem.rubygems_version >= Gem::Version.new("3.3.0.dev") expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH 2.3.9 @@ -1694,12 +1693,12 @@ RSpec.describe "bundle update --bundler" do system_gems "bundler-2.3.9" gemfile <<~G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -1739,7 +1738,7 @@ RSpec.describe "bundle update conservative" do # establish a lockfile set to 1.4.3 install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo', '1.4.3' gem 'bar', '2.0.3' gem 'qux', '1.0.0' @@ -1748,7 +1747,7 @@ RSpec.describe "bundle update conservative" do # remove 1.4.3 requirement and bar altogether # to setup update specs below gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'foo' gem 'qux' G @@ -1844,7 +1843,7 @@ RSpec.describe "bundle update conservative" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'isolated_owner' gem 'shared_owner_a' @@ -1853,7 +1852,7 @@ RSpec.describe "bundle update conservative" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: isolated_dep (2.0.1) isolated_owner (1.0.1) @@ -1906,9 +1905,17 @@ RSpec.describe "bundle update conservative" do it "should only change direct dependencies when updating the lockfile with --conservative" do bundle "lock --update --conservative" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "isolated_dep", "2.0.1" + c.checksum gem_repo4, "isolated_owner", "1.0.2" + c.checksum gem_repo4, "shared_dep", "5.0.1" + c.checksum gem_repo4, "shared_owner_a", "3.0.2" + c.checksum gem_repo4, "shared_owner_b", "4.0.2" + end + expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: isolated_dep (2.0.1) isolated_owner (1.0.2) @@ -1926,14 +1933,7 @@ RSpec.describe "bundle update conservative" do isolated_owner shared_owner_a shared_owner_b - - CHECKSUMS - isolated_dep (2.0.1) - isolated_owner (1.0.2) - shared_dep (5.0.1) - shared_owner_a (3.0.2) - shared_owner_b (4.0.2) - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -1941,7 +1941,7 @@ RSpec.describe "bundle update conservative" do it "should match bundle install conservative update behavior when not eagerly unlocking" do gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'isolated_owner', '1.0.2' gem 'shared_owner_a', '3.0.2' @@ -1969,14 +1969,14 @@ RSpec.describe "bundle update conservative" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri", ">=1.16.4" gem "prism", ">=0.25.0" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.16.4-arm64-darwin) nokogiri (1.16.4-x86_64-linux) @@ -2002,7 +2002,7 @@ RSpec.describe "bundle update conservative" do context "error handling" do before do - gemfile "source \"#{file_uri_for(gem_repo1)}\"" + gemfile "source 'https://gem.repo1'" end it "raises if too many flags are provided" do diff --git a/spec/bundler/commands/viz_spec.rb b/spec/bundler/commands/viz_spec.rb index f8b5f7836e..c26e3c81ed 100644 --- a/spec/bundler/commands/viz_spec.rb +++ b/spec/bundler/commands/viz_spec.rb @@ -7,9 +7,9 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld it "graphs gems from the Gemfile" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G bundle "viz" @@ -25,11 +25,11 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld node[ fontname = "Arial, Helvetica, SansSerif"]; edge[ fontname = "Arial, Helvetica, SansSerif" , fontsize = "12"]; default [style = "filled", fillcolor = "#B9B9D5", shape = "box3d", fontsize = "16", label = "default"]; - rack [style = "filled", fillcolor = "#B9B9D5", label = "rack"]; - default -> rack [constraint = "false"]; - "rack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "rack-obama"]; - default -> "rack-obama" [constraint = "false"]; - "rack-obama" -> rack; + myrack [style = "filled", fillcolor = "#B9B9D5", label = "myrack"]; + default -> myrack [constraint = "false"]; + "myrack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "myrack-obama"]; + default -> "myrack-obama" [constraint = "false"]; + "myrack-obama" -> myrack; } debugging bundle viz... DOT @@ -37,13 +37,13 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld it "graphs gems that are prereleases" do build_repo2 do - build_gem "rack", "1.3.pre" + build_gem "myrack", "1.3.pre" end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack", "= 1.3.pre" - gem "rack-obama" + source "https://gem.repo2" + gem "myrack", "= 1.3.pre" + gem "myrack-obama" G bundle "viz" @@ -59,11 +59,11 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld node[ fontname = "Arial, Helvetica, SansSerif"]; edge[ fontname = "Arial, Helvetica, SansSerif" , fontsize = "12"]; default [style = "filled", fillcolor = "#B9B9D5", shape = "box3d", fontsize = "16", label = "default"]; - rack [style = "filled", fillcolor = "#B9B9D5", label = "rack\\n1.3.pre"]; - default -> rack [constraint = "false"]; - "rack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "rack-obama\\n1.0"]; - default -> "rack-obama" [constraint = "false"]; - "rack-obama" -> rack; + myrack [style = "filled", fillcolor = "#B9B9D5", label = "myrack\\n1.3.pre"]; + default -> myrack [constraint = "false"]; + "myrack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "myrack-obama\\n1.0"]; + default -> "myrack-obama" [constraint = "false"]; + "myrack-obama" -> myrack; } debugging bundle viz... EOS @@ -82,9 +82,9 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld it "loads the correct ruby-graphviz gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G bundle "viz", format: "debug" @@ -97,11 +97,11 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld node[ fontname = "Arial, Helvetica, SansSerif"]; edge[ fontname = "Arial, Helvetica, SansSerif" , fontsize = "12"]; default [style = "filled", fillcolor = "#B9B9D5", shape = "box3d", fontsize = "16", label = "default"]; - rack [style = "filled", fillcolor = "#B9B9D5", label = "rack"]; - default -> rack [constraint = "false"]; - "rack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "rack-obama"]; - default -> "rack-obama" [constraint = "false"]; - "rack-obama" -> rack; + myrack [style = "filled", fillcolor = "#B9B9D5", label = "myrack"]; + default -> myrack [constraint = "false"]; + "myrack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "myrack-obama"]; + default -> "myrack-obama" [constraint = "false"]; + "myrack-obama" -> myrack; } debugging bundle viz... DOT @@ -111,7 +111,7 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld context "--without option" do it "one group" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" group :rails do @@ -125,11 +125,11 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld it "two groups" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" - group :rack do - gem "rack" + group :myrack do + gem "myrack" end group :rails do @@ -137,7 +137,7 @@ RSpec.describe "bundle viz", bundler: "< 3", if: Bundler.which("dot"), realworld end G - bundle "viz --without=rails:rack" + bundle "viz --without=rails:myrack" expect(out).to include("gem_graph.png") end end diff --git a/spec/bundler/install/allow_offline_install_spec.rb b/spec/bundler/install/allow_offline_install_spec.rb index 8da94718e0..21b0568f7d 100644 --- a/spec/bundler/install/allow_offline_install_spec.rb +++ b/spec/bundler/install/allow_offline_install_spec.rb @@ -9,15 +9,15 @@ RSpec.describe "bundle install with :allow_offline_install" do it "still installs" do install_gemfile <<-G, artifice: "compact_index" source "http://testgemserver.local" - gem "rack-obama" + gem "myrack-obama" G - expect(the_bundle).to include_gem("rack 1.0") + expect(the_bundle).to include_gem("myrack 1.0") end it "still fails when the network is down" do install_gemfile <<-G, artifice: "fail", raise_on_error: false source "http://testgemserver.local" - gem "rack-obama" + gem "myrack-obama" G expect(err).to include("Could not reach host testgemserver.local.") expect(the_bundle).to_not be_locked @@ -26,26 +26,26 @@ RSpec.describe "bundle install with :allow_offline_install" do context "with cached data locally" do it "will install from the compact index" do - system_gems ["rack-1.0.0"], path: default_bundle_path + system_gems ["myrack-1.0.0"], path: default_bundle_path bundle "config set clean false" install_gemfile <<-G, artifice: "compact_index" source "http://testgemserver.local" - gem "rack-obama" - gem "rack", "< 1.0" + gem "myrack-obama" + gem "myrack", "< 1.0" G - expect(the_bundle).to include_gems("rack-obama 1.0", "rack 0.9.1") + expect(the_bundle).to include_gems("myrack-obama 1.0", "myrack 0.9.1") gemfile <<-G source "http://testgemserver.local" - gem "rack-obama" + gem "myrack-obama" G bundle :update, artifice: "fail", all: true expect(last_command.stdboth).to include "Using the cached data for the new index because of a network error" - expect(the_bundle).to include_gems("rack-obama 1.0", "rack 1.0.0") + expect(the_bundle).to include_gems("myrack-obama 1.0", "myrack 1.0.0") end def break_git_remote_ops! @@ -53,10 +53,10 @@ RSpec.describe "bundle install with :allow_offline_install" do File.open(tmp("broken_path/git"), "w", 0o755) do |f| f.puts <<~RUBY #!/usr/bin/env ruby - fetch_args = %w(fetch --force --quiet) + fetch_args = %w(fetch --force --quiet --no-tags) clone_args = %w(clone --bare --no-hardlinks --quiet) - if (fetch_args.-(ARGV).empty? || clone_args.-(ARGV).empty?) && ARGV.any? {|arg| arg.start_with?("file://") } + if (fetch_args.-(ARGV).empty? || clone_args.-(ARGV).empty?) && File.exist?(ARGV[ARGV.index("--") + 1]) warn "git remote ops have been disabled" exit 1 end @@ -78,7 +78,7 @@ RSpec.describe "bundle install with :allow_offline_install" do git = build_git "a", "1.0.0", path: lib_path("a") update_git("a", path: git.path, branch: "new_branch") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "a", :git => #{git.path.to_s.dump} G @@ -88,7 +88,7 @@ RSpec.describe "bundle install with :allow_offline_install" do break_git_remote_ops! do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "a", :git => #{git.path.to_s.dump}, :branch => "new_branch" G end diff --git a/spec/bundler/install/binstubs_spec.rb b/spec/bundler/install/binstubs_spec.rb index 928ba80b15..00765ac6dd 100644 --- a/spec/bundler/install/binstubs_spec.rb +++ b/spec/bundler/install/binstubs_spec.rb @@ -6,14 +6,14 @@ RSpec.describe "bundle install" do expect(Pathname.new("/usr/bin")).not_to be_writable gemfile <<-G def Gem.bindir; "/usr/bin"; end - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G config "BUNDLE_SYSTEM_BINDIR" => system_gem_path("altbin").to_s bundle :install - expect(the_bundle).to include_gems "rack 1.0.0" - expect(system_gem_path("altbin/rackup")).to exist + expect(the_bundle).to include_gems "myrack 1.0.0" + expect(system_gem_path("altbin/myrackup")).to exist end end @@ -21,26 +21,26 @@ RSpec.describe "bundle install" do before do build_repo2 do build_gem "fake", "14" do |s| - s.executables = "rackup" + s.executables = "myrackup" end end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "fake" - gem "rack" + gem "myrack" G end it "warns about the situation" do - bundle "exec rackup" + bundle "exec myrackup" expect(last_command.stderr).to include( - "The `rackup` executable in the `fake` gem is being loaded, but it's also present in other gems (rack).\n" \ + "The `myrackup` executable in the `fake` gem is being loaded, but it's also present in other gems (myrack).\n" \ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names." ).or include( - "The `rackup` executable in the `rack` gem is being loaded, but it's also present in other gems (fake).\n" \ + "The `myrackup` executable in the `myrack` gem is being loaded, but it's also present in other gems (fake).\n" \ "If you meant to run the executable for another gem, make sure you use a project specific binstub (`bundle binstub <gem_name>`).\n" \ "If you plan to use multiple conflicting executables, generate binstubs for them and disambiguate their names." ) diff --git a/spec/bundler/install/bundler_spec.rb b/spec/bundler/install/bundler_spec.rb index 19911f1154..56f8431181 100644 --- a/spec/bundler/install/bundler_spec.rb +++ b/spec/bundler/install/bundler_spec.rb @@ -5,7 +5,7 @@ RSpec.describe "bundle install" do before(:each) do build_repo2 do build_gem "rails", "3.0" do |s| - s.add_dependency "bundler", ">= 0.9.0.pre" + s.add_dependency "bundler", ">= 0.9.0" end build_gem "bundler", "0.9.1" build_gem "bundler", Bundler::VERSION @@ -14,7 +14,7 @@ RSpec.describe "bundle install" do it "are forced to the current bundler version" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" G @@ -23,15 +23,15 @@ RSpec.describe "bundle install" do it "are forced to the current bundler version even if not already present" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G expect(the_bundle).to include_gems "bundler #{Bundler::VERSION}" end it "causes a conflict if explicitly requesting a different version of bundler" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" gem "bundler", "0.9.1" G @@ -51,7 +51,7 @@ RSpec.describe "bundle install" do it "causes a conflict if explicitly requesting a non matching requirement on bundler" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" gem "bundler", "~> 0.8" G @@ -59,8 +59,8 @@ RSpec.describe "bundle install" do nice_error = <<~E.strip Could not find compatible versions - Because rails >= 3.0 depends on bundler >= 0.9.0.pre - and the current Bundler version (#{Bundler::VERSION}) does not satisfy bundler >= 0.9.0.pre, < 1.A, + Because rails >= 3.0 depends on bundler >= 0.9.0 + and the current Bundler version (#{Bundler::VERSION}) does not satisfy bundler >= 0.9.0, < 1.A, rails >= 3.0 requires bundler >= 1.A. So, because Gemfile depends on rails = 3.0 and Gemfile depends on bundler ~> 0.8, @@ -74,7 +74,7 @@ RSpec.describe "bundle install" do it "causes a conflict if explicitly requesting a version of bundler that doesn't exist" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" gem "bundler", "0.9.2" G @@ -99,16 +99,16 @@ RSpec.describe "bundle install" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "multiple_versioned_deps" G install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "multiple_versioned_deps" - gem "rack" + gem "myrack" G expect(the_bundle).to include_gems "multiple_versioned_deps 1.0.0" @@ -116,7 +116,7 @@ RSpec.describe "bundle install" do it "includes bundler in the bundle when it's a child dependency" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" G @@ -126,8 +126,8 @@ RSpec.describe "bundle install" do it "allows gem 'bundler' when Bundler is not in the Gemfile or its dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" G run "begin; gem 'bundler'; puts 'WIN'; rescue Gem::LoadError => e; puts e.backtrace; end" @@ -144,7 +144,7 @@ RSpec.describe "bundle install" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activemerchant" gem "rails_pinned_to_old_activesupport" G @@ -172,7 +172,7 @@ RSpec.describe "bundle install" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails_pinned_to_old_activesupport" gem "activesupport", "2.3.5" G @@ -197,12 +197,12 @@ RSpec.describe "bundle install" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'rails', "2.3.2" G install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails_pinned_to_old_activesupport" G @@ -219,17 +219,17 @@ RSpec.describe "bundle install" do bundle "config set path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'rails', "7.0.4" G install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'rails', "7.0.3" G install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'rails', "7.0.4" G @@ -243,7 +243,7 @@ RSpec.describe "bundle install" do system_gems "bundler-99999999.99.1" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" G @@ -257,7 +257,7 @@ RSpec.describe "bundle install" do system_gems "bundler-99999999.99.1" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0" G diff --git a/spec/bundler/install/deploy_spec.rb b/spec/bundler/install/deploy_spec.rb index d89fdea6f1..7b6e775b4c 100644 --- a/spec/bundler/install/deploy_spec.rb +++ b/spec/bundler/install/deploy_spec.rb @@ -3,8 +3,8 @@ RSpec.describe "install in deployment or frozen mode" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -37,7 +37,7 @@ RSpec.describe "install in deployment or frozen mode" do it "doesn't mess up a subsequent `bundle install` after you try to deploy without a lock" do bundle "install --deployment", raise_on_error: false bundle :install - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end it "installs gems by default to vendor/bundle" do @@ -60,33 +60,45 @@ RSpec.describe "install in deployment or frozen mode" do it "explodes with the --deployment flag if you make a change and don't check in the lockfile" do bundle :lock gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G bundle "install --deployment", raise_on_error: false expect(err).to include("frozen mode") expect(err).to include("You have added to the Gemfile") - expect(err).to include("* rack-obama") + expect(err).to include("* myrack-obama") expect(err).not_to include("You have deleted from the Gemfile") expect(err).not_to include("You have changed in the Gemfile") end end + it "fails without a lockfile and says that deployment requires a lock" do + bundle "config deployment true" + bundle "install", raise_on_error: false + expect(err).to include("The deployment setting requires a lockfile") + end + + it "fails without a lockfile and says that frozen requires a lock" do + bundle "config frozen true" + bundle "install", raise_on_error: false + expect(err).to include("The frozen setting requires a lockfile") + end + it "still works if you are not in the app directory and specify --gemfile" do bundle "install" simulate_new_machine bundle "config set --local deployment true" bundle "config set --local path vendor/bundle" bundle "install --gemfile #{tmp}/bundled_app/Gemfile", dir: tmp - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end it "works if you exclude a group with a git gem" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" group :test do gem "foo", :git => "#{lib_path("foo-1.0")}" end @@ -110,7 +122,7 @@ RSpec.describe "install in deployment or frozen mode" do build_lib "foo", path: lib_path("nested/foo") build_lib "bar", path: lib_path("nested/bar") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.0", :path => "#{lib_path("nested")}" gem "bar", :path => "#{lib_path("nested")}" G @@ -123,7 +135,7 @@ RSpec.describe "install in deployment or frozen mode" do it "works when path gems are specified twice" do build_lib "foo", path: lib_path("nested/foo") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("nested/foo")}" gem "foo", :path => "#{lib_path("nested/foo")}" G @@ -137,7 +149,7 @@ RSpec.describe "install in deployment or frozen mode" do install_gemfile(<<-G, artifice: "endpoint_strict_basic_authentication", quiet: true) source "http://user:pass@localgemserver.test/" - gem "rack-obama", ">= 1.0" + gem "myrack-obama", ">= 1.0" G bundle "config set --local deployment true" @@ -146,16 +158,16 @@ RSpec.describe "install in deployment or frozen mode" do it "works with sources given by a block" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - source "#{file_uri_for(gem_repo1)}" do - gem "rack" + source "https://gem.repo1" + source "https://gem.repo1" do + gem "myrack" end G bundle "config set --local deployment true" bundle :install - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end context "when replacing a host with the same host with credentials" do @@ -164,20 +176,20 @@ RSpec.describe "install in deployment or frozen mode" do bundle "install" gemfile <<-G source "http://user_name:password@localgemserver.test/" - gem "rack" + gem "myrack" G lockfile <<-G GEM remote: http://localgemserver.test/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{generic_local_platform} DEPENDENCIES - rack + myrack G bundle "config set --local deployment true" @@ -231,16 +243,16 @@ RSpec.describe "install in deployment or frozen mode" do it "explodes with the `deployment` setting if you make a change and don't check in the lockfile" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G bundle "config set --local deployment true" bundle :install, raise_on_error: false expect(err).to include("frozen mode") expect(err).to include("You have added to the Gemfile") - expect(err).to include("* rack-obama") + expect(err).to include("* myrack-obama") expect(err).not_to include("You have deleted from the Gemfile") expect(err).not_to include("You have changed in the Gemfile") end @@ -248,7 +260,7 @@ RSpec.describe "install in deployment or frozen mode" do it "works if a path gem is missing but is in a without group" do build_lib "path_gem" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" gem "path_gem", :path => "#{lib_path("path_gem-1.0")}", :group => :development G @@ -267,9 +279,9 @@ RSpec.describe "install in deployment or frozen mode" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - source "#{file_uri_for(gem_repo1)}" do + source "https://gem.repo1" do gem "rake", platform: :#{not_local_tag} end G @@ -315,7 +327,7 @@ RSpec.describe "install in deployment or frozen mode" do it "explodes if a path gem is missing" do build_lib "path_gem" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" gem "path_gem", :path => "#{lib_path("path_gem-1.0")}", :group => :development G @@ -330,32 +342,32 @@ RSpec.describe "install in deployment or frozen mode" do it "can have --frozen set via an environment variable" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G ENV["BUNDLE_FROZEN"] = "1" bundle "install", raise_on_error: false expect(err).to include("frozen mode") expect(err).to include("You have added to the Gemfile") - expect(err).to include("* rack-obama") + expect(err).to include("* myrack-obama") expect(err).not_to include("You have deleted from the Gemfile") expect(err).not_to include("You have changed in the Gemfile") end it "can have --deployment set via an environment variable" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G ENV["BUNDLE_DEPLOYMENT"] = "true" bundle "install", raise_on_error: false expect(err).to include("frozen mode") expect(err).to include("You have added to the Gemfile") - expect(err).to include("* rack-obama") + expect(err).to include("* myrack-obama") expect(err).not_to include("You have deleted from the Gemfile") expect(err).not_to include("You have changed in the Gemfile") end @@ -375,9 +387,9 @@ RSpec.describe "install in deployment or frozen mode" do it "can have --frozen set to false via an environment variable" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G ENV["BUNDLE_FROZEN"] = "false" @@ -385,12 +397,12 @@ RSpec.describe "install in deployment or frozen mode" do bundle "install" expect(out).not_to include("frozen mode") expect(out).not_to include("You have added to the Gemfile") - expect(out).not_to include("* rack-obama") + expect(out).not_to include("* myrack-obama") end - it "explodes if you remove a gem and don't check in the lockfile" do + it "explodes if you replace a gem and don't check in the lockfile" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" G @@ -398,34 +410,45 @@ RSpec.describe "install in deployment or frozen mode" do bundle :install, raise_on_error: false expect(err).to include("frozen mode") expect(err).to include("You have added to the Gemfile:\n* activesupport\n\n") - expect(err).to include("You have deleted from the Gemfile:\n* rack") + expect(err).to include("You have deleted from the Gemfile:\n* myrack") + expect(err).not_to include("You have changed in the Gemfile") + end + + it "explodes if you remove a gem and don't check in the lockfile" do + gemfile 'source "https://gem.repo1"' + + bundle "config set --local deployment true" + bundle :install, raise_on_error: false + expect(err).to include("Some dependencies were deleted") + expect(err).to include("frozen mode") + expect(err).to include("You have deleted from the Gemfile:\n* myrack") expect(err).not_to include("You have changed in the Gemfile") end it "explodes if you add a source" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "git://hubz.com" + source "https://gem.repo1" + gem "myrack", :git => "git://hubz.com" G bundle "config set --local deployment true" bundle :install, raise_on_error: false expect(err).to include("frozen mode") expect(err).not_to include("You have added to the Gemfile") - expect(err).to include("You have changed in the Gemfile:\n* rack from `no specified source` to `git://hubz.com`") + expect(err).to include("You have changed in the Gemfile:\n* myrack from `no specified source` to `git://hubz.com`") end it "explodes if you change a source" do - build_git "rack" + build_git "myrack" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-1.0")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-1.0")}" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set --local deployment true" @@ -433,29 +456,29 @@ RSpec.describe "install in deployment or frozen mode" do expect(err).to include("frozen mode") expect(err).not_to include("You have deleted from the Gemfile") expect(err).not_to include("You have added to the Gemfile") - expect(err).to include("You have changed in the Gemfile:\n* rack from `#{lib_path("rack-1.0")}` to `no specified source`") + expect(err).to include("You have changed in the Gemfile:\n* myrack from `#{lib_path("myrack-1.0")}` to `no specified source`") end it "explodes if you change a source" do - build_lib "foo", path: lib_path("rack/foo") - build_git "rack", path: lib_path("rack") + build_lib "foo", path: lib_path("myrack/foo") + build_git "myrack", path: lib_path("myrack") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack")}" - gem "foo", :git => "#{lib_path("rack")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack")}" + gem "foo", :git => "#{lib_path("myrack")}" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "foo", :git => "#{lib_path("rack")}" + source "https://gem.repo1" + gem "myrack" + gem "foo", :git => "#{lib_path("myrack")}" G bundle "config set --local deployment true" bundle :install, raise_on_error: false expect(err).to include("frozen mode") - expect(err).to include("You have changed in the Gemfile:\n* rack from `#{lib_path("rack")}` to `no specified source`") + expect(err).to include("You have changed in the Gemfile:\n* myrack from `#{lib_path("myrack")}` to `no specified source`") expect(err).not_to include("You have added to the Gemfile") expect(err).not_to include("You have deleted from the Gemfile") end @@ -466,21 +489,21 @@ RSpec.describe "install in deployment or frozen mode" do bundle "config set --local deployment true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack", "1.0.0" + gem "myrack-obama" G - run "require 'rack'", raise_on_error: false + run "require 'myrack'", raise_on_error: false expect(err).to include <<~E.strip The dependencies in your gemfile changed, but the lockfile can't be updated because frozen mode is set (Bundler::ProductionError) You have added to the Gemfile: - * rack (= 1.0.0) - * rack-obama + * myrack (= 1.0.0) + * myrack-obama You have deleted from the Gemfile: - * rack + * myrack E end end @@ -489,7 +512,7 @@ RSpec.describe "install in deployment or frozen mode" do it "works fine after bundle package and bundle install --local" do build_lib "foo", path: lib_path("foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G diff --git a/spec/bundler/install/failure_spec.rb b/spec/bundler/install/failure_spec.rb index f972a37bf6..2c2773e849 100644 --- a/spec/bundler/install/failure_spec.rb +++ b/spec/bundler/install/failure_spec.rb @@ -15,7 +15,7 @@ RSpec.describe "bundle install" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" G expect(err).to start_with("Gem::Ext::BuildError: ERROR: Failed to build gem native extension.") @@ -40,7 +40,7 @@ In Gemfile: it "removes the downloaded .gem" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "a" G diff --git a/spec/bundler/install/gemfile/eval_gemfile_spec.rb b/spec/bundler/install/gemfile/eval_gemfile_spec.rb index cfa66e5986..a507e52485 100644 --- a/spec/bundler/install/gemfile/eval_gemfile_spec.rb +++ b/spec/bundler/install/gemfile/eval_gemfile_spec.rb @@ -2,7 +2,7 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do before do - build_lib("gunks", path: bundled_app.join("gems/gunks")) do |s| + build_lib("gunks", path: bundled_app("gems/gunks")) do |s| s.name = "gunks" s.version = "0.0.1" end @@ -10,15 +10,15 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do context "eval-ed Gemfile points to an internal gemspec" do before do - create_file "Gemfile-other", <<-G - source "#{file_uri_for(gem_repo1)}" + gemfile "Gemfile-other", <<-G + source "https://gem.repo1" gemspec :path => 'gems/gunks' G end it "installs the gemspec specified gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile 'Gemfile-other' G expect(out).to include("Resolving dependencies") @@ -36,12 +36,12 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do build_gem "zip-zip", "0.3" end - create_file bundled_app("gems/Gemfile"), <<-G - source "#{file_uri_for(gem_repo2)}" + gemfile bundled_app("gems/Gemfile"), <<-G + source "https://gem.repo2" gemspec :path => "\#{__dir__}/gunks" - source "#{file_uri_for(gem_repo2)}" do + source "https://gem.repo2" do gem "zip-zip" end G @@ -49,7 +49,7 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do it "installs and finds gems correctly" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails" @@ -65,13 +65,13 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do context "eval-ed Gemfile has relative-path gems" do before do build_lib("a", path: bundled_app("gems/a")) - create_file bundled_app("nested/Gemfile-nested"), <<-G - source "#{file_uri_for(gem_repo1)}" + gemfile bundled_app("nested/Gemfile-nested"), <<-G + source "https://gem.repo1" gem "a", :path => "../gems/a" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile "nested/Gemfile-nested" G end @@ -95,7 +95,7 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do it "installs the gemspec specified gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" eval_gemfile 'other/Gemfile-other' gemspec :path => 'gems/gunks' G @@ -108,15 +108,15 @@ RSpec.describe "bundle install with gemfile that uses eval_gemfile" do context "eval-ed Gemfile references other gemfiles" do it "works with relative paths" do - create_file "other/Gemfile-other", "gem 'rack'" - create_file "other/Gemfile", "eval_gemfile 'Gemfile-other'" - create_file "Gemfile-alt", <<-G - source "#{file_uri_for(gem_repo1)}" + gemfile "other/Gemfile-other", "gem 'myrack'" + gemfile "other/Gemfile", "eval_gemfile 'Gemfile-other'" + gemfile "Gemfile-alt", <<-G + source "https://gem.repo1" eval_gemfile "other/Gemfile" G install_gemfile "eval_gemfile File.expand_path('Gemfile-alt')" - expect(the_bundle).to include_gem "rack 1.0.0" + expect(the_bundle).to include_gem "myrack 1.0.0" end end end diff --git a/spec/bundler/install/gemfile/force_ruby_platform_spec.rb b/spec/bundler/install/gemfile/force_ruby_platform_spec.rb index a29b79ad62..f5d993adac 100644 --- a/spec/bundler/install/gemfile/force_ruby_platform_spec.rb +++ b/spec/bundler/install/gemfile/force_ruby_platform_spec.rb @@ -5,77 +5,68 @@ RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do before do build_repo4 do # Build a gem with platform specific versions - build_gem("platform_specific") do |s| - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'" - end + build_gem("platform_specific") build_gem("platform_specific") do |s| s.platform = Bundler.local_platform - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'" end # Build the exact same gem with a different name to compare using vs not using the option - build_gem("platform_specific_forced") do |s| - s.write "lib/platform_specific_forced.rb", "PLATFORM_SPECIFIC_FORCED = '1.0.0 RUBY'" - end + build_gem("platform_specific_forced") build_gem("platform_specific_forced") do |s| s.platform = Bundler.local_platform - s.write "lib/platform_specific_forced.rb", "PLATFORM_SPECIFIC_FORCED = '1.0.0 #{Bundler.local_platform}'" end end end it "pulls the pure ruby variant of the given gem" do install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "platform_specific_forced", :force_ruby_platform => true gem "platform_specific" G - expect(the_bundle).to include_gems "platform_specific_forced 1.0.0 RUBY" - expect(the_bundle).to include_gems "platform_specific 1.0.0 #{Bundler.local_platform}" + expect(the_bundle).to include_gems "platform_specific_forced 1.0 ruby" + expect(the_bundle).to include_gems "platform_specific 1.0 #{Bundler.local_platform}" end it "still respects a global `force_ruby_platform` config" do install_gemfile <<-G, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" } - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "platform_specific_forced", :force_ruby_platform => true gem "platform_specific" G - expect(the_bundle).to include_gems "platform_specific_forced 1.0.0 RUBY" - expect(the_bundle).to include_gems "platform_specific 1.0.0 RUBY" + expect(the_bundle).to include_gems "platform_specific_forced 1.0 ruby" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" end end context "when also a transitive dependency" do before do build_repo4 do - build_gem("depends_on_platform_specific") {|s| s.add_runtime_dependency "platform_specific" } + build_gem("depends_on_platform_specific") {|s| s.add_dependency "platform_specific" } - build_gem("platform_specific") do |s| - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'" - end + build_gem("platform_specific") build_gem("platform_specific") do |s| s.platform = Bundler.local_platform - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'" end end end it "still pulls the ruby variant" do install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "depends_on_platform_specific" gem "platform_specific", :force_ruby_platform => true G - expect(the_bundle).to include_gems "platform_specific 1.0.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" end end @@ -83,42 +74,37 @@ RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do before do build_repo4 do build_gem("depends_on_platform_specific") do |s| - s.add_runtime_dependency "platform_specific" - s.write "lib/depends_on_platform_specific.rb", "DEPENDS_ON_PLATFORM_SPECIFIC = '1.0.0 RUBY'" + s.add_dependency "platform_specific" end build_gem("depends_on_platform_specific") do |s| - s.add_runtime_dependency "platform_specific" + s.add_dependency "platform_specific" s.platform = Bundler.local_platform - s.write "lib/depends_on_platform_specific.rb", "DEPENDS_ON_PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'" end - build_gem("platform_specific") do |s| - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'" - end + build_gem("platform_specific") build_gem("platform_specific") do |s| s.platform = Bundler.local_platform - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Bundler.local_platform}'" end end end it "ignores ruby variants for the transitive dependencies" do install_gemfile <<-G, env: { "DEBUG_RESOLVER" => "true" } - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "depends_on_platform_specific", :force_ruby_platform => true G - expect(the_bundle).to include_gems "depends_on_platform_specific 1.0.0 RUBY" - expect(the_bundle).to include_gems "platform_specific 1.0.0 #{Bundler.local_platform}" + expect(the_bundle).to include_gems "depends_on_platform_specific 1.0 ruby" + expect(the_bundle).to include_gems "platform_specific 1.0 #{Bundler.local_platform}" end - it "reinstalls the ruby variant when a platform specific variant is already installed, the lockile has only RUBY platform, and :force_ruby_platform is used in the Gemfile" do + it "reinstalls the ruby variant when a platform specific variant is already installed, the lockile has only ruby platform, and :force_ruby_platform is used in the Gemfile" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: platform_specific (1.0) @@ -132,15 +118,17 @@ RSpec.describe "bundle install with force_ruby_platform DSL option", :jruby do #{Bundler::VERSION} L - system_gems "platform_specific-1.0-#{Gem::Platform.local}", path: default_bundle_path + simulate_platform "x86-darwin-100" do + system_gems "platform_specific-1.0-x86-darwin-100", path: default_bundle_path - install_gemfile <<-G, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, artifice: "compact_index" - source "#{file_uri_for(gem_repo4)}" + install_gemfile <<-G, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, artifice: "compact_index" + source "https://gem.repo4" - gem "platform_specific", :force_ruby_platform => true - G + gem "platform_specific", :force_ruby_platform => true + G - expect(the_bundle).to include_gems "platform_specific 1.0.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" + end end end end diff --git a/spec/bundler/install/gemfile/gemspec_spec.rb b/spec/bundler/install/gemfile/gemspec_spec.rb index 63778567cf..5610a6f05b 100644 --- a/spec/bundler/install/gemfile/gemspec_spec.rb +++ b/spec/bundler/install/gemfile/gemspec_spec.rb @@ -39,14 +39,14 @@ RSpec.describe "bundle install from an existing gemspec" do end it "should install runtime and development dependencies" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("Gemfile", "source :rubygems\ngemspec") s.add_dependency "bar", "=1.0.0" s.add_development_dependency "bar-dev", "=1.0.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}' + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}' G expect(the_bundle).to include_gems "bar 1.0.0" @@ -54,16 +54,16 @@ RSpec.describe "bundle install from an existing gemspec" do end it "that is hidden should install runtime and development dependencies" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("Gemfile", "source :rubygems\ngemspec") s.add_dependency "bar", "=1.0.0" s.add_development_dependency "bar-dev", "=1.0.0" end - FileUtils.mv tmp.join("foo", "foo.gemspec"), tmp.join("foo", ".gemspec") + FileUtils.mv tmp("foo", "foo.gemspec"), tmp("foo", ".gemspec") install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}' + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}' G expect(the_bundle).to include_gems "bar 1.0.0" @@ -76,50 +76,50 @@ RSpec.describe "bundle install from an existing gemspec" do build_gem "baz", "1.1" end - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("Gemfile", "source :rubygems\ngemspec") s.add_dependency "baz", ">= 1.0", "< 1.1" end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}' + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}' G expect(the_bundle).to include_gems "baz 1.0" end it "should raise if there are no gemspecs available" do - build_lib("foo", path: tmp.join("foo"), gemspec: false) + build_lib("foo", path: tmp("foo"), gemspec: false) install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}' + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}' G - expect(err).to match(/There are no gemspecs at #{tmp.join("foo")}/) + expect(err).to match(/There are no gemspecs at #{tmp("foo")}/) end it "should raise if there are too many gemspecs available" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("foo2.gemspec", build_spec("foo", "4.0").first.to_ruby) end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}' + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}' G - expect(err).to match(/There are multiple gemspecs at #{tmp.join("foo")}/) + expect(err).to match(/There are multiple gemspecs at #{tmp("foo")}/) end it "should pick a specific gemspec" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("foo2.gemspec", "") s.add_dependency "bar", "=1.0.0" s.add_development_dependency "bar-dev", "=1.0.0" end install_gemfile(<<-G) - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo' + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}', :name => 'foo' G expect(the_bundle).to include_gems "bar 1.0.0" @@ -127,15 +127,15 @@ RSpec.describe "bundle install from an existing gemspec" do end it "should use a specific group for development dependencies" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.write("foo2.gemspec", "") s.add_dependency "bar", "=1.0.0" s.add_development_dependency "bar-dev", "=1.0.0" end install_gemfile(<<-G) - source "#{file_uri_for(gem_repo2)}" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo', :development_group => :dev + source "https://gem.repo2" + gemspec :path => '#{tmp("foo")}', :name => 'foo', :development_group => :dev G expect(the_bundle).to include_gems "bar 1.0.0" @@ -144,33 +144,33 @@ RSpec.describe "bundle install from an existing gemspec" do end it "should match a lockfile even if the gemspec defines development dependencies" do - build_lib("foo", path: tmp.join("foo")) do |s| - s.write("Gemfile", "source '#{file_uri_for(gem_repo1)}'\ngemspec") + build_lib("foo", path: tmp("foo")) do |s| + s.write("Gemfile", "source 'https://gem.repo1'\ngemspec") s.add_dependency "actionpack", "=2.3.2" s.add_development_dependency "rake", rake_version end - bundle "install", dir: tmp.join("foo") + bundle "install", dir: tmp("foo"), artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } # This should really be able to rely on $stderr, but, it's not written # right, so we can't. In fact, this is a bug negation test, and so it'll # ghost pass in future, and will only catch a regression if the message # doesn't change. Exit codes should be used correctly (they can be more # than just 0 and 1). bundle "config set --local deployment true" - output = bundle("install", dir: tmp.join("foo")) + output = bundle("install", dir: tmp("foo"), artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s }) expect(output).not_to match(/You have added to the Gemfile/) expect(output).not_to match(/You have deleted from the Gemfile/) expect(output).not_to match(/the lockfile can't be updated because frozen mode is set/) end it "should match a lockfile without needing to re-resolve" do - build_lib("foo", path: tmp.join("foo")) do |s| - s.add_dependency "rack" + build_lib("foo", path: tmp("foo")) do |s| + s.add_dependency "myrack" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gemspec :path => '#{tmp.join("foo")}' + source "https://gem.repo1" + gemspec :path => '#{tmp("foo")}' G bundle "install", verbose: true @@ -180,47 +180,47 @@ RSpec.describe "bundle install from an existing gemspec" do end it "should match a lockfile without needing to re-resolve with development dependencies" do - simulate_platform java - - build_lib("foo", path: tmp.join("foo")) do |s| - s.add_dependency "rack" - s.add_development_dependency "thin" - end + simulate_platform java do + build_lib("foo", path: tmp("foo")) do |s| + s.add_dependency "myrack" + s.add_development_dependency "thin" + end - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gemspec :path => '#{tmp.join("foo")}' - G + install_gemfile <<-G + source "https://gem.repo1" + gemspec :path => '#{tmp("foo")}' + G - bundle "install", verbose: true + bundle "install", verbose: true - message = "Found no changes, using resolution from the lockfile" - expect(out.scan(message).size).to eq(1) + message = "Found no changes, using resolution from the lockfile" + expect(out.scan(message).size).to eq(1) + end end it "should match a lockfile on non-ruby platforms with a transitive platform dependency", :jruby_only do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.add_dependency "platform_specific" end system_gems "platform_specific-1.0-java", path: default_bundle_path install_gemfile <<-G - gemspec :path => '#{tmp.join("foo")}' + gemspec :path => '#{tmp("foo")}' G bundle "update --bundler", artifice: "compact_index", verbose: true - expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 JAVA" + expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 java" end it "should evaluate the gemspec in its directory" do - build_lib("foo", path: tmp.join("foo")) - File.open(tmp.join("foo/foo.gemspec"), "w") do |s| - s.write "raise 'ahh' unless Dir.pwd == '#{tmp.join("foo")}'" + build_lib("foo", path: tmp("foo")) + File.open(tmp("foo/foo.gemspec"), "w") do |s| + s.write "raise 'ahh' unless Dir.pwd == '#{tmp("foo")}'" end install_gemfile <<-G, raise_on_error: false - gemspec :path => '#{tmp.join("foo")}' + gemspec :path => '#{tmp("foo")}' G expect(last_command.stdboth).not_to include("ahh") end @@ -231,16 +231,16 @@ RSpec.describe "bundle install from an existing gemspec" do # # issue was caused by rubygems having an unresolved gem during a require, # so emulate that - system_gems %w[rack-1.0.0 rack-0.9.1 rack-obama-1.0] + system_gems %w[myrack-1.0.0 myrack-0.9.1 myrack-obama-1.0] build_lib("foo", path: bundled_app) gemspec = bundled_app("foo.gemspec").read bundled_app("foo.gemspec").open("w") do |f| - f.write "#{gemspec.strip}.tap { gem 'rack-obama'; require 'rack/obama' }" + f.write "#{gemspec.strip}.tap { gem 'myrack-obama'; require 'myrack/obama' }" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G @@ -248,7 +248,7 @@ RSpec.describe "bundle install from an existing gemspec" do end it "allows conflicts" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.version = "1.0.0" s.add_dependency "bar", "= 1.0.0" end @@ -258,16 +258,16 @@ RSpec.describe "bundle install from an existing gemspec" do build_gem "foo", "0.0.1", to_bundle: true install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "deps" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo' + gemspec :path => '#{tmp("foo")}', :name => 'foo' G expect(the_bundle).to include_gems "foo 1.0.0" end it "does not break Gem.finish_resolve with conflicts" do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.version = "1.0.0" s.add_dependency "bar", "= 1.0.0" end @@ -279,9 +279,9 @@ RSpec.describe "bundle install from an existing gemspec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "deps" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo' + gemspec :path => '#{tmp("foo")}', :name => 'foo' G expect(the_bundle).to include_gems "foo 1.0.0" @@ -294,7 +294,7 @@ RSpec.describe "bundle install from an existing gemspec" do build_lib "omg", "2.0", path: lib_path("omg") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec :path => "#{lib_path("omg")}" G @@ -313,7 +313,7 @@ RSpec.describe "bundle install from an existing gemspec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G @@ -335,23 +335,23 @@ RSpec.describe "bundle install from an existing gemspec" do before do # build the "parent" gem that depends on another gem in the same repo build_lib "source_conflict", path: bundled_app do |s| - s.add_dependency "rack_middleware" + s.add_dependency "myrack_middleware" end # build the "child" gem that is the same version as a released gem, but # has completely different and conflicting dependency requirements - build_lib "rack_middleware", "1.0", path: bundled_app("rack_middleware") do |s| - s.add_dependency "rack", "1.0" # anything other than 0.9.1 + build_lib "myrack_middleware", "1.0", path: bundled_app("myrack_middleware") do |s| + s.add_dependency "myrack", "1.0" # anything other than 0.9.1 end end it "should install the child gemspec's deps" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end @@ -359,8 +359,8 @@ RSpec.describe "bundle install from an existing gemspec" do let(:source_uri) { "http://localgemserver.test" } before do - build_lib("foo", path: tmp.join("foo")) do |s| - s.add_dependency "rack", "=1.0.0" + build_lib("foo", path: tmp("foo")) do |s| + s.add_dependency "myrack", "=1.0.0" end gemfile <<-G @@ -368,7 +368,7 @@ RSpec.describe "bundle install from an existing gemspec" do gemspec :path => "../foo" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end @@ -377,12 +377,12 @@ RSpec.describe "bundle install from an existing gemspec" do remote: ../foo specs: foo (1.0) - rack (= 1.0.0) + myrack (= 1.0.0) GEM remote: #{source_uri} specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{generic_local_platform} @@ -398,9 +398,9 @@ RSpec.describe "bundle install from an existing gemspec" do context "using JRuby with explicit platform", :jruby_only do before do create_file( - tmp.join("foo", "foo-java.gemspec"), + tmp("foo", "foo-java.gemspec"), build_spec("foo", "1.0", "java") do - dep "rack", "=1.0.0" + dep "myrack", "=1.0.0" @spec.authors = "authors" @spec.summary = "summary" end.first.to_ruby @@ -409,15 +409,15 @@ RSpec.describe "bundle install from an existing gemspec" do it "should install" do results = bundle "install", artifice: "endpoint" - expect(results).to include("Installing rack 1.0.0") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(results).to include("Installing myrack 1.0.0") + expect(the_bundle).to include_gems "myrack 1.0.0" end end it "should install", :jruby do results = bundle "install", artifice: "endpoint" - expect(results).to include("Installing rack 1.0.0") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(results).to include("Installing myrack 1.0.0") + expect(the_bundle).to include_gems "myrack 1.0.0" end context "bundled for multiple platforms" do @@ -441,7 +441,7 @@ RSpec.describe "bundle install from an existing gemspec" do end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gemspec G @@ -461,9 +461,9 @@ RSpec.describe "bundle install from an existing gemspec" do context "as a runtime dependency" do it "keeps all platform dependencies in the lockfile" do - expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 ruby" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" c.checksum gem_repo2, "platform_specific", "1.0" c.checksum gem_repo2, "platform_specific", "1.0", "java" @@ -478,7 +478,7 @@ RSpec.describe "bundle install from an existing gemspec" do platform_specific GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: platform_specific (1.0) platform_specific (1.0-java) @@ -502,9 +502,9 @@ RSpec.describe "bundle install from an existing gemspec" do let(:platform_specific_type) { :development } it "keeps all platform dependencies in the lockfile" do - expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "foo 1.0", "platform_specific 1.0 ruby" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" c.checksum gem_repo2, "platform_specific", "1.0" c.checksum gem_repo2, "platform_specific", "1.0", "java" @@ -518,7 +518,7 @@ RSpec.describe "bundle install from an existing gemspec" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: platform_specific (1.0) platform_specific (1.0-java) @@ -544,9 +544,9 @@ RSpec.describe "bundle install from an existing gemspec" do let(:dependency) { "indirect_platform_specific" } it "keeps all platform dependencies in the lockfile" do - expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "foo 1.0", "indirect_platform_specific 1.0", "platform_specific 1.0 ruby" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" c.checksum gem_repo2, "indirect_platform_specific", "1.0" c.checksum gem_repo2, "platform_specific", "1.0" @@ -561,7 +561,7 @@ RSpec.describe "bundle install from an existing gemspec" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: indirect_platform_specific (1.0) platform_specific @@ -589,10 +589,10 @@ RSpec.describe "bundle install from an existing gemspec" do context "with multiple platforms" do before do - build_lib("foo", path: tmp.join("foo")) do |s| + build_lib("foo", path: tmp("foo")) do |s| s.version = "1.0.0" - s.add_development_dependency "rack" - s.write "foo-universal-java.gemspec", build_spec("foo", "1.0.0", "universal-java") {|sj| sj.runtime "rack", "1.0.0" }.first.to_ruby + s.add_development_dependency "myrack" + s.write "foo-universal-java.gemspec", build_spec("foo", "1.0.0", "universal-java") {|sj| sj.runtime "myrack", "1.0.0" }.first.to_ruby end end @@ -600,11 +600,11 @@ RSpec.describe "bundle install from an existing gemspec" do bundle "config set --local force_ruby_platform true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo' + source "https://gem.repo1" + gemspec :path => '#{tmp("foo")}', :name => 'foo' G - expect(the_bundle).to include_gems "foo 1.0.0", "rack 1.0.0" + expect(the_bundle).to include_gems "foo 1.0.0", "myrack 1.0.0" end it "installs the ruby platform gemspec and skips dev deps with `without development` configured" do @@ -612,18 +612,18 @@ RSpec.describe "bundle install from an existing gemspec" do bundle "config set --local without development" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gemspec :path => '#{tmp.join("foo")}', :name => 'foo' + source "https://gem.repo1" + gemspec :path => '#{tmp("foo")}', :name => 'foo' G expect(the_bundle).to include_gem "foo 1.0.0" - expect(the_bundle).not_to include_gem "rack" + expect(the_bundle).not_to include_gem "myrack" end end context "with multiple platforms and resolving for more specific platforms" do before do - build_lib("chef", path: tmp.join("chef")) do |s| + build_lib("chef", path: tmp("chef")) do |s| s.version = "17.1.17" s.write "chef-universal-mingw32.gemspec", build_spec("chef", "17.1.17", "universal-mingw32") {|sw| sw.runtime "win32-api", "~> 1.5.3" }.first.to_ruby end @@ -637,11 +637,11 @@ RSpec.describe "bundle install from an existing gemspec" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec :path => "../chef" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "chef", "17.1.17" c.no_checksum "chef", "17.1.17", "universal-mingw32" c.checksum gem_repo4, "win32-api", "1.5.3", "universal-mingw32" @@ -656,7 +656,7 @@ RSpec.describe "bundle install from an existing gemspec" do win32-api (~> 1.5.3) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: win32-api (1.5.3-universal-mingw32) @@ -682,7 +682,7 @@ RSpec.describe "bundle install from an existing gemspec" do context "with multiple locked platforms" do before do - build_lib("activeadmin", path: tmp.join("activeadmin")) do |s| + build_lib("activeadmin", path: tmp("activeadmin")) do |s| s.version = "2.9.0" s.add_dependency "railties", ">= 5.2", "< 6.2" end @@ -696,7 +696,7 @@ RSpec.describe "bundle install from an existing gemspec" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec :path => "../activeadmin" gem "jruby-openssl", :platform => :jruby G @@ -705,9 +705,9 @@ RSpec.describe "bundle install from an existing gemspec" do end it "does not remove the platform specific specs from the lockfile when re-resolving due to gemspec changes" do - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "activeadmin", "2.9.0" - c.no_checksum "jruby-openssl", "0.10.7", "java" + c.checksum gem_repo4, "jruby-openssl", "0.10.7", "java" c.checksum gem_repo4, "railties", "6.1.4" end @@ -719,7 +719,7 @@ RSpec.describe "bundle install from an existing gemspec" do railties (>= 5.2, < 6.2) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: jruby-openssl (0.10.7-java) railties (6.1.4) @@ -735,7 +735,7 @@ RSpec.describe "bundle install from an existing gemspec" do #{Bundler::VERSION} L - gemspec = tmp.join("activeadmin/activeadmin.gemspec") + gemspec = tmp("activeadmin/activeadmin.gemspec") File.write(gemspec, File.read(gemspec).sub(">= 5.2", ">= 6.0")) previous_lockfile = lockfile diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb index 45ee7b44d1..83b3c06cbe 100644 --- a/spec/bundler/install/gemfile/git_spec.rb +++ b/spec/bundler/install/gemfile/git_spec.rb @@ -8,7 +8,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem 'foo' end @@ -31,7 +31,7 @@ RSpec.describe "bundle install with git sources" do end it "does not write to cache on bundler/setup" do - cache_path = default_bundle_path.join("cache") + cache_path = default_bundle_path("cache") FileUtils.rm_rf(cache_path) ruby "require 'bundler/setup'" expect(cache_path).not_to exist @@ -59,7 +59,7 @@ RSpec.describe "bundle install with git sources" do bundle "update foo" sha = git.ref_for("main", 11) - spec_file = default_bundle_path.join("bundler/gems/foo-1.0-#{sha}/foo.gemspec") + spec_file = default_bundle_path("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) @@ -70,7 +70,7 @@ RSpec.describe "bundle install with git sources" do update_git "foo" install_gemfile bundled_app2("Gemfile"), <<-G, dir: bundled_app2 - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem 'foo' end @@ -93,7 +93,7 @@ RSpec.describe "bundle install with git sources" do build_git "foo" install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.1", :git => "#{lib_path("foo-1.0")}" G @@ -106,7 +106,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platforms :jruby do gem "only_java", "1.2", :git => "#{lib_path("only_java-1.0-java")}" end @@ -126,7 +126,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platforms :jruby do gem "only_java", "1.2", :git => "#{lib_path("only_java-1.1-java")}" end @@ -153,17 +153,17 @@ RSpec.describe "bundle install with git sources" do update_git "foo", "1.1", path: lib_path("foo-1.0") gemfile tmp("bundled_app.bck/Gemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem 'foo' end - gem "rack", "1.0" + gem "myrack", "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") + expect(the_bundle).to include_gems "foo 1.1", "myrack 1.0", dir: tmp("bundled_app.bck") end end @@ -171,8 +171,8 @@ RSpec.describe "bundle install with git sources" do before do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" git "#{lib_path("foo-1.0")}" do # this page left intentionally blank @@ -182,7 +182,7 @@ RSpec.describe "bundle install with git sources" do it "does not explode" do bundle "install" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end @@ -195,7 +195,7 @@ RSpec.describe "bundle install with git sources" do it "works" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :ref => "#{@revision}" do gem "foo" end @@ -212,7 +212,7 @@ RSpec.describe "bundle install with git sources" do it "works when the revision is a symbol" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :ref => #{@revision.to_sym.inspect} do gem "foo" end @@ -229,14 +229,14 @@ RSpec.describe "bundle install with git sources" do it "works when an abbreviated revision is added after an initial, potentially shallow clone" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem "foo" end G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :ref => #{@revision[0..7].inspect} do gem "foo" end @@ -246,11 +246,11 @@ RSpec.describe "bundle install with git sources" do 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", remote: @remote.path update_git "foo", push: "main" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{@remote.path}" G @@ -259,7 +259,7 @@ RSpec.describe "bundle install with git sources" do update_git "foo", push: "v1.0.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{@remote.path}", :ref => "v1.0.0" G @@ -272,7 +272,7 @@ RSpec.describe "bundle install with git sources" do 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")) + git("update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", 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| @@ -280,7 +280,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :ref => "refs/bundler/1" do gem "foo" end @@ -297,7 +297,7 @@ RSpec.describe "bundle install with git sources" do 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)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem "foo" end @@ -308,7 +308,7 @@ RSpec.describe "bundle install with git sources" do 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")) + git("update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", 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| @@ -316,7 +316,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :ref => "refs/bundler/1" do gem "foo" end @@ -332,12 +332,12 @@ RSpec.describe "bundle install with git sources" do 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")) + git("update-ref -m \"Bundler Spec!\" refs/bundler/1 main~1", lib_path("foo-1.0")) bundle "config set global_gem_cache true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem "foo" end @@ -346,7 +346,7 @@ RSpec.describe "bundle install with git sources" do # ensure we also git fetch after cloning bundle :update, all: true - sys_exec("git ls-remote .", dir: Dir[home(".bundle/cache/git/foo-*")].first) + git("ls-remote .", Dir[home(".bundle/cache/git/foo-*")].first) expect(out).not_to include("refs/bundler/1") end @@ -360,7 +360,7 @@ RSpec.describe "bundle install with git sources" do update_git("foo", path: repo, branch: branch) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{repo}", :branch => #{branch.dump} do gem "foo" end @@ -377,7 +377,7 @@ RSpec.describe "bundle install with git sources" do update_git("foo", path: repo, branch: branch) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{repo}", :branch => #{branch.dump} do gem "foo" end @@ -395,7 +395,7 @@ RSpec.describe "bundle install with git sources" do update_git("foo", path: repo, branch: branch) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{repo}", :branch => #{branch.dump} do gem "foo" end @@ -414,7 +414,7 @@ RSpec.describe "bundle install with git sources" do update_git("foo", path: repo, tag: tag) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{repo}", :tag => #{tag.dump} do gem "foo" end @@ -431,7 +431,7 @@ RSpec.describe "bundle install with git sources" do update_git("foo", path: repo, tag: tag) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{repo}", :tag => #{tag.dump} do gem "foo" end @@ -449,7 +449,7 @@ RSpec.describe "bundle install with git sources" do update_git("foo", path: repo, tag: tag) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{repo}", :tag => #{tag.dump} do gem "foo" end @@ -462,100 +462,100 @@ RSpec.describe "bundle install with git sources" do 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" + build_git "myrack", "0.8", path: lib_path("local-myrack") do |s| + s.write "lib/myrack.rb", "puts :LOCAL" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle :install - run "require 'rack'" + run "require 'myrack'" expect(out).to eq("LOCAL") end it "chooses the local repository on runtime" do - build_git "rack", "0.8" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) - update_git "rack", "0.8", path: lib_path("local-rack") do |s| - s.write "lib/rack.rb", "puts :LOCAL" + update_git "myrack", "0.8", path: lib_path("local-myrack") do |s| + s.write "lib/myrack.rb", "puts :LOCAL" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) - run "require 'rack'" + bundle %(config set local.myrack #{lib_path("local-myrack")}) + run "require 'myrack'" 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" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) - 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" + update_git "myrack", "0.8", path: lib_path("local-myrack") do |s| + s.write "myrack.gemspec", build_spec("myrack", "0.8") { runtime "rspec", "> 0" }.first.to_ruby + s.write "lib/myrack.rb", "puts :LOCAL" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle :install - run "require 'rack'" + run "require 'myrack'" expect(out).to eq("LOCAL") end it "updates specs on runtime" do system_gems "nokogiri-1.4.2" - build_git "rack", "0.8" + build_git "myrack", "0.8" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-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| + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) + update_git "myrack", "0.8", path: lib_path("local-myrack") do |s| s.add_dependency "nokogiri", "1.4.2" end - bundle %(config set local.rack #{lib_path("local-rack")}) - run "require 'rack'" + bundle %(config set local.myrack #{lib_path("local-myrack")}) + run "require 'myrack'" lockfile1 = File.read(bundled_app_lock) expect(lockfile1).not_to eq(lockfile0) end it "updates ref on install" do - build_git "rack", "0.8" + build_git "myrack", "0.8" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-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") + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) + update_git "myrack", "0.8", path: lib_path("local-myrack") - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle :install lockfile1 = File.read(bundled_app_lock) @@ -563,18 +563,18 @@ RSpec.describe "bundle install with git sources" do end it "explodes and gives correct solution if given path does not exist on install" do - build_git "rack", "0.8" + build_git "myrack", "0.8" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) 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/) + expect(err).to match(/Cannot use local override for myrack-0.8 because #{Regexp.escape(lib_path("local-myrack").to_s)} does not exist/) - solution = "config unset local.rack" + solution = "config unset local.myrack" expect(err).to match(/Run `bundle #{solution}` to remove the local override/) bundle solution @@ -584,19 +584,19 @@ RSpec.describe "bundle install with git sources" do 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")) + build_git "myrack", "0.8" + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) 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/) + expect(err).to match(/Cannot use local override for myrack-0.8 at #{Regexp.escape(lib_path("local-myrack").to_s)} because :branch is not specified in Gemfile/) - solution = "config unset local.rack" + solution = "config unset local.myrack" expect(err).to match(/Specify a branch or run `bundle #{solution}` to remove the local override/) bundle solution @@ -606,69 +606,69 @@ RSpec.describe "bundle install with git sources" do 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")) + build_git "myrack", "0.8" + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) 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" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) - update_git "rack", "0.8", path: lib_path("local-rack"), branch: "another" do |s| - s.write "lib/rack.rb", "puts :LOCAL" + update_git "myrack", "0.8", path: lib_path("local-myrack"), branch: "another" do |s| + s.write "lib/myrack.rb", "puts :LOCAL" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) 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 "myrack", "0.8" - build_git "rack", "0.8", path: lib_path("local-rack") do |s| - s.write "lib/rack.rb", "puts :LOCAL" + build_git "myrack", "0.8", path: lib_path("local-myrack") do |s| + s.write "lib/myrack.rb", "puts :LOCAL" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) 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 "myrack", "0.8" - build_git "rack", "0.8", path: lib_path("local-rack") do |s| - s.write "lib/rack.rb", "puts :LOCAL" + build_git "myrack", "0.8", path: lib_path("local-myrack") do |s| + s.write "lib/myrack.rb", "puts :LOCAL" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle %(config set disable_local_revision_check true) bundle :install expect(out).to match(/Bundle complete!/) @@ -693,66 +693,66 @@ RSpec.describe "bundle install with git sources" do # end it "installs from git even if a newer gem is available elsewhere" do - build_git "rack", "0.8" + build_git "myrack", "0.8" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}" G - expect(the_bundle).to include_gems "rack 0.8" + expect(the_bundle).to include_gems "myrack 0.8" end it "installs dependencies from git even if a newer gem is available elsewhere" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" - build_lib "rack", "1.0", path: lib_path("nested/bar") do |s| - s.write "lib/rack.rb", "puts 'WIN OVERRIDE'" + build_lib "myrack", "1.0", path: lib_path("nested/bar") do |s| + s.write "lib/myrack.rb", "puts 'WIN OVERRIDE'" end build_git "foo", path: lib_path("nested") do |s| - s.add_dependency "rack", "= 1.0" + s.add_dependency "myrack", "= 1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("nested")}" G - run "require 'rack'" + run "require 'myrack'" 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" + source "https://gem.repo1" + gem "myrack", "0.9.1" G - build_git "rack", path: lib_path("rack") + build_git "myrack", path: lib_path("myrack") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0", :git => "#{lib_path("rack")}" + source "https://gem.repo1" + gem "myrack", "1.0.0", :git => "#{lib_path("myrack")}" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 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" + source "https://gem.repo1" + gem "myrack" G - build_git "rack", "1.2", path: lib_path("rack") + build_git "myrack", "1.2", path: lib_path("myrack") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack")}" G - expect(the_bundle).to include_gems "rack 1.2" + expect(the_bundle).to include_gems "myrack 1.2" end end @@ -762,7 +762,7 @@ RSpec.describe "bundle install with git sources" do build_lib "hi2u", path: lib_path("hi2u") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path("hi2u")}" do gem "omg" gem "hi2u" @@ -779,7 +779,7 @@ RSpec.describe "bundle install with git sources" do update_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{@revision}" G @@ -797,7 +797,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" gem "rails", "2.3.2" G @@ -827,7 +827,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :git => "#{lib_path("foo")}" gem "rails", "2.3.2" G @@ -836,6 +836,32 @@ RSpec.describe "bundle install with git sources" do expect(the_bundle).to include_gems "rails 2.3.2" end + it "runs the gemspec in the context of its parent directory, when using local overrides" do + build_git "foo", path: lib_path("foo"), gemspec: false do |s| + s.write lib_path("foo/lib/foo/version.rb"), %(FOO_VERSION = '1.0') + s.write "foo.gemspec", <<-G + $:.unshift Dir.pwd + require 'lib/foo/version' + Gem::Specification.new do |s| + s.name = 'foo' + s.author = 'no one' + s.version = FOO_VERSION + s.summary = 'Foo' + s.files = Dir["lib/**/*.rb"] + end + G + end + + gemfile <<-G + source "https://gem.repo1" + gem "foo", :git => "https://github.com/gems/foo", branch: "main" + G + + bundle %(config set local.foo #{lib_path("foo")}) + + expect(the_bundle).to include_gems "foo 1.0" + 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'" @@ -844,7 +870,7 @@ RSpec.describe "bundle install with git sources" do build_git "foo", "1.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.0", :git => "#{lib_path("foo-1.0")}" G @@ -855,7 +881,7 @@ RSpec.describe "bundle install with git sources" do build_git "foo", gemspec: false install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.0", :git => "#{lib_path("foo-1.0")}" gem "rails", "2.3.2" G @@ -866,7 +892,7 @@ RSpec.describe "bundle install with git sources" do it "catches git errors and spits out useful output" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.0", :git => "omgomg" G @@ -881,7 +907,7 @@ RSpec.describe "bundle install with git sources" do build_git "foo", path: lib_path("foo space-1.0") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo space-1.0")}" G @@ -892,7 +918,7 @@ RSpec.describe "bundle install with git sources" do build_git "forced", "1.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("forced-1.0")}" do gem 'forced' end @@ -906,7 +932,7 @@ RSpec.describe "bundle install with git sources" do 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")) + git("reset --hard HEAD^", lib_path("forced-1.0")) bundle "update", all: true expect(the_bundle).to include_gems "forced 1.0" @@ -920,16 +946,16 @@ RSpec.describe "bundle install with git sources" do 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") + git "submodule add #{lib_path("submodule-1.0")} submodule-1.0", lib_path("has_submodule-1.0") + git "commit -m \"submodulator\"", lib_path("has_submodule-1.0") install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://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)}/, cached gems or installed locally}) + expect(err).to match(%r{submodule >= 0 could not be found in rubygems repository https://gem.repo1/ or installed locally}) expect(the_bundle).not_to include_gems "has_submodule 1.0" end @@ -942,11 +968,11 @@ RSpec.describe "bundle install with git sources" do 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") + git "submodule add #{lib_path("submodule-1.0")} submodule-1.0", lib_path("has_submodule-1.0") + git "commit -m \"submodulator\"", lib_path("has_submodule-1.0") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("has_submodule-1.0")}", :submodules => true do gem "has_submodule" end @@ -962,11 +988,11 @@ RSpec.describe "bundle install with git sources" do 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") + git "submodule add #{lib_path("submodule-1.0")} submodule-1.0", lib_path("has_submodule-1.0") + git "commit -m \"submodulator\"", lib_path("has_submodule-1.0") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("has_submodule-1.0")}" do gem "has_submodule" end @@ -981,7 +1007,7 @@ RSpec.describe "bundle install with git sources" do git = build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem "foo" end @@ -991,7 +1017,7 @@ RSpec.describe "bundle install with git sources" do update_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :ref => "#{git.ref_for("HEAD^")}" do gem "foo" end @@ -1009,7 +1035,7 @@ RSpec.describe "bundle install with git sources" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1023,7 +1049,7 @@ RSpec.describe "bundle install with git sources" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1038,7 +1064,7 @@ RSpec.describe "bundle install with git sources" do FileUtils.touch(default_bundle_path("bundler")) install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1056,7 +1082,7 @@ RSpec.describe "bundle install with git sources" do build_git "bar", path: lib_path("nested") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("nested")}" gem "bar", :git => "#{lib_path("nested")}" G @@ -1075,12 +1101,12 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :path => "#{lib_path("bar")}" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :git => "#{lib_path("bar")}" G @@ -1089,24 +1115,43 @@ RSpec.describe "bundle install with git sources" do 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" + source "https://gem.repo1" + gem "myrack-obama" + gem "myrack", "1.0.0" G - build_git "rack", "1.0" do |s| + build_git "myrack", "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")}" + source "https://gem.repo1" + gem "myrack-obama" + gem "myrack", "1.0.0", :git => "#{lib_path("myrack-1.0")}" G run "require 'new_file'" expect(out).to eq("USING GIT") end + + it "doesn't explode when removing an explicit exact version from a git gem with dependencies" do + build_lib "activesupport", "7.1.4", path: lib_path("rails/activesupport") + build_git "rails", "7.1.4", path: lib_path("rails") do |s| + s.add_dependency "activesupport", "= 7.1.4" + end + + install_gemfile <<-G + source "https://gem.repo1" + gem "rails", "7.1.4", :git => "#{lib_path("rails")}" + G + + install_gemfile <<-G + source "https://gem.repo1" + gem "rails", :git => "#{lib_path("rails")}" + G + + expect(the_bundle).to include_gem "rails 7.1.4", "activesupport 7.1.4" + end end describe "bundle install after the remote has been updated" do @@ -1114,8 +1159,8 @@ RSpec.describe "bundle install with git sources" do build_git "valim" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "valim", :git => "#{file_uri_for(lib_path("valim-1.0"))}" + source "https://gem.repo1" + gem "valim", :git => "#{lib_path("valim-1.0")}" G old_revision = revision_for(lib_path("valim-1.0")) @@ -1140,14 +1185,14 @@ RSpec.describe "bundle install with git sources" do 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}" + source "https://gem.repo1" + gem "foo", :git => "#{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" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "deadbeef" G expect(err).to include("Revision deadbeef does not exist in the repository") end @@ -1156,8 +1201,8 @@ RSpec.describe "bundle install with git sources" 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" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "deadbeef" G expect(err).to include("Revision deadbeef does not exist in the repository") @@ -1169,7 +1214,7 @@ RSpec.describe "bundle install with git sources" do build_git "valim", path: lib_path("valim") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "valim", "= 1.0", :git => "#{lib_path("valim")}" G @@ -1184,7 +1229,7 @@ RSpec.describe "bundle install with git sources" do it "runs pre-install hooks" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1204,7 +1249,7 @@ RSpec.describe "bundle install with git sources" do it "runs post-install hooks" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1224,7 +1269,7 @@ RSpec.describe "bundle install with git sources" do it "complains if the install hook fails" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1258,7 +1303,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1292,12 +1337,12 @@ RSpec.describe "bundle install with git sources" do 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 -m \"commit for iteration #{i}\" ext/foo.c", git_reader.path) git_commit_sha = git_reader.ref_for("HEAD") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :ref => "#{git_commit_sha}" G @@ -1322,7 +1367,7 @@ RSpec.describe "bundle install with git sources" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1352,7 +1397,7 @@ In Gemfile: end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1365,7 +1410,7 @@ In Gemfile: expect(installed_time).to match(/\A\d+\.\d+\z/) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1393,8 +1438,8 @@ In Gemfile: end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1407,8 +1452,8 @@ In Gemfile: expect(installed_time).to match(/\A\d+\.\d+\z/) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1436,7 +1481,7 @@ In Gemfile: end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1452,7 +1497,7 @@ In Gemfile: expect(installed_time).to match(/\A\d+\.\d+\z/) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "branch2" G @@ -1485,7 +1530,7 @@ In Gemfile: ENV["GIT_WORK_TREE"] = "bar" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("xxxxxx-1.0")}" do gem 'xxxxxx' end @@ -1499,7 +1544,7 @@ In Gemfile: describe "without git installed" do it "prints a better error message when installing" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake", git: "https://github.com/ruby/rake" G @@ -1536,7 +1581,7 @@ In Gemfile: build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem 'foo' end @@ -1549,17 +1594,17 @@ In Gemfile: 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 + it "doesn't need git in the new machine if an installed git gem is copied to another machine" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem 'foo' end G - bundle "config set cache_all true" - bundle :cache + bundle "config set --global path vendor/bundle" + bundle :install simulate_new_machine bundle "install", env: { "PATH" => "" } @@ -1583,7 +1628,7 @@ In Gemfile: build_git "foo", "1.0", path: lib_path("foo") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo")}", :branch => "main" G @@ -1599,7 +1644,7 @@ In Gemfile: it "does not display the password" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "https://#{credentials}@github.com/company/private-repo" do gem "foo" end @@ -1615,7 +1660,7 @@ In Gemfile: it "displays the oauth scheme but not the oauth token" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "https://#{credentials}:x-oauth-basic@github.com/company/private-repo" do gem "foo" end diff --git a/spec/bundler/install/gemfile/groups_spec.rb b/spec/bundler/install/gemfile/groups_spec.rb index f7907a9cad..71871899a2 100644 --- a/spec/bundler/install/gemfile/groups_spec.rb +++ b/spec/bundler/install/gemfile/groups_spec.rb @@ -4,8 +4,8 @@ RSpec.describe "bundle install with groups" do describe "installing with no options" do before :each do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" group :emo do gem "activesupport", "2.3.5" end @@ -14,7 +14,7 @@ RSpec.describe "bundle install with groups" do end it "installs gems in the default group" do - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs gems in a group block into that group" do @@ -40,7 +40,7 @@ RSpec.describe "bundle install with groups" do end it "sets up everything if Bundler.setup is used with no groups" do - output = run("require 'rack'; puts RACK") + output = run("require 'myrack'; puts MYRACK") expect(output).to eq("1.0.0") output = run("require 'activesupport'; puts ACTIVESUPPORT") @@ -74,8 +74,8 @@ RSpec.describe "bundle install with groups" do describe "with gems assigned to a single group" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" group :emo do gem "activesupport", "2.3.5" end @@ -88,13 +88,13 @@ RSpec.describe "bundle install with groups" do it "installs gems in the default group" do bundle "config set --local without emo" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0", groups: [:default] + expect(the_bundle).to include_gems "myrack 1.0.0", groups: [:default] end it "respects global `without` configuration, but does not save it locally" do bundle "config set --global without emo" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0", groups: [:default] + expect(the_bundle).to include_gems "myrack 1.0.0", groups: [:default] bundle "config list" expect(out).not_to include("Set for your local app (#{bundled_app(".bundle/config")}): [:emo]") expect(out).to include("Set for the current user (#{home(".bundle/config")}): [:emo]") @@ -129,13 +129,13 @@ RSpec.describe "bundle install with groups" do it "allows Bundler.setup for specific groups" do bundle "config set --local without emo" bundle :install - run("require 'rack'; puts RACK", :default) + run("require 'myrack'; puts MYRACK", :default) expect(out).to eq("1.0.0") end it "does not effect the resolve" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" group :emo do gem "rails", "2.3.2" @@ -153,7 +153,7 @@ RSpec.describe "bundle install with groups" do bundle :install expect(out).not_to include("activesupport") - expect(the_bundle).to include_gems "rack 1.0.0", groups: [:default] + expect(the_bundle).to include_gems "myrack 1.0.0", groups: [:default] expect(the_bundle).not_to include_gems "activesupport 2.3.5", groups: [:default] ENV["BUNDLE_WITHOUT"] = nil @@ -257,8 +257,8 @@ RSpec.describe "bundle install with groups" do describe "with gems assigned to multiple groups" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" group :emo, :lolercoaster do gem "activesupport", "2.3.5" end @@ -268,20 +268,20 @@ RSpec.describe "bundle install with groups" do it "installs gems in the default group" do bundle "config set --local without emo lolercoaster" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs the gem if any of its groups are installed" do bundle "config set --local without emo" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5" + expect(the_bundle).to include_gems "myrack 1.0.0", "activesupport 2.3.5" end describe "with a gem defined multiple times in different groups" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" group :emo do gem "activesupport", "2.3.5" @@ -316,8 +316,8 @@ RSpec.describe "bundle install with groups" do describe "nesting groups" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" group :emo do group :lolercoaster do gem "activesupport", "2.3.5" @@ -329,13 +329,13 @@ RSpec.describe "bundle install with groups" do it "installs gems in the default group" do bundle "config set --local without emo lolercoaster" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs the gem if any of its groups are installed" do bundle "config set --local without emo" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5" + expect(the_bundle).to include_gems "myrack 1.0.0", "activesupport 2.3.5" end end end @@ -343,8 +343,8 @@ RSpec.describe "bundle install with groups" do describe "when loading only the default group" do it "should not load all groups" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :groups => :development G @@ -352,7 +352,7 @@ RSpec.describe "bundle install with groups" do require "bundler" Bundler.setup :default Bundler.require :default - puts RACK + puts MYRACK begin require "activesupport" rescue LoadError @@ -369,33 +369,33 @@ RSpec.describe "bundle install with groups" do before(:each) do build_repo2 - system_gems "rack-0.9.1" + system_gems "myrack-0.9.1" - bundle "config set --local without rack" + bundle "config set --local without myrack" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + source "https://gem.repo2" + gem "myrack" - group :rack do - gem "rack_middleware" + group :myrack do + gem "myrack_middleware" end G end it "uses the correct versions even if --without was used on the original" do - expect(the_bundle).to include_gems "rack 0.9.1" - expect(the_bundle).not_to include_gems "rack_middleware 1.0" + expect(the_bundle).to include_gems "myrack 0.9.1" + expect(the_bundle).not_to include_gems "myrack_middleware 1.0" simulate_new_machine bundle :install - expect(the_bundle).to include_gems "rack 0.9.1" - expect(the_bundle).to include_gems "rack_middleware 1.0" + expect(the_bundle).to include_gems "myrack 0.9.1" + expect(the_bundle).to include_gems "myrack_middleware 1.0" end it "does not hit the remote a second time" do FileUtils.rm_rf gem_repo2 - bundle "config set --local without rack" + bundle "config set --local without myrack" bundle :install, verbose: true expect(last_command.stdboth).not_to match(/fetching/i) end diff --git a/spec/bundler/install/gemfile/install_if_spec.rb b/spec/bundler/install/gemfile/install_if_spec.rb index c7640d07e1..170b58c4c0 100644 --- a/spec/bundler/install/gemfile/install_if_spec.rb +++ b/spec/bundler/install/gemfile/install_if_spec.rb @@ -3,7 +3,7 @@ RSpec.describe "bundle install with install_if conditionals" do it "follows the install_if DSL" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" install_if(lambda { true }) do gem "activesupport", "2.3.5" end @@ -11,29 +11,29 @@ RSpec.describe "bundle install with install_if conditionals" do install_if(lambda { false }) do gem "foo" end - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems("rack 1.0", "activesupport 2.3.5") + expect(the_bundle).to include_gems("myrack 1.0", "activesupport 2.3.5") expect(the_bundle).not_to include_gems("thin") expect(the_bundle).not_to include_gems("foo") - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo1, "activesupport", "2.3.5" - c.no_checksum "foo", "1.0" - c.checksum gem_repo1, "rack", "1.0.0" - c.no_checksum "thin", "1.0" + c.checksum gem_repo1, "foo", "1.0" + c.checksum gem_repo1, "myrack", "1.0.0" + c.checksum gem_repo1, "thin", "1.0" end expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: activesupport (2.3.5) foo (1.0) - rack (1.0.0) + myrack (1.0.0) thin (1.0) - rack + myrack PLATFORMS #{lockfile_platforms} @@ -41,7 +41,7 @@ RSpec.describe "bundle install with install_if conditionals" do DEPENDENCIES activesupport (= 2.3.5) foo - rack + myrack thin #{checksums} BUNDLED WITH diff --git a/spec/bundler/install/gemfile/lockfile_spec.rb b/spec/bundler/install/gemfile/lockfile_spec.rb index 4601d3e2a8..f80b21e562 100644 --- a/spec/bundler/install/gemfile/lockfile_spec.rb +++ b/spec/bundler/install/gemfile/lockfile_spec.rb @@ -2,9 +2,9 @@ RSpec.describe "bundle install with a lockfile present" do let(:gf) { <<-G } - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G subject do @@ -28,7 +28,7 @@ RSpec.describe "bundle install with a lockfile present" do it "does not evaluate the gemfile twice" do bundle :install - with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" } + with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "myrack 1.0.0" } # The first eval is from the initial install, we're testing that the # second install doesn't double-eval @@ -41,7 +41,7 @@ RSpec.describe "bundle install with a lockfile present" do it "does not evaluate the gemfile twice" do bundle :install - with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "rack 1.0.0" } + with_env_vars("BUNDLER_SPEC_NO_APPEND" => "1") { expect(the_bundle).to include_gem "myrack 1.0.0" } # The first eval is from the initial install, we're testing that the # second install doesn't double-eval diff --git a/spec/bundler/install/gemfile/path_spec.rb b/spec/bundler/install/gemfile/path_spec.rb index a57b7ee560..7525404b24 100644 --- a/spec/bundler/install/gemfile/path_spec.rb +++ b/spec/bundler/install/gemfile/path_spec.rb @@ -16,7 +16,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path("foo-1.0")}" do gem 'foo' end @@ -29,7 +29,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "#{lib_path("foo-1.0")}" G @@ -42,7 +42,7 @@ RSpec.describe "bundle install with explicit source paths" do relative_path = lib_path("foo-1.0").relative_path_from(bundled_app) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "#{relative_path}" G @@ -55,7 +55,7 @@ RSpec.describe "bundle install with explicit source paths" do relative_path = lib_path("foo-1.0").relative_path_from(Pathname.new("~").expand_path) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "~/#{relative_path}" G @@ -70,7 +70,7 @@ RSpec.describe "bundle install with explicit source paths" do relative_path = lib_path("foo-1.0").relative_path_from(Pathname.new("/home/#{username}").expand_path) install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "~#{username}/#{relative_path}" G expect(err).to match("There was an error while trying to use the path `~#{username}/#{relative_path}`.") @@ -81,7 +81,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", path: bundled_app("foo-1.0") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "./foo-1.0" G @@ -93,12 +93,12 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "aaa", path: lib_path("demo/aaa") gemfile lib_path("demo/Gemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec gem "aaa", :path => "./aaa" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "aaa", "1.0" c.no_checksum "demo", "1.0" end @@ -115,7 +115,7 @@ RSpec.describe "bundle install with explicit source paths" do aaa (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -139,7 +139,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", path: bundled_app("foo-1.0") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => File.expand_path("foo-1.0", __dir__) G @@ -148,22 +148,22 @@ RSpec.describe "bundle install with explicit source paths" do end it "installs dependencies from the path even if a newer gem is available elsewhere" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" - build_lib "rack", "1.0", path: lib_path("nested/bar") do |s| - s.write "lib/rack.rb", "puts 'WIN OVERRIDE'" + build_lib "myrack", "1.0", path: lib_path("nested/bar") do |s| + s.write "lib/myrack.rb", "puts 'WIN OVERRIDE'" end build_lib "foo", path: lib_path("nested") do |s| - s.add_dependency "rack", "= 1.0" + s.add_dependency "myrack", "= 1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("nested")}" G - run "require 'rack'" + run "require 'myrack'" expect(out).to eq("WIN OVERRIDE") end @@ -179,7 +179,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", "1.0.0", path: lib_path("omg/foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "omg", :path => "#{lib_path("omg")}" G @@ -190,7 +190,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", "0.0.0.dev", path: lib_path("foo") gemfile <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G @@ -201,7 +201,7 @@ RSpec.describe "bundle install with explicit source paths" do foo (0.0.0.dev) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -223,7 +223,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", "0.0.0.SNAPSHOT", path: lib_path("foo") gemfile <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G @@ -234,7 +234,7 @@ RSpec.describe "bundle install with explicit source paths" do foo (0.0.0.SNAPSHOT) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -256,7 +256,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "omg", "2.0", path: lib_path("omg") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "omg", :path => "#{lib_path("omg")}" G @@ -280,7 +280,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "premailer", :path => "#{lib_path("premailer")}" G @@ -302,7 +302,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo-1.0")}" G @@ -314,17 +314,17 @@ RSpec.describe "bundle install with explicit source paths" do it "supports gemspec syntax" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "1.0" + s.add_dependency "myrack", "1.0" end gemfile lib_path("foo/Gemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G bundle "install", dir: lib_path("foo") expect(the_bundle).to include_gems "foo 1.0", dir: lib_path("foo") - expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("foo") + expect(the_bundle).to include_gems "myrack 1.0", dir: lib_path("foo") end it "does not unlock dependencies of path sources" do @@ -340,13 +340,13 @@ RSpec.describe "bundle install with explicit source paths" do gemfile_path = lib_path("foo/Gemfile") gemfile gemfile_path, <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec G lockfile_path = lib_path("foo/Gemfile.lock") - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "0.1.0" c.checksum gem_repo4, "graphql", "2.0.15" end @@ -359,7 +359,7 @@ RSpec.describe "bundle install with explicit source paths" do graphql (~> 2.0) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: graphql (2.0.15) @@ -385,53 +385,53 @@ RSpec.describe "bundle install with explicit source paths" do it "supports gemspec syntax with an alternative path" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "1.0" + s.add_dependency "myrack", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec :path => "#{lib_path("foo")}" G expect(the_bundle).to include_gems "foo 1.0" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end it "doesn't automatically unlock dependencies when using the gemspec syntax" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", ">= 1.0" + s.add_dependency "myrack", ">= 1.0" end install_gemfile lib_path("foo/Gemfile"), <<-G, dir: lib_path("foo") - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G - build_gem "rack", "1.0.1", to_system: true + build_gem "myrack", "1.0.1", to_system: true bundle "install", dir: lib_path("foo") expect(the_bundle).to include_gems "foo 1.0", dir: lib_path("foo") - expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("foo") + expect(the_bundle).to include_gems "myrack 1.0", dir: lib_path("foo") end it "doesn't automatically unlock dependencies when using the gemspec syntax and the gem has development dependencies" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", ">= 1.0" + s.add_dependency "myrack", ">= 1.0" s.add_development_dependency "activesupport" end install_gemfile lib_path("foo/Gemfile"), <<-G, dir: lib_path("foo") - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G - build_gem "rack", "1.0.1", to_system: true + build_gem "myrack", "1.0.1", to_system: true bundle "install", dir: lib_path("foo") expect(the_bundle).to include_gems "foo 1.0", dir: lib_path("foo") - expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("foo") + expect(the_bundle).to include_gems "myrack 1.0", dir: lib_path("foo") end it "raises if there are multiple gemspecs" do @@ -440,7 +440,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec :path => "#{lib_path("foo")}" G @@ -454,7 +454,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec :path => "#{lib_path("foo")}", :name => "foo" G @@ -467,7 +467,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path("foo-1.0")}" do gem 'foo' end @@ -485,7 +485,7 @@ RSpec.describe "bundle install with explicit source paths" do lib_path("foo-1.0").join("bin/performance").mkpath install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', '1.0', :path => "#{lib_path("foo-1.0")}" G expect(err).to be_empty @@ -495,7 +495,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :path => "#{lib_path("foo-1.0")}" G @@ -508,7 +508,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "hi2u" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "omg" gem "hi2u" @@ -527,7 +527,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" gem "omg", :path => "#{lib_path("omg")}" G @@ -539,7 +539,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", gemspec: false gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", "1.0", :path => "#{lib_path("foo-1.0")}" G @@ -569,18 +569,18 @@ RSpec.describe "bundle install with explicit source paths" do context "existing lockfile" do it "rubygems gems don't re-resolve without changes" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack-obama', '1.0' + source "https://gem.repo1" + gem 'myrack-obama', '1.0' gem 'net-ssh', '1.0' G bundle :check, env: { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) - expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0" + expect(the_bundle).to include_gems "myrack-obama 1.0", "net-ssh 1.0" end it "source path gems w/deps don't re-resolve without changes" do - build_lib "rack-obama", "1.0", path: lib_path("omg") do |s| + build_lib "myrack-obama", "1.0", path: lib_path("omg") do |s| s.add_dependency "yard" end @@ -589,14 +589,14 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack-obama', :path => "#{lib_path("omg")}" + source "https://gem.repo1" + gem 'myrack-obama', :path => "#{lib_path("omg")}" gem 'net-ssh', :path => "#{lib_path("omg")}" G bundle :check, env: { "DEBUG" => "1" } expect(out).to match(/using resolution from the lockfile/) - expect(the_bundle).to include_gems "rack-obama 1.0", "net-ssh 1.0" + expect(the_bundle).to include_gems "myrack-obama 1.0", "net-ssh 1.0" end end @@ -606,7 +606,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo-1.0")}" G @@ -622,7 +622,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "bar", "1.0", path: lib_path("foo/bar") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G end @@ -651,33 +651,33 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "foo", "1.0", path: lib_path("foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo")}" G end it "gets dependencies that are updated in the path" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack" + s.add_dependency "myrack" end bundle "install" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "keeps using the same version if it's compatible" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "0.9.1" + s.add_dependency "myrack", "0.9.1" end bundle "install" - expect(the_bundle).to include_gems "rack 0.9.1" + expect(the_bundle).to include_gems "myrack 0.9.1" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" - c.checksum gem_repo1, "rack", "0.9.1" + c.checksum gem_repo1, "myrack", "0.9.1" end expect(lockfile).to eq <<~G @@ -685,12 +685,12 @@ RSpec.describe "bundle install with explicit source paths" do remote: #{lib_path("foo")} specs: foo (1.0) - rack (= 0.9.1) + myrack (= 0.9.1) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} @@ -703,7 +703,7 @@ RSpec.describe "bundle install with explicit source paths" do G build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack" + s.add_dependency "myrack" end bundle "install" @@ -713,12 +713,12 @@ RSpec.describe "bundle install with explicit source paths" do remote: #{lib_path("foo")} specs: foo (1.0) - rack + myrack GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} @@ -730,21 +730,21 @@ RSpec.describe "bundle install with explicit source paths" do #{Bundler::VERSION} G - expect(the_bundle).to include_gems "rack 0.9.1" + expect(the_bundle).to include_gems "myrack 0.9.1" end it "keeps using the same version even when another dependency is added" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "0.9.1" + s.add_dependency "myrack", "0.9.1" end bundle "install" - expect(the_bundle).to include_gems "rack 0.9.1" + expect(the_bundle).to include_gems "myrack 0.9.1" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" - c.checksum gem_repo1, "rack", "0.9.1" + c.checksum gem_repo1, "myrack", "0.9.1" end expect(lockfile).to eq <<~G @@ -752,12 +752,12 @@ RSpec.describe "bundle install with explicit source paths" do remote: #{lib_path("foo")} specs: foo (1.0) - rack (= 0.9.1) + myrack (= 0.9.1) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} @@ -770,7 +770,7 @@ RSpec.describe "bundle install with explicit source paths" do G build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack" + s.add_dependency "myrack" s.add_dependency "rake", rake_version end @@ -783,13 +783,13 @@ RSpec.describe "bundle install with explicit source paths" do remote: #{lib_path("foo")} specs: foo (1.0) - rack + myrack rake (= #{rake_version}) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) + myrack (0.9.1) rake (#{rake_version}) PLATFORMS @@ -802,15 +802,15 @@ RSpec.describe "bundle install with explicit source paths" do #{Bundler::VERSION} G - expect(the_bundle).to include_gems "rack 0.9.1" + expect(the_bundle).to include_gems "myrack 0.9.1" end it "does not remove existing ruby platform" do build_lib "foo", "1.0", path: lib_path("foo") do |s| - s.add_dependency "rack", "0.9.1" + s.add_dependency "myrack", "0.9.1" end - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end @@ -832,19 +832,19 @@ RSpec.describe "bundle install with explicit source paths" do bundle "lock" - checksums.no_checksum "rack", "0.9.1" + checksums.checksum gem_repo1, "myrack", "0.9.1" expect(lockfile).to eq <<~G PATH remote: #{lib_path("foo")} specs: foo (1.0) - rack (= 0.9.1) + myrack (= 0.9.1) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms("ruby")} @@ -869,12 +869,12 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :git => "#{lib_path("bar")}" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :path => "#{lib_path("bar")}" G @@ -888,7 +888,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar" path "#{lib_path("foo")}" do gem "foo" @@ -898,7 +898,7 @@ RSpec.describe "bundle install with explicit source paths" do build_lib "bar", "1.0", path: lib_path("foo/bar") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path("foo")}" do gem "foo" gem "bar" @@ -915,13 +915,13 @@ RSpec.describe "bundle install with explicit source paths" do gemfile lib_path("private_lib/Gemfile"), <<-G source "http://localgemserver.test" gemspec - gem 'rack' + gem 'myrack' G bundle :install, env: { "DEBUG" => "1" }, artifice: "endpoint", dir: lib_path("private_lib") - expect(out).to match(%r{^HTTP GET http://localgemserver\.test/api/v1/dependencies\?gems=rack$}) + expect(out).to match(%r{^HTTP GET http://localgemserver\.test/api/v1/dependencies\?gems=myrack$}) expect(out).not_to match(/^HTTP GET.*private_lib/) expect(the_bundle).to include_gems "private_lib 2.2", dir: lib_path("private_lib") - expect(the_bundle).to include_gems "rack 1.0", dir: lib_path("private_lib") + expect(the_bundle).to include_gems "myrack 1.0", dir: lib_path("private_lib") end end @@ -929,7 +929,7 @@ RSpec.describe "bundle install with explicit source paths" do it "runs pre-install hooks" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -949,7 +949,7 @@ RSpec.describe "bundle install with explicit source paths" do it "runs post-install hooks" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -969,7 +969,7 @@ RSpec.describe "bundle install with explicit source paths" do it "complains if the install hook fails" do build_git "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -1000,7 +1000,7 @@ RSpec.describe "bundle install with explicit source paths" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo-1.0")}" gem "bar", :path => "#{lib_path("bar-1.0")}" G diff --git a/spec/bundler/install/gemfile/platform_spec.rb b/spec/bundler/install/gemfile/platform_spec.rb index d90dacdc02..820feb18bf 100644 --- a/spec/bundler/install/gemfile/platform_spec.rb +++ b/spec/bundler/install/gemfile/platform_spec.rb @@ -4,30 +4,30 @@ RSpec.describe "bundle install across platforms" do it "maintains the same lockfile if all gems are compatible across platforms" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{not_local} DEPENDENCIES - rack + myrack G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 0.9.1" + expect(the_bundle).to include_gems "myrack 0.9.1" end it "pulls in the correct platform specific gem" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)} + remote: https://gem.repo1 specs: platform_specific (1.0) platform_specific (1.0-java) @@ -40,20 +40,21 @@ RSpec.describe "bundle install across platforms" do platform_specific G - simulate_platform "java" - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + simulate_platform "java" do + install_gemfile <<-G + source "https://gem.repo1" - gem "platform_specific" - G + gem "platform_specific" + G - expect(the_bundle).to include_gems "platform_specific 1.0 JAVA" + expect(the_bundle).to include_gems "platform_specific 1.0 java" + end end it "pulls the pure ruby version on jruby if the java platform is not present in the lockfile and bundler is run in frozen mode", :jruby_only do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)} + remote: https://gem.repo1 specs: platform_specific (1.0) @@ -67,12 +68,12 @@ RSpec.describe "bundle install across platforms" do bundle "config set --local frozen true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G - expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" end context "on universal Rubies" do @@ -80,15 +81,12 @@ RSpec.describe "bundle install across platforms" do build_repo4 do build_gem "darwin_single_arch" do |s| s.platform = "ruby" - s.write "lib/darwin_single_arch.rb", "DARWIN_SINGLE_ARCH = '1.0 RUBY'" end build_gem "darwin_single_arch" do |s| s.platform = "arm64-darwin" - s.write "lib/darwin_single_arch.rb", "DARWIN_SINGLE_ARCH = '1.0 arm64-darwin'" end build_gem "darwin_single_arch" do |s| s.platform = "x86_64-darwin" - s.write "lib/darwin_single_arch.rb", "DARWIN_SINGLE_ARCH = '1.0 x86_64-darwin'" end end end @@ -96,7 +94,7 @@ RSpec.describe "bundle install across platforms" do it "pulls in the correct architecture gem" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: darwin_single_arch (1.0) darwin_single_arch (1.0-arm64-darwin) @@ -109,22 +107,23 @@ RSpec.describe "bundle install across platforms" do darwin_single_arch G - simulate_platform "universal-darwin-21" - simulate_ruby_platform "universal.x86_64-darwin21" do - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + simulate_platform "universal-darwin-21" do + simulate_ruby_platform "universal.x86_64-darwin21" do + install_gemfile <<-G + source "https://gem.repo4" - gem "darwin_single_arch" - G + gem "darwin_single_arch" + G - expect(the_bundle).to include_gems "darwin_single_arch 1.0 x86_64-darwin" + expect(the_bundle).to include_gems "darwin_single_arch 1.0 x86_64-darwin" + end end end it "pulls in the correct architecture gem on arm64e macOS Ruby" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: darwin_single_arch (1.0) darwin_single_arch (1.0-arm64-darwin) @@ -137,41 +136,42 @@ RSpec.describe "bundle install across platforms" do darwin_single_arch G - simulate_platform "universal-darwin-21" - simulate_ruby_platform "universal.arm64e-darwin21" do - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + simulate_platform "universal-darwin-21" do + simulate_ruby_platform "universal.arm64e-darwin21" do + install_gemfile <<-G + source "https://gem.repo4" - gem "darwin_single_arch" - G + gem "darwin_single_arch" + G - expect(the_bundle).to include_gems "darwin_single_arch 1.0 arm64-darwin" + expect(the_bundle).to include_gems "darwin_single_arch 1.0 arm64-darwin" + end end end end it "works with gems that have different dependencies" do - simulate_platform "java" - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + simulate_platform "java" do + install_gemfile <<-G + source "https://gem.repo1" - gem "nokogiri" - G + gem "nokogiri" + G - expect(the_bundle).to include_gems "nokogiri 1.4.2 JAVA", "weakling 0.0.3" + expect(the_bundle).to include_gems "nokogiri 1.4.2 java", "weakling 0.0.3" - simulate_new_machine - bundle "config set --local force_ruby_platform true" - bundle "install" + simulate_new_machine + bundle "config set --local force_ruby_platform true" + bundle "install" - expect(the_bundle).to include_gems "nokogiri 1.4.2" - expect(the_bundle).not_to include_gems "weakling" + expect(the_bundle).to include_gems "nokogiri 1.4.2" + expect(the_bundle).not_to include_gems "weakling" - simulate_new_machine - simulate_platform "java" - bundle "install" + simulate_new_machine + bundle "install" - expect(the_bundle).to include_gems "nokogiri 1.4.2 JAVA", "weakling 0.0.3" + expect(the_bundle).to include_gems "nokogiri 1.4.2 java", "weakling 0.0.3" + end end it "does not keep unneeded platforms for gems that are used" do @@ -179,187 +179,189 @@ RSpec.describe "bundle install across platforms" do build_gem "empyrean", "0.1.0" build_gem "coderay", "1.1.2" build_gem "method_source", "0.9.0" - build_gem("spoon", "0.0.6") {|s| s.add_runtime_dependency "ffi" } + build_gem("spoon", "0.0.6") {|s| s.add_dependency "ffi" } build_gem "pry", "0.11.3" do |s| s.platform = "java" - s.add_runtime_dependency "coderay", "~> 1.1.0" - s.add_runtime_dependency "method_source", "~> 0.9.0" - s.add_runtime_dependency "spoon", "~> 0.0" + s.add_dependency "coderay", "~> 1.1.0" + s.add_dependency "method_source", "~> 0.9.0" + s.add_dependency "spoon", "~> 0.0" end build_gem "pry", "0.11.3" do |s| - s.add_runtime_dependency "coderay", "~> 1.1.0" - s.add_runtime_dependency "method_source", "~> 0.9.0" + s.add_dependency "coderay", "~> 1.1.0" + s.add_dependency "method_source", "~> 0.9.0" end build_gem("ffi", "1.9.23") {|s| s.platform = "java" } build_gem("ffi", "1.9.23") end - simulate_platform java - - install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" - - gem "empyrean", "0.1.0" - gem "pry" - G - - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo4, "coderay", "1.1.2" - c.checksum gem_repo4, "empyrean", "0.1.0" - c.checksum gem_repo4, "ffi", "1.9.23", "java" - c.checksum gem_repo4, "method_source", "0.9.0" - c.checksum gem_repo4, "pry", "0.11.3", "java" - c.checksum gem_repo4, "spoon", "0.0.6" - end + simulate_platform java do + install_gemfile <<-G + source "https://gem.repo4" - expect(lockfile).to eq <<~L - GEM - remote: #{file_uri_for(gem_repo4)}/ - specs: - coderay (1.1.2) - empyrean (0.1.0) - ffi (1.9.23-java) - method_source (0.9.0) - pry (0.11.3-java) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - spoon (~> 0.0) - spoon (0.0.6) - ffi - - PLATFORMS - java - - DEPENDENCIES - empyrean (= 0.1.0) - pry - #{checksums} - BUNDLED WITH - #{Bundler::VERSION} - L + gem "empyrean", "0.1.0" + gem "pry" + G - bundle "lock --add-platform ruby" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "coderay", "1.1.2" + c.checksum gem_repo4, "empyrean", "0.1.0" + c.checksum gem_repo4, "ffi", "1.9.23", "java" + c.checksum gem_repo4, "method_source", "0.9.0" + c.checksum gem_repo4, "pry", "0.11.3", "java" + c.checksum gem_repo4, "spoon", "0.0.6" + end - good_lockfile = <<~L - GEM - remote: #{file_uri_for(gem_repo4)}/ - specs: - coderay (1.1.2) - empyrean (0.1.0) - ffi (1.9.23-java) - method_source (0.9.0) - pry (0.11.3) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - pry (0.11.3-java) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - spoon (~> 0.0) - spoon (0.0.6) - ffi + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + coderay (1.1.2) + empyrean (0.1.0) + ffi (1.9.23-java) + method_source (0.9.0) + pry (0.11.3-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) + spoon (0.0.6) + ffi - PLATFORMS - java - ruby + PLATFORMS + java - DEPENDENCIES - empyrean (= 0.1.0) - pry - #{checksums} - BUNDLED WITH - #{Bundler::VERSION} - L + DEPENDENCIES + empyrean (= 0.1.0) + pry + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L - expect(lockfile).to eq good_lockfile + bundle "lock --add-platform ruby" - bad_lockfile = <<~L - GEM - remote: #{file_uri_for(gem_repo4)}/ - specs: - coderay (1.1.2) - empyrean (0.1.0) - ffi (1.9.23) - ffi (1.9.23-java) - method_source (0.9.0) - pry (0.11.3) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - pry (0.11.3-java) - coderay (~> 1.1.0) - method_source (~> 0.9.0) - spoon (~> 0.0) - spoon (0.0.6) - ffi + checksums.checksum gem_repo4, "pry", "0.11.3" - PLATFORMS - java - ruby + good_lockfile = <<~L + GEM + remote: https://gem.repo4/ + specs: + coderay (1.1.2) + empyrean (0.1.0) + ffi (1.9.23-java) + method_source (0.9.0) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry (0.11.3-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) + spoon (0.0.6) + ffi - DEPENDENCIES - empyrean (= 0.1.0) - pry - #{checksums} - BUNDLED WITH - 1.16.1 - L + PLATFORMS + java + ruby - aggregate_failures do - lockfile bad_lockfile - bundle :install, env: { "BUNDLER_VERSION" => Bundler::VERSION } - expect(lockfile).to eq good_lockfile + DEPENDENCIES + empyrean (= 0.1.0) + pry + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L - lockfile bad_lockfile - bundle :update, all: true, env: { "BUNDLER_VERSION" => Bundler::VERSION } expect(lockfile).to eq good_lockfile - lockfile bad_lockfile - bundle "update ffi", env: { "BUNDLER_VERSION" => Bundler::VERSION } - expect(lockfile).to eq good_lockfile + bad_lockfile = <<~L + GEM + remote: https://gem.repo4/ + specs: + coderay (1.1.2) + empyrean (0.1.0) + ffi (1.9.23) + ffi (1.9.23-java) + method_source (0.9.0) + pry (0.11.3) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry (0.11.3-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) + spoon (0.0.6) + ffi - lockfile bad_lockfile - bundle "update empyrean", env: { "BUNDLER_VERSION" => Bundler::VERSION } - expect(lockfile).to eq good_lockfile + PLATFORMS + java + ruby - lockfile bad_lockfile - bundle :lock, env: { "BUNDLER_VERSION" => Bundler::VERSION } - expect(lockfile).to eq good_lockfile + DEPENDENCIES + empyrean (= 0.1.0) + pry + #{checksums} + BUNDLED WITH + 1.16.1 + L + + aggregate_failures do + lockfile bad_lockfile + bundle :install, env: { "BUNDLER_VERSION" => Bundler::VERSION } + expect(lockfile).to eq good_lockfile + + lockfile bad_lockfile + bundle :update, all: true, env: { "BUNDLER_VERSION" => Bundler::VERSION } + expect(lockfile).to eq good_lockfile + + lockfile bad_lockfile + bundle "update ffi", env: { "BUNDLER_VERSION" => Bundler::VERSION } + expect(lockfile).to eq good_lockfile + + lockfile bad_lockfile + bundle "update empyrean", env: { "BUNDLER_VERSION" => Bundler::VERSION } + expect(lockfile).to eq good_lockfile + + lockfile bad_lockfile + bundle :lock, env: { "BUNDLER_VERSION" => Bundler::VERSION } + expect(lockfile).to eq good_lockfile + end end end it "works with gems with platform-specific dependency having different requirements order" do - simulate_platform x64_mac - - update_repo2 do - build_gem "fspath", "3" - build_gem "image_optim_pack", "1.2.3" do |s| - s.add_runtime_dependency "fspath", ">= 2.1", "< 4" - end - build_gem "image_optim_pack", "1.2.3" do |s| - s.platform = "universal-darwin" - s.add_runtime_dependency "fspath", "< 4", ">= 2.1" + simulate_platform x64_mac do + update_repo2 do + build_gem "fspath", "3" + build_gem "image_optim_pack", "1.2.3" do |s| + s.add_dependency "fspath", ">= 2.1", "< 4" + end + build_gem "image_optim_pack", "1.2.3" do |s| + s.platform = "universal-darwin" + s.add_dependency "fspath", "< 4", ">= 2.1" + end end - end - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - G + install_gemfile <<-G + source "https://gem.repo2" + G - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G + source "https://gem.repo2" - gem "image_optim_pack" - G + gem "image_optim_pack" + G - expect(err).not_to include "Unable to use the platform-specific" + expect(err).not_to include "Unable to use the platform-specific" - expect(the_bundle).to include_gem "image_optim_pack 1.2.3 universal-darwin" + expect(the_bundle).to include_gem "image_optim_pack 1.2.3 universal-darwin" + end end it "fetches gems again after changing the version of Ruby" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G bundle "config set --local path vendor/bundle" @@ -368,18 +370,18 @@ RSpec.describe "bundle install across platforms" do FileUtils.mv(vendored_gems, bundled_app("vendor/bundle", Gem.ruby_engine, "1.8")) bundle :install - expect(vendored_gems("gems/rack-1.0.0")).to exist + expect(vendored_gems("gems/myrack-1.0.0")).to exist end it "keeps existing platforms when installing with force_ruby_platform" do - checksums = checksums_section do |c| - c.no_checksum "platform_specific", "1.0" - c.no_checksum "platform_specific", "1.0", "java" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo1, "platform_specific", "1.0" + c.checksum gem_repo1, "platform_specific", "1.0", "java" end lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: platform_specific (1.0-java) @@ -394,17 +396,17 @@ RSpec.describe "bundle install across platforms" do bundle "config set --local force_ruby_platform true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G checksums.checksum gem_repo1, "platform_specific", "1.0" - expect(the_bundle).to include_gem "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gem "platform_specific 1.0 ruby" expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: platform_specific (1.0) platform_specific (1.0-java) @@ -425,7 +427,7 @@ end RSpec.describe "bundle install with platform conditionals" do it "installs gems tagged w/ the current platforms" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platforms :#{local_tag} do gem "nokogiri" @@ -437,14 +439,14 @@ RSpec.describe "bundle install with platform conditionals" do it "does not install gems tagged w/ another platforms" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" platforms :#{not_local_tag} do gem "nokogiri" end G - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" expect(the_bundle).not_to include_gems "nokogiri 1.4.2" end @@ -458,7 +460,7 @@ RSpec.describe "bundle install with platform conditionals" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "activesupport" @@ -469,7 +471,7 @@ RSpec.describe "bundle install with platform conditionals" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: activesupport (6.1.4.1) tzinfo (~> 2.0) @@ -493,7 +495,7 @@ RSpec.describe "bundle install with platform conditionals" do it "installs gems tagged w/ the current platforms inline" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri", :platforms => :#{local_tag} G expect(the_bundle).to include_gems "nokogiri 1.4.2" @@ -501,17 +503,17 @@ RSpec.describe "bundle install with platform conditionals" do it "does not install gems tagged w/ another platforms inline" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "nokogiri", :platforms => :#{not_local_tag} G - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" expect(the_bundle).not_to include_gems "nokogiri 1.4.2" end it "installs gems tagged w/ the current platform inline" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri", :platform => :#{local_tag} G expect(the_bundle).to include_gems "nokogiri 1.4.2" @@ -519,7 +521,7 @@ RSpec.describe "bundle install with platform conditionals" do it "doesn't install gems tagged w/ another platform inline" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri", :platform => :#{not_local_tag} G expect(the_bundle).not_to include_gems "nokogiri 1.4.2" @@ -529,7 +531,7 @@ RSpec.describe "bundle install with platform conditionals" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platform :#{not_local_tag} do gem "foo", :git => "#{lib_path("foo-1.0")}" end @@ -542,7 +544,7 @@ RSpec.describe "bundle install with platform conditionals" do bundle "config set --local force_ruby_platform true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "some_gem", :platform => :rbx G @@ -553,7 +555,7 @@ RSpec.describe "bundle install with platform conditionals" do it "does not attempt to install gems from other rubies when using --local" do bundle "config set --local force_ruby_platform true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "some_gem", platform: :ruby_22 G @@ -565,9 +567,9 @@ RSpec.describe "bundle install with platform conditionals" do bundle "config set --local force_ruby_platform true" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", :platform => [:windows, :mswin, :mswin64, :mingw, :x64_mingw, :jruby] + gem "myrack", :platform => [:windows, :mswin, :mswin64, :mingw, :x64_mingw, :jruby] G bundle "install" @@ -576,15 +578,15 @@ RSpec.describe "bundle install with platform conditionals" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS ruby DEPENDENCIES - rack - #{checksums_section_when_existing} + myrack + #{checksums_section_when_enabled} BUNDLED WITH #{Bundler::VERSION} L @@ -602,7 +604,7 @@ RSpec.describe "bundle install with platform conditionals" do end install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "listen" gem "ffi", :platform => :windows @@ -613,23 +615,23 @@ end RSpec.describe "when a gem has no architecture" do it "still installs correctly" do - simulate_platform x86_mswin32 - - build_repo2 do - # The rcov gem is platform mswin32, but has no arch - build_gem "rcov" do |s| - s.platform = Gem::Platform.new([nil, "mswin32", nil]) - s.write "lib/rcov.rb", "RCOV = '1.0.0'" + simulate_platform x86_mswin32 do + build_repo2 do + # The rcov gem is platform mswin32, but has no arch + build_gem "rcov" do |s| + s.platform = Gem::Platform.new([nil, "mswin32", nil]) + s.write "lib/rcov.rb", "RCOV = '1.0.0'" + end end - end - gemfile <<-G - # Try to install gem with nil arch - source "http://localgemserver.test/" - gem "rcov" - G + gemfile <<-G + # Try to install gem with nil arch + source "http://localgemserver.test/" + gem "rcov" + G - bundle :install, artifice: "windows", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } - expect(the_bundle).to include_gems "rcov 1.0.0" + bundle :install, artifice: "windows", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + expect(the_bundle).to include_gems "rcov 1.0.0" + end end end diff --git a/spec/bundler/install/gemfile/ruby_spec.rb b/spec/bundler/install/gemfile/ruby_spec.rb index b64d633fd3..3e15d82bbe 100644 --- a/spec/bundler/install/gemfile/ruby_spec.rb +++ b/spec/bundler/install/gemfile/ruby_spec.rb @@ -10,77 +10,77 @@ RSpec.describe "ruby requirement" do # requirement. This test verifies the fix, committed in bfbad5c5. it "allows adding gems" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "#{Gem.ruby_version}" - gem "rack" + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "#{Gem.ruby_version}" - gem "rack" - gem "rack-obama" + gem "myrack" + gem "myrack-obama" G - expect(the_bundle).to include_gems "rack-obama 1.0" + expect(the_bundle).to include_gems "myrack-obama 1.0" end it "allows removing the ruby version requirement" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "~> #{Gem.ruby_version}" - gem "rack" + gem "myrack" G expect(lockfile).to include("RUBY VERSION") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(lockfile).not_to include("RUBY VERSION") end it "allows changing the ruby version requirement to something compatible" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= #{current_ruby_minor}" - gem "rack" + gem "myrack" G allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) expect(locked_ruby_version).to eq(Bundler::RubyVersion.system) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= #{Gem.ruby_version}" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(locked_ruby_version).to eq(Bundler::RubyVersion.system) end it "allows changing the ruby version requirement to something incompatible" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= 1.0.0" - gem "rack" + gem "myrack" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack RUBY VERSION ruby 2.1.4p422 @@ -92,30 +92,30 @@ RSpec.describe "ruby requirement" do allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= #{current_ruby_minor}" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(locked_ruby_version).to eq(Bundler::RubyVersion.system) end it "allows requirements with trailing whitespace" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "#{Gem.ruby_version}\\n \t\\n" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "fails gracefully with malformed requirements" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby ">= 0", "-.\\0" - gem "rack" + gem "myrack" G expect(err).to include("There was an error parsing") # i.e. DSL error, not error template @@ -125,9 +125,9 @@ RSpec.describe "ruby requirement" do create_file ".ruby-version", Gem.ruby_version.to_s install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby file: ".ruby-version" - gem "rack" + gem "myrack" G expect(lockfile).to include("RUBY VERSION") @@ -137,16 +137,16 @@ RSpec.describe "ruby requirement" do create_file ".ruby-version", Gem.ruby_version.to_s gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby file: ".ruby-version" - gem "rack" + gem "myrack" G nested_dir = bundled_app(".ruby-lsp") FileUtils.mkdir nested_dir - create_file ".ruby-lsp/Gemfile", <<-G + gemfile ".ruby-lsp/Gemfile", <<-G eval_gemfile(File.expand_path("../Gemfile", __dir__)) G diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb index a5ba76f4d9..84af5c0d06 100644 --- a/spec/bundler/install/gemfile/sources_spec.rb +++ b/spec/bundler/install/gemfile/sources_spec.rb @@ -2,28 +2,28 @@ RSpec.describe "bundle install with gems on multiple sources" do # repo1 is built automatically before all of the specs run - # it contains rack-obama 1.0.0 and rack 0.9.1 & 1.0.0 amongst other gems + # it contains myrack-obama 1.0.0 and myrack 0.9.1 & 1.0.0 amongst other gems context "without source affinity" do before do - # Oh no! Someone evil is trying to hijack rack :( + # Oh no! Someone evil is trying to hijack myrack :( # need this to be broken to check for correct source ordering - build_repo gem_repo3 do - build_gem "rack", repo3_rack_version do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_repo3 do + build_gem "myrack", repo3_myrack_version do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end end end context "with multiple toplevel sources" do - let(:repo3_rack_version) { "1.0.0" } + let(:repo3_myrack_version) { "1.0.0" } before do gemfile <<-G source "https://gem.repo3" source "https://gem.repo1" - gem "rack-obama" - gem "rack" + gem "myrack-obama" + gem "myrack" G end @@ -33,13 +33,13 @@ RSpec.describe "bundle install with gems on multiple sources" do remote: https://gem.repo3/ remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{local_platform} DEPENDENCIES - depends_on_rack! + depends_on_myrack! BUNDLED WITH #{Bundler::VERSION} @@ -51,9 +51,9 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to eq <<~E.strip [DEPRECATED] Your Gemfile contains multiple global sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source. Bundler found mismatched checksums. This is a potential security risk. - #{checksum_to_lock(gem_repo1, "rack", "1.0.0")} + #{checksum_to_lock(gem_repo1, "myrack", "1.0.0")} from the API at https://gem.repo1/ - #{checksum_to_lock(gem_repo3, "rack", "1.0.0")} + #{checksum_to_lock(gem_repo3, "myrack", "1.0.0")} from the API at https://gem.repo3/ Mismatched checksums each have an authoritative source: @@ -74,9 +74,9 @@ RSpec.describe "bundle install with gems on multiple sources" do it "warns about ambiguous gems, but installs anyway, prioritizing sources last to first", bundler: "< 3" do bundle :install, artifice: "compact_index" - expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") + expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.") expect(err).to include("Installed from: https://gem.repo1") - expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", source: "remote1") + expect(the_bundle).to include_gems("myrack-obama 1.0.0", "myrack 1.0.0", source: "remote1") end it "does not use the full index unnecessarily", bundler: "< 3" do @@ -97,22 +97,22 @@ RSpec.describe "bundle install with gems on multiple sources" do end context "when different versions of the same gem are in multiple sources" do - let(:repo3_rack_version) { "1.2" } + let(:repo3_myrack_version) { "1.2" } before do gemfile <<-G source "https://gem.repo3" source "https://gem.repo1" - gem "rack-obama" - gem "rack", "1.0.0" # force it to install the working version in repo1 + gem "myrack-obama" + gem "myrack", "1.0.0" # force it to install the working version in repo1 G end it "warns about ambiguous gems, but installs anyway", bundler: "< 3" do bundle :install, artifice: "compact_index" - expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") + expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.") expect(err).to include("Installed from: https://gem.repo1") - expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0", source: "remote1") + expect(the_bundle).to include_gems("myrack-obama 1.0.0", "myrack 1.0.0", source: "remote1") end it "fails", bundler: "3" do @@ -154,15 +154,15 @@ RSpec.describe "bundle install with gems on multiple sources" do context "with source affinity" do context "with sources given by a block" do before do - # Oh no! Someone evil is trying to hijack rack :( + # Oh no! Someone evil is trying to hijack myrack :( # need this to be broken to check for correct source ordering - build_repo gem_repo3 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_repo3 do + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end - build_gem "rack-obama" do |s| - s.add_dependency "rack" + build_gem "myrack-obama" do |s| + s.add_dependency "myrack" end end @@ -170,76 +170,76 @@ RSpec.describe "bundle install with gems on multiple sources" do source "https://gem.repo3" source "https://gem.repo1" do gem "thin" # comes first to test name sorting - gem "rack" + gem "myrack" end - gem "rack-obama" # should come from repo3! + gem "myrack-obama" # should come from repo3! G end it "installs the gems without any warning" do bundle :install, artifice: "compact_index" expect(err).not_to include("Warning") - expect(the_bundle).to include_gems("rack-obama 1.0.0") - expect(the_bundle).to include_gems("rack 1.0.0", source: "remote1") + expect(the_bundle).to include_gems("myrack-obama 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0", source: "remote1") end it "can cache and deploy" do bundle :cache, artifice: "compact_index" - expect(bundled_app("vendor/cache/rack-1.0.0.gem")).to exist - expect(bundled_app("vendor/cache/rack-obama-1.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-1.0.0.gem")).to exist + expect(bundled_app("vendor/cache/myrack-obama-1.0.gem")).to exist bundle "config set --local deployment true" bundle :install, artifice: "compact_index" - expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0") + expect(the_bundle).to include_gems("myrack-obama 1.0.0", "myrack 1.0.0") end end context "with sources set by an option" do before do - # Oh no! Someone evil is trying to hijack rack :( + # Oh no! Someone evil is trying to hijack myrack :( # need this to be broken to check for correct source ordering - build_repo gem_repo3 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_repo3 do + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end - build_gem "rack-obama" do |s| - s.add_dependency "rack" + build_gem "myrack-obama" do |s| + s.add_dependency "myrack" end end install_gemfile <<-G, artifice: "compact_index" source "https://gem.repo3" - gem "rack-obama" # should come from repo3! - gem "rack", :source => "https://gem.repo1" + gem "myrack-obama" # should come from repo3! + gem "myrack", :source => "https://gem.repo1" G end it "installs the gems without any warning" do expect(err).not_to include("Warning") - expect(the_bundle).to include_gems("rack-obama 1.0.0", "rack 1.0.0") + expect(the_bundle).to include_gems("myrack-obama 1.0.0", "myrack 1.0.0") end end context "when a pinned gem has an indirect dependency in the pinned source" do before do - build_repo gem_repo3 do - build_gem "depends_on_rack", "1.0.1" do |s| - s.add_dependency "rack" + build_repo3 do + build_gem "depends_on_myrack", "1.0.1" do |s| + s.add_dependency "myrack" end end - # we need a working rack gem in repo3 + # we need a working myrack gem in repo3 update_repo gem_repo3 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end gemfile <<-G source "https://gem.repo2" source "https://gem.repo3" do - gem "depends_on_rack" + gem "depends_on_myrack" end G end @@ -252,7 +252,7 @@ RSpec.describe "bundle install with gems on multiple sources" do it "installs from the same source without any warning" do bundle :install, artifice: "compact_index" expect(err).not_to include("Warning") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote3") end end @@ -260,8 +260,8 @@ RSpec.describe "bundle install with gems on multiple sources" do before do # need this to be broken to check for correct source ordering build_repo gem_repo2 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end end end @@ -269,32 +269,32 @@ RSpec.describe "bundle install with gems on multiple sources" do it "installs from the same source without any warning" do bundle :install, artifice: "compact_index" - expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3") + expect(err).not_to include("Warning: the gem 'myrack' was found in multiple sources.") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote3") # In https://github.com/bundler/bundler/issues/3585 this failed # when there is already a lock file, and the gems are missing, so try again system_gems [] bundle :install, artifice: "compact_index" - expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3") + expect(err).not_to include("Warning: the gem 'myrack' was found in multiple sources.") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote3") end end end context "when a pinned gem has an indirect dependency in a different source" do before do - # In these tests, we need a working rack gem in repo2 and not repo3 + # In these tests, we need a working myrack gem in repo2 and not repo3 - build_repo gem_repo3 do - build_gem "depends_on_rack", "1.0.1" do |s| - s.add_dependency "rack" + build_repo3 do + build_gem "depends_on_myrack", "1.0.1" do |s| + s.add_dependency "myrack" end end build_repo gem_repo2 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end end @@ -303,14 +303,14 @@ RSpec.describe "bundle install with gems on multiple sources" do install_gemfile <<-G, artifice: "compact_index" source "https://gem.repo2" source "https://gem.repo3" do - gem "depends_on_rack" + gem "depends_on_myrack" end G end it "installs from the other source without any warning" do expect(err).not_to include("Warning") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0") end end @@ -320,7 +320,7 @@ RSpec.describe "bundle install with gems on multiple sources" do source "https://gem.repo1" source "https://gem.repo2" source "https://gem.repo3" do - gem "depends_on_rack" + gem "depends_on_myrack" end G end @@ -331,9 +331,9 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to eq(<<~E.strip) [DEPRECATED] Your Gemfile contains multiple global sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source. Bundler found mismatched checksums. This is a potential security risk. - #{checksum_to_lock(gem_repo2, "rack", "1.0.0")} + #{checksum_to_lock(gem_repo2, "myrack", "1.0.0")} from the API at https://gem.repo2/ - #{checksum_to_lock(gem_repo1, "rack", "1.0.0")} + #{checksum_to_lock(gem_repo1, "myrack", "1.0.0")} from the API at https://gem.repo1/ Mismatched checksums each have an authoritative source: @@ -348,20 +348,20 @@ RSpec.describe "bundle install with gems on multiple sources" do end it "fails when the two sources agree, but the local gem calculates a different checksum", bundler: "< 3" do - rack_checksum = "c0ffee11" * 8 - bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => rack_checksum }, raise_on_error: false + myrack_checksum = "c0ffee11" * 8 + bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_MYRACK_CHECKSUM" => myrack_checksum }, raise_on_error: false expect(err).to eq(<<~E.strip) [DEPRECATED] Your Gemfile contains multiple global sources. Using `source` more than once without a block is a security risk, and may result in installing unexpected gems. To resolve this warning, use a block to indicate which gems should come from the secondary source. Bundler found mismatched checksums. This is a potential security risk. - rack (1.0.0) sha256=#{rack_checksum} + myrack (1.0.0) sha256=#{myrack_checksum} from the API at https://gem.repo2/ and the API at https://gem.repo1/ - #{checksum_to_lock(gem_repo2, "rack", "1.0.0")} - from the gem at #{default_bundle_path("cache", "rack-1.0.0.gem")} + #{checksum_to_lock(gem_repo2, "myrack", "1.0.0")} + from the gem at #{default_bundle_path("cache", "myrack-1.0.0.gem")} If you trust the API at https://gem.repo2/, to resolve this issue you can: - 1. remove the gem at #{default_bundle_path("cache", "rack-1.0.0.gem")} + 1. remove the gem at #{default_bundle_path("cache", "myrack-1.0.0.gem")} 2. run `bundle install` To ignore checksum security warnings, disable checksum validation with @@ -371,15 +371,15 @@ RSpec.describe "bundle install with gems on multiple sources" do end it "installs from the other source and warns about ambiguous gems when the sources have the same checksum", bundler: "< 3" do - gem_checksum = checksum_digest(gem_repo2, "rack", "1.0.0") - bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => gem_checksum, "DEBUG" => "1" } + gem_checksum = checksum_digest(gem_repo2, "myrack", "1.0.0") + bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_MYRACK_CHECKSUM" => gem_checksum, "DEBUG" => "1" } - expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") + expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.") expect(err).to include("Installed from: https://gem.repo2") - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo3, "depends_on_rack", "1.0.1" - c.checksum gem_repo2, "rack", "1.0.0" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo3, "depends_on_myrack", "1.0.1" + c.checksum gem_repo2, "myrack", "1.0.0" end expect(lockfile).to eq <<~L @@ -387,26 +387,26 @@ RSpec.describe "bundle install with gems on multiple sources" do remote: https://gem.repo1/ remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) GEM remote: https://gem.repo3/ specs: - depends_on_rack (1.0.1) - rack + depends_on_myrack (1.0.1) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - depends_on_rack! + depends_on_myrack! #{checksums} BUNDLED WITH #{Bundler::VERSION} L previous_lockfile = lockfile - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0") expect(lockfile).to eq(previous_lockfile) end @@ -414,12 +414,12 @@ RSpec.describe "bundle install with gems on multiple sources" do bundle "config set --local disable_checksum_validation true" bundle :install, artifice: "compact_index" - expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") + expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.") expect(err).to include("Installed from: https://gem.repo2") - checksums = checksums_section_when_existing do |c| - c.no_checksum "depends_on_rack", "1.0.1" - c.no_checksum "rack", "1.0.0" + checksums = checksums_section_when_enabled do |c| + c.no_checksum "depends_on_myrack", "1.0.1" + c.no_checksum "myrack", "1.0.0" end expect(lockfile).to eq <<~L @@ -427,26 +427,26 @@ RSpec.describe "bundle install with gems on multiple sources" do remote: https://gem.repo1/ remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) GEM remote: https://gem.repo3/ specs: - depends_on_rack (1.0.1) - rack + depends_on_myrack (1.0.1) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - depends_on_rack! + depends_on_myrack! #{checksums} BUNDLED WITH #{Bundler::VERSION} L previous_lockfile = lockfile - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0") expect(lockfile).to eq(previous_lockfile) end @@ -461,33 +461,33 @@ RSpec.describe "bundle install with gems on multiple sources" do before do # need this to be broken to check for correct source ordering build_repo gem_repo2 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end end gemfile <<-G - source "https://gem.repo3" # contains depends_on_rack - source "https://gem.repo2" # contains broken rack + source "https://gem.repo3" # contains depends_on_myrack + source "https://gem.repo2" # contains broken myrack - gem "depends_on_rack" # installed from gem_repo3 - gem "rack", :source => "https://gem.repo1" + gem "depends_on_myrack" # installed from gem_repo3 + gem "myrack", :source => "https://gem.repo1" G end it "installs the dependency from the pinned source without warning", bundler: "< 3" do bundle :install, artifice: "compact_index" - expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0") + expect(err).not_to include("Warning: the gem 'myrack' was found in multiple sources.") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0") # In https://github.com/rubygems/bundler/issues/3585 this failed # when there is already a lock file, and the gems are missing, so try again system_gems [] bundle :install, artifice: "compact_index" - expect(err).not_to include("Warning: the gem 'rack' was found in multiple sources.") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0") + expect(err).not_to include("Warning: the gem 'myrack' was found in multiple sources.") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0") end it "fails", bundler: "3" do @@ -502,7 +502,7 @@ RSpec.describe "bundle install with gems on multiple sources" do before do build_repo2 - build_repo gem_repo3 do + build_repo3 do build_gem "private_gem_1", "1.0.0" build_gem "private_gem_2", "1.0.0" end @@ -520,7 +520,7 @@ RSpec.describe "bundle install with gems on multiple sources" do it "fails" do bundle :install, artifice: "compact_index", raise_on_error: false - expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/, cached gems or installed locally.") + expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/ or installed locally.") end end @@ -528,7 +528,7 @@ RSpec.describe "bundle install with gems on multiple sources" do before do build_repo2 - build_repo gem_repo3 do + build_repo3 do build_gem "depends_on_missing", "1.0.1" do |s| s.add_dependency "missing" end @@ -560,19 +560,19 @@ RSpec.describe "bundle install with gems on multiple sources" do context "when a top-level gem has an indirect dependency" do before do build_repo gem_repo2 do - build_gem "depends_on_rack", "1.0.1" do |s| - s.add_dependency "rack" + build_gem "depends_on_myrack", "1.0.1" do |s| + s.add_dependency "myrack" end end - build_repo gem_repo3 do + build_repo3 do build_gem "unrelated_gem", "1.0.0" end gemfile <<-G source "https://gem.repo2" - gem "depends_on_rack" + gem "depends_on_myrack" source "https://gem.repo3" do gem "unrelated_gem" @@ -583,15 +583,15 @@ RSpec.describe "bundle install with gems on multiple sources" do context "and the dependency is only in the top-level source" do before do update_repo gem_repo2 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end end it "installs the dependency from the top-level source without warning" do bundle :install, artifice: "compact_index" expect(err).not_to include("Warning") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote2") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", "unrelated_gem 1.0.0") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote2") expect(the_bundle).to include_gems("unrelated_gem 1.0.0", source: "remote3") end end @@ -599,8 +599,8 @@ RSpec.describe "bundle install with gems on multiple sources" do context "and the dependency is only in a pinned source" do before do update_repo gem_repo3 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end end end @@ -610,10 +610,10 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to end_with <<~E.strip Could not find compatible versions - Because every version of depends_on_rack depends on rack >= 0 - and rack >= 0 could not be found in rubygems repository https://gem.repo2/, cached gems or installed locally, - depends_on_rack cannot be used. - So, because Gemfile depends on depends_on_rack >= 0, + Because every version of depends_on_myrack depends on myrack >= 0 + and myrack >= 0 could not be found in rubygems repository https://gem.repo2/ or installed locally, + depends_on_myrack cannot be used. + So, because Gemfile depends on depends_on_myrack >= 0, version solving has failed. E end @@ -622,12 +622,12 @@ RSpec.describe "bundle install with gems on multiple sources" do context "and the dependency is in both the top-level and a pinned source" do before do update_repo gem_repo2 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end update_repo gem_repo3 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end end end @@ -635,9 +635,9 @@ RSpec.describe "bundle install with gems on multiple sources" do it "installs the dependency from the top-level source without warning" do bundle :install, artifice: "compact_index" expect(err).not_to include("Warning") - expect(run("require 'rack'; puts RACK")).to eq("1.0.0") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", "unrelated_gem 1.0.0") - expect(the_bundle).to include_gems("depends_on_rack 1.0.1", "rack 1.0.0", source: "remote2") + expect(run("require 'myrack'; puts MYRACK")).to eq("1.0.0") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", "unrelated_gem 1.0.0") + expect(the_bundle).to include_gems("depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote2") expect(the_bundle).to include_gems("unrelated_gem 1.0.0", source: "remote3") end end @@ -645,13 +645,13 @@ RSpec.describe "bundle install with gems on multiple sources" do context "when a scoped gem has a deeply nested indirect dependency" do before do - build_repo gem_repo3 do - build_gem "depends_on_depends_on_rack", "1.0.1" do |s| - s.add_dependency "depends_on_rack" + build_repo3 do + build_gem "depends_on_depends_on_myrack", "1.0.1" do |s| + s.add_dependency "depends_on_myrack" end - build_gem "depends_on_rack", "1.0.1" do |s| - s.add_dependency "rack" + build_gem "depends_on_myrack", "1.0.1" do |s| + s.add_dependency "myrack" end end @@ -659,7 +659,7 @@ RSpec.describe "bundle install with gems on multiple sources" do source "https://gem.repo2" source "https://gem.repo3" do - gem "depends_on_depends_on_rack" + gem "depends_on_depends_on_myrack" end G end @@ -667,15 +667,15 @@ RSpec.describe "bundle install with gems on multiple sources" do context "and the dependency is only in the top-level source" do before do update_repo gem_repo2 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end end it "installs the dependency from the top-level source" do bundle :install, artifice: "compact_index" - expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0") - expect(the_bundle).to include_gems("rack 1.0.0", source: "remote2") - expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", source: "remote3") + expect(the_bundle).to include_gems("depends_on_depends_on_myrack 1.0.1", "depends_on_myrack 1.0.1", "myrack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0", source: "remote2") + expect(the_bundle).to include_gems("depends_on_depends_on_myrack 1.0.1", "depends_on_myrack 1.0.1", source: "remote3") end end @@ -684,32 +684,32 @@ RSpec.describe "bundle install with gems on multiple sources" do build_repo2 update_repo gem_repo3 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end end it "installs the dependency from the pinned source" do bundle :install, artifice: "compact_index" - expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3") + expect(the_bundle).to include_gems("depends_on_depends_on_myrack 1.0.1", "depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote3") end end context "and the dependency is in both the top-level and a pinned source" do before do update_repo gem_repo2 do - build_gem "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end end update_repo gem_repo3 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end end it "installs the dependency from the pinned source without warning" do bundle :install, artifice: "compact_index" - expect(the_bundle).to include_gems("depends_on_depends_on_rack 1.0.1", "depends_on_rack 1.0.1", "rack 1.0.0", source: "remote3") + expect(the_bundle).to include_gems("depends_on_depends_on_myrack 1.0.1", "depends_on_myrack 1.0.1", "myrack 1.0.0", source: "remote3") end end end @@ -742,12 +742,12 @@ RSpec.describe "bundle install with gems on multiple sources" do end build_gem "minitest", "5.14.3" - build_gem "rack", "2.2.3" + build_gem "myrack", "2.2.3" build_gem "redis", "4.2.5" build_gem "sidekiq", "6.1.3" do |s| s.add_dependency "connection_pool", ">= 2.2.2" - s.add_dependency "rack", "~> 2.0" + s.add_dependency "myrack", "~> 2.0" s.add_dependency "redis", ">= 4.2.0" end @@ -764,7 +764,7 @@ RSpec.describe "bundle install with gems on multiple sources" do build_gem "zeitwerk", "2.4.2" end - build_repo gem_repo3 do + build_repo3 do build_gem "sidekiq-pro", "5.2.1" do |s| s.add_dependency "connection_pool", ">= 2.2.3" s.add_dependency "sidekiq", ">= 6.1.0" @@ -783,13 +783,13 @@ RSpec.describe "bundle install with gems on multiple sources" do end G - @locked_checksums = checksums_section_when_existing do |c| + @locked_checksums = checksums_section_when_enabled do |c| c.checksum gem_repo2, "activesupport", "6.0.3.4" c.checksum gem_repo2, "concurrent-ruby", "1.1.8" c.checksum gem_repo2, "connection_pool", "2.2.3" c.checksum gem_repo2, "i18n", "1.8.9" c.checksum gem_repo2, "minitest", "5.14.3" - c.checksum gem_repo2, "rack", "2.2.3" + c.checksum gem_repo2, "myrack", "2.2.3" c.checksum gem_repo2, "redis", "4.2.5" c.checksum gem_repo2, "sidekiq", "6.1.3" c.checksum gem_repo3, "sidekiq-pro", "5.2.1" @@ -814,11 +814,11 @@ RSpec.describe "bundle install with gems on multiple sources" do i18n (1.8.9) concurrent-ruby (~> 1.0) minitest (5.14.3) - rack (2.2.3) + myrack (2.2.3) redis (4.2.5) sidekiq (6.1.3) connection_pool (>= 2.2.2) - rack (~> 2.0) + myrack (~> 2.0) redis (>= 4.2.0) sidekiq-pro (5.2.1) connection_pool (>= 2.2.3) @@ -866,11 +866,11 @@ RSpec.describe "bundle install with gems on multiple sources" do i18n (1.8.9) concurrent-ruby (~> 1.0) minitest (5.14.3) - rack (2.2.3) + myrack (2.2.3) redis (4.2.5) sidekiq (6.1.3) connection_pool (>= 2.2.2) - rack (~> 2.0) + myrack (~> 2.0) redis (>= 4.2.0) thread_safe (0.3.6) tzinfo (1.2.9) @@ -957,11 +957,11 @@ RSpec.describe "bundle install with gems on multiple sources" do i18n (1.8.9) concurrent-ruby (~> 1.0) minitest (5.14.3) - rack (2.2.3) + myrack (2.2.3) redis (4.2.5) sidekiq (6.1.3) connection_pool (>= 2.2.2) - rack (~> 2.0) + myrack (~> 2.0) redis (>= 4.2.0) tzinfo (2.0.4) concurrent-ruby (~> 1.0) @@ -1014,11 +1014,11 @@ RSpec.describe "bundle install with gems on multiple sources" do i18n (1.8.9) concurrent-ruby (~> 1.0) minitest (5.14.3) - rack (2.2.3) + myrack (2.2.3) redis (4.2.5) sidekiq (6.1.3) connection_pool (>= 2.2.2) - rack (~> 2.0) + myrack (~> 2.0) redis (>= 4.2.0) thread_safe (0.3.6) tzinfo (1.2.9) @@ -1080,7 +1080,7 @@ RSpec.describe "bundle install with gems on multiple sources" do context "when a pinned gem has an indirect dependency with more than one level of indirection in the default source " do before do - build_repo gem_repo3 do + build_repo3 do build_gem "handsoap", "0.2.5.5" do |s| s.add_dependency "nokogiri", ">= 1.2.3" end @@ -1106,7 +1106,7 @@ RSpec.describe "bundle install with gems on multiple sources" do end it "installs from the default source without any warnings or errors and generates a proper lockfile" do - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo3, "handsoap", "0.2.5.5" c.checksum gem_repo2, "nokogiri", "1.11.1" c.checksum gem_repo2, "racca", "1.5.2" @@ -1157,7 +1157,7 @@ RSpec.describe "bundle install with gems on multiple sources" do context "with a gem that is only found in the wrong source" do before do - build_repo gem_repo3 do + build_repo3 do build_gem "not_in_repo1", "1.0.0" end @@ -1174,7 +1174,7 @@ RSpec.describe "bundle install with gems on multiple sources" do context "with an existing lockfile" do before do - system_gems "rack-0.9.1", "rack-1.0.0", path: default_bundle_path + system_gems "myrack-0.9.1", "myrack-1.0.0", path: default_bundle_path lockfile <<-L GEM @@ -1184,26 +1184,26 @@ RSpec.describe "bundle install with gems on multiple sources" do GEM remote: https://gem.repo3 specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack! + myrack! L gemfile <<-G source "https://gem.repo1" source "https://gem.repo3" do - gem 'rack' + gem 'myrack' end G end # Reproduction of https://github.com/rubygems/bundler/issues/3298 it "does not unlock the installed gem on exec" do - expect(the_bundle).to include_gems("rack 0.9.1") + expect(the_bundle).to include_gems("myrack 0.9.1") end end @@ -1214,13 +1214,13 @@ RSpec.describe "bundle install with gems on multiple sources" do remote: https://gem.repo1/ remote: https://gem.repo3/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack! + myrack! #{checksums_section} BUNDLED WITH #{Bundler::VERSION} @@ -1236,13 +1236,13 @@ RSpec.describe "bundle install with gems on multiple sources" do GEM remote: https://gem.repo3/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack! + myrack! BUNDLED WITH #{Bundler::VERSION} @@ -1250,14 +1250,14 @@ RSpec.describe "bundle install with gems on multiple sources" do end before do - build_repo gem_repo3 do - build_gem "rack", "0.9.1" + build_repo3 do + build_gem "myrack", "0.9.1" end gemfile <<-G source "https://gem.repo1" source "https://gem.repo3" do - gem 'rack' + gem 'myrack' end G @@ -1272,7 +1272,7 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(lockfile).to eq(aggregate_gem_section_lockfile) expect(err).to include("Your lockfile contains a single rubygems source section with multiple remotes, which is insecure.") - expect(the_bundle).to include_gems("rack 0.9.1", source: "remote3") + expect(the_bundle).to include_gems("myrack 0.9.1", source: "remote3") end it "prints a checksum warning when the checksums from both sources do not match", bundler: "< 3" do @@ -1280,16 +1280,16 @@ RSpec.describe "bundle install with gems on multiple sources" do bundle "install", artifice: "compact_index", raise_on_error: false - api_checksum1 = checksum_digest(gem_repo1, "rack", "0.9.1") - api_checksum3 = checksum_digest(gem_repo3, "rack", "0.9.1") + api_checksum1 = checksum_digest(gem_repo1, "myrack", "0.9.1") + api_checksum3 = checksum_digest(gem_repo3, "myrack", "0.9.1") expect(exitstatus).to eq(37) expect(err).to eq(<<~E.strip) [DEPRECATED] Your lockfile contains a single rubygems source section with multiple remotes, which is insecure. Make sure you run `bundle install` in non frozen mode and commit the result to make your lockfile secure. Bundler found mismatched checksums. This is a potential security risk. - rack (0.9.1) sha256=#{api_checksum3} + myrack (0.9.1) sha256=#{api_checksum3} from the API at https://gem.repo3/ - rack (0.9.1) sha256=#{api_checksum1} + myrack (0.9.1) sha256=#{api_checksum1} from the API at https://gem.repo1/ Mismatched checksums each have an authoritative source: @@ -1318,8 +1318,8 @@ RSpec.describe "bundle install with gems on multiple sources" do build_lib "foo" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :source => "https://gem.repo1" + source "https://gem.repo1" + gem "myrack", :source => "https://gem.repo1" gem "foo", :path => "#{lib_path("foo-1.0")}" G end @@ -1336,17 +1336,17 @@ RSpec.describe "bundle install with gems on multiple sources" do context "when an older version of the same gem also ships with Ruby" do before do - system_gems "rack-0.9.1" + system_gems "myrack-0.9.1" install_gemfile <<-G, artifice: "compact_index" source "https://gem.repo1" - gem "rack" # should come from repo1! + gem "myrack" # should come from repo1! G end it "installs the gems without any warning" do expect(err).not_to include("Warning") - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") end end @@ -1361,7 +1361,7 @@ RSpec.describe "bundle install with gems on multiple sources" do # Installing this gemfile... gemfile <<-G source 'https://gem.repo1' - gem 'rack' + gem 'myrack' gem 'foo', '~> 0.1', :source => 'https://gem.repo4' gem 'bar', '~> 0.1', :source => 'https://gem.repo4' G @@ -1380,7 +1380,7 @@ RSpec.describe "bundle install with gems on multiple sources" do # And install this gemfile, updating only foo. install_gemfile <<-G, artifice: "compact_index" source 'https://gem.repo1' - gem 'rack' + gem 'myrack' gem 'foo', '~> 0.2', :source => 'https://gem.repo4' gem 'bar', '~> 0.1', :source => 'https://gem.repo4' G @@ -1393,8 +1393,8 @@ RSpec.describe "bundle install with gems on multiple sources" do context "re-resolving" do context "when there is a mix of sources in the gemfile" do before do - build_repo gem_repo3 do - build_gem "rack" + build_repo3 do + build_gem "myrack" end build_lib "path1" @@ -1407,7 +1407,7 @@ RSpec.describe "bundle install with gems on multiple sources" do gem "rails" source "https://gem.repo3" do - gem "rack" + gem "myrack" end gem "path1", :path => "#{lib_path("path1-1.0")}" @@ -1429,14 +1429,14 @@ RSpec.describe "bundle install with gems on multiple sources" do before do install_gemfile <<-G, artifice: "compact_index" source "https://gem.repo1" - gem "rack" + gem "myrack" G end context "and the gemfile changes" do it "is still able to find that gem from remote sources" do build_repo4 do - build_gem "rack", "2.0.1.1.forked" + build_gem "myrack", "2.0.1.1.forked" build_gem "thor", "0.19.1.1.forked" end @@ -1445,10 +1445,10 @@ RSpec.describe "bundle install with gems on multiple sources" do source "https://gem.repo1" source "https://gem.repo4" do - gem "rack", "2.0.1.1.forked" + gem "myrack", "2.0.1.1.forked" gem "thor" end - gem "rack-obama" + gem "myrack-obama" G # Then we change the Gemfile by adding a version to thor @@ -1456,13 +1456,13 @@ RSpec.describe "bundle install with gems on multiple sources" do source "https://gem.repo1" source "https://gem.repo4" do - gem "rack", "2.0.1.1.forked" + gem "myrack", "2.0.1.1.forked" gem "thor", "0.19.1.1.forked" end - gem "rack-obama" + gem "myrack-obama" G - # But we should still be able to find rack 2.0.1.1.forked and install it + # But we should still be able to find myrack 2.0.1.1.forked and install it bundle :install, artifice: "compact_index" end end @@ -1473,30 +1473,30 @@ RSpec.describe "bundle install with gems on multiple sources" do install_gemfile <<-G, artifice: "compact_index" source "https://gem.repo1" - gem "rack" + gem "myrack" G build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end build_gem "bar" end - build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s| + build_lib("gemspec_test", path: tmp("gemspec_test")) do |s| s.add_dependency "bar", "=1.0.0" end install_gemfile <<-G, artifice: "compact_index" source "https://gem.repo2" - gem "rack" - gemspec :path => "#{tmp.join("gemspec_test")}" + gem "myrack" + gemspec :path => "#{tmp("gemspec_test")}" G end it "conservatively installs the existing locked version" do - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") end end @@ -1506,7 +1506,7 @@ RSpec.describe "bundle install with gems on multiple sources" do build_gem "bar" end - build_lib("gemspec_test", path: tmp.join("gemspec_test")) do |s| + build_lib("gemspec_test", path: tmp("gemspec_test")) do |s| s.add_development_dependency "bar" end @@ -1517,7 +1517,7 @@ RSpec.describe "bundle install with gems on multiple sources" do gem "bar" end - gemspec :path => "#{tmp.join("gemspec_test")}" + gemspec :path => "#{tmp("gemspec_test")}" G end @@ -1586,27 +1586,27 @@ RSpec.describe "bundle install with gems on multiple sources" do context "when an indirect dependency is available from multiple ambiguous sources", bundler: "< 3" do it "succeeds but warns, suggesting a source block" do build_repo4 do - build_gem "depends_on_rack" do |s| - s.add_dependency "rack" + build_gem "depends_on_myrack" do |s| + s.add_dependency "myrack" end - build_gem "rack" + build_gem "myrack" end - install_gemfile <<-G, artifice: "compact_index", raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + install_gemfile <<-G, artifice: "compact_index_extra_api", raise_on_error: false + source "https://global.source" - source "https://gem.repo4" do - gem "depends_on_rack" + source "https://scoped.source/extra" do + gem "depends_on_myrack" end - source "https://gem.repo1" do + source "https://scoped.source" do gem "thin" end G expect(err).to eq <<~EOS.strip - Warning: The gem 'rack' was found in multiple relevant sources. - * rubygems repository https://gem.repo1/ - * rubygems repository https://gem.repo4/ + Warning: The gem 'myrack' was found in multiple relevant sources. + * rubygems repository https://scoped.source/ + * rubygems repository https://scoped.source/extra/ You should add this gem to the source block for the source you wish it to be installed from. EOS expect(last_command).to be_success @@ -1617,26 +1617,28 @@ RSpec.describe "bundle install with gems on multiple sources" do context "when an indirect dependency is available from multiple ambiguous sources", bundler: "3" do it "raises, suggesting a source block" do build_repo4 do - build_gem "depends_on_rack" do |s| - s.add_dependency "rack" + build_gem "depends_on_myrack" do |s| + s.add_dependency "myrack" end - build_gem "rack" + build_gem "myrack" end - install_gemfile <<-G, artifice: "compact_index", raise_on_error: false - source "#{file_uri_for(gem_repo1)}" - source "https://gem.repo4" do - gem "depends_on_rack" + install_gemfile <<-G, artifice: "compact_index_extra_api", raise_on_error: false + source "https://global.source" + + source "https://scoped.source/extra" do + gem "depends_on_myrack" end - source "https://gem.repo1" do + + source "https://scoped.source" do gem "thin" end G expect(last_command).to be_failure expect(err).to eq <<~EOS.strip - The gem 'rack' was found in multiple relevant sources. - * rubygems repository https://gem.repo1/ - * rubygems repository https://gem.repo4/ + The gem 'myrack' was found in multiple relevant sources. + * rubygems repository https://scoped.source/ + * rubygems repository https://scoped.source/extra/ You must add this gem to the source block for the source you wish it to be installed from. EOS expect(the_bundle).not_to be_locked @@ -1690,7 +1692,7 @@ RSpec.describe "bundle install with gems on multiple sources" do it "upgrades the lockfile correctly" do bundle "lock --update", artifice: "compact_index" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo2, "capybara", "2.5.0" c.checksum gem_repo4, "mime-types", "3.0.0" end @@ -1740,28 +1742,28 @@ RSpec.describe "bundle install with gems on multiple sources" do end gemfile <<~G - source "https://localgemserver.test" + source "https://gem.repo4" - gem "ruport", "= 1.7.0.3", :source => "https://localgemserver.test/extra" + gem "ruport", "= 1.7.0.3", :source => "https://gem.repo4/extra" G end it "handles that fine" do - bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install", artifice: "compact_index_extra" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "pdf-writer", "1.1.8" c.checksum gem_repo2, "ruport", "1.7.0.3" end expect(lockfile).to eq <<~L GEM - remote: https://localgemserver.test/ + remote: https://gem.repo4/ specs: pdf-writer (1.1.8) GEM - remote: https://localgemserver.test/extra/ + remote: https://gem.repo4/extra/ specs: ruport (1.7.0.3) pdf-writer (= 1.1.8) @@ -1798,28 +1800,28 @@ RSpec.describe "bundle install with gems on multiple sources" do end gemfile <<~G - source "https://localgemserver.test" + source "https://gem.repo4" - gem "ruport", "= 1.7.0.3", :source => "https://localgemserver.test/extra" + gem "ruport", "= 1.7.0.3", :source => "https://gem.repo4/extra" G end it "handles that fine" do - bundle "install", artifice: "compact_index_extra", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install", artifice: "compact_index_extra" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "pdf-writer", "1.1.8" c.checksum gem_repo2, "ruport", "1.7.0.3" end expect(lockfile).to eq <<~L GEM - remote: https://localgemserver.test/ + remote: https://gem.repo4/ specs: pdf-writer (1.1.8) GEM - remote: https://localgemserver.test/extra/ + remote: https://gem.repo4/extra/ specs: ruport (1.7.0.3) pdf-writer (= 1.1.8) @@ -1850,22 +1852,22 @@ RSpec.describe "bundle install with gems on multiple sources" do end gemfile <<~G - source "https://localgemserver.test" + source "https://gem.repo4" gem "pdf-writer", "= 1.1.8" G end it "handles that fine" do - bundle "install --verbose", artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install --verbose", artifice: "endpoint" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "pdf-writer", "1.1.8" end expect(lockfile).to eq <<~L GEM - remote: https://localgemserver.test/ + remote: https://gem.repo4/ specs: pdf-writer (1.1.8) @@ -1919,4 +1921,70 @@ RSpec.describe "bundle install with gems on multiple sources" do expect(err).to include("Could not find gem 'example' in rubygems repository https://gem.repo4/") end end + + context "when a gem has versions in two sources, but only the locked one has updates" do + let(:original_lockfile) do + <<~L + GEM + remote: https://main.source/ + specs: + activesupport (1.0) + bigdecimal + bigdecimal (1.0.0) + + GEM + remote: https://main.source/extra/ + specs: + foo (1.0) + bigdecimal + + PLATFORMS + #{lockfile_platforms} + + DEPENDENCIES + activesupport + foo! + + BUNDLED WITH + #{Bundler::VERSION} + L + end + + before do + build_repo3 do + build_gem "activesupport" do |s| + s.add_dependency "bigdecimal" + end + + build_gem "bigdecimal", "1.0.0" + build_gem "bigdecimal", "3.3.1" + end + + build_repo4 do + build_gem "foo" do |s| + s.add_dependency "bigdecimal" + end + + build_gem "bigdecimal", "1.0.0" + end + + gemfile <<~G + source "https://main.source" + + gem "activesupport" + + source "https://main.source/extra" do + gem "foo" + end + G + + lockfile original_lockfile + end + + it "properly upgrades the lockfile when updating that specific gem" do + bundle "update bigdecimal --conservative", artifice: "compact_index_extra_api", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo3.to_s } + + expect(lockfile).to eq original_lockfile.gsub("bigdecimal (1.0.0)", "bigdecimal (3.3.1)") + end + end end diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb index 5f1b034bfc..a1feadb113 100644 --- a/spec/bundler/install/gemfile/specific_platform_spec.rb +++ b/spec/bundler/install/gemfile/specific_platform_spec.rb @@ -2,7 +2,7 @@ RSpec.describe "bundle install with specific platforms" do let(:google_protobuf) { <<-G } - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "google-protobuf" G @@ -33,7 +33,7 @@ RSpec.describe "bundle install with specific platforms" do # simulate lockfile created with old bundler, which only locks for ruby platform lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: google-protobuf (3.0.0.alpha.5.0.5.1) @@ -55,7 +55,7 @@ RSpec.describe "bundle install with specific platforms" do end end - it "understands that a non-platform specific gem in a new lockfile locked only to RUBY doesn't necessarily mean installing the non-specific variant" do + it "understands that a non-platform specific gem in a new lockfile locked only to ruby doesn't necessarily mean installing the non-specific variant" do simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem @@ -66,14 +66,14 @@ RSpec.describe "bundle install with specific platforms" do gemfile google_protobuf - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo2, "google-protobuf", "3.0.0.alpha.4.0" end # simulate lockfile created with old bundler, which only locks for ruby platform lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: google-protobuf (3.0.0.alpha.4.0) @@ -97,7 +97,7 @@ RSpec.describe "bundle install with specific platforms" do # make sure we're still only locked to ruby expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: google-protobuf (3.0.0.alpha.5.0.5.1) @@ -113,7 +113,7 @@ RSpec.describe "bundle install with specific platforms" do end end - context "when running on a legacy lockfile locked only to RUBY" do + context "when running on a legacy lockfile locked only to ruby" do around do |example| build_repo4 do build_gem "nokogiri", "1.3.10" @@ -124,14 +124,14 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.3.10) @@ -148,13 +148,13 @@ RSpec.describe "bundle install with specific platforms" do simulate_platform "arm64-darwin-22", &example end - it "still installs the generic RUBY variant if necessary" do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + it "still installs the generic ruby variant if necessary" do + bundle "install --verbose" expect(out).to include("Installing nokogiri 1.3.10") end - it "still installs the generic RUBY variant if necessary, even in frozen mode" do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s, "BUNDLE_FROZEN" => "true" } + it "still installs the generic ruby variant if necessary, even in frozen mode" do + bundle "install --verbose", env: { "BUNDLE_FROZEN" => "true" } expect(out).to include("Installing nokogiri 1.3.10") end end @@ -166,7 +166,7 @@ RSpec.describe "bundle install with specific platforms" do build_gem("libv8", "8.4.255.0") {|s| s.platform = "universal-darwin" } build_gem("mini_racer", "1.0.0") do |s| - s.add_runtime_dependency "libv8" + s.add_dependency "libv8" end end @@ -176,14 +176,14 @@ RSpec.describe "bundle install with specific platforms" do bundle "config set --local path vendor/bundle", env: { "BUNDLER_VERSION" => "2.1.4" } gemfile <<-G - source "https://localgemserver.test" + source "https://gem.repo2" gem "libv8" G # simulate lockfile created with old bundler, which only locks for ruby platform lockfile <<-L GEM - remote: https://localgemserver.test/ + remote: https://gem.repo2/ specs: libv8 (8.4.255.0) @@ -197,10 +197,10 @@ RSpec.describe "bundle install with specific platforms" do 2.1.4 L - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_VERSION" => "2.1.4", "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + bundle "install --verbose", env: { "BUNDLER_VERSION" => "2.1.4" } expect(out).to include("Installing libv8 8.4.255.0 (universal-darwin)") - bundle "add mini_racer --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + bundle "add mini_racer --verbose" expect(out).to include("Using libv8 8.4.255.0 (universal-darwin)") end end @@ -213,14 +213,14 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<-G - source "https://localgemserver.test" + source "https://gem.repo4" gem "grpc" G # simulate lockfile created with old bundler, which only locks for ruby platform lockfile <<-L GEM - remote: https://localgemserver.test/ + remote: https://gem.repo4/ specs: grpc (1.50.0) @@ -234,7 +234,7 @@ RSpec.describe "bundle install with specific platforms" do #{Bundler::VERSION} L - bundle "install --verbose", artifice: "compact_index_precompiled_before", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install --verbose", artifice: "compact_index_precompiled_before" expect(out).to include("Installing grpc 1.50.0 (universal-darwin)") end end @@ -268,7 +268,7 @@ RSpec.describe "bundle install with specific platforms" do git = build_git "pg_array_parser", "1.0" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "pg_array_parser", :git => "#{lib_path("pg_array_parser-1.0")}" G @@ -304,7 +304,7 @@ RSpec.describe "bundle install with specific platforms" do simulate_platform "x86_64-darwin-15" do setup_multiplatform_gem_with_different_dependencies_per_platform install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "facter" G allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) @@ -358,14 +358,14 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "sorbet-static", "0.5.6403" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: sorbet-static (0.5.6403-#{Bundler.local_platform}) @@ -389,13 +389,13 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "sorbet-static", "0.5.6433" G error_message = <<~ERROR.strip - Could not find gem 'sorbet-static (= 0.5.6433)' with platform 'arm64-darwin-21' in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally. + Could not find gem 'sorbet-static (= 0.5.6433)' with platform 'arm64-darwin-21' in rubygems repository https://gem.repo4/ or installed locally. The source contains the following gems matching 'sorbet-static (= 0.5.6433)': * sorbet-static-0.5.6433-universal-darwin-20 @@ -425,7 +425,7 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "sorbet", "0.5.6433" G @@ -434,7 +434,7 @@ RSpec.describe "bundle install with specific platforms" do Could not find compatible versions Because every version of sorbet depends on sorbet-static = 0.5.6433 - and sorbet-static = 0.5.6433 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally for any resolution platforms (arm64-darwin-21), + and sorbet-static = 0.5.6433 could not be found in rubygems repository https://gem.repo4/ or installed locally for any resolution platforms (arm64-darwin-21), sorbet cannot be used. So, because Gemfile depends on sorbet = 0.5.6433, version solving has failed. @@ -459,13 +459,13 @@ RSpec.describe "bundle install with specific platforms" do expect(err).to include(error_message).once end - it "does not generate a lockfile if RUBY platform is forced and some gem has no RUBY variant available" do + it "does not generate a lockfile if ruby platform is forced and some gem has no ruby variant available" do build_repo4 do build_gem("sorbet-static", "0.5.9889") {|s| s.platform = Gem::Platform.local } end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "sorbet-static", "0.5.9889" G @@ -473,22 +473,22 @@ RSpec.describe "bundle install with specific platforms" do bundle "lock", raise_on_error: false, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" } expect(err).to include <<~ERROR.rstrip - Could not find gem 'sorbet-static (= 0.5.9889)' with platform 'ruby' in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally. + Could not find gem 'sorbet-static (= 0.5.9889)' with platform 'ruby' in rubygems repository https://gem.repo4/ or installed locally. The source contains the following gems matching 'sorbet-static (= 0.5.9889)': * sorbet-static-0.5.9889-#{Gem::Platform.local} ERROR end - it "automatically fixes the lockfile if RUBY platform is locked and some gem has no RUBY variant available" do + it "automatically fixes the lockfile if ruby platform is locked and some gem has no ruby variant available" do build_repo4 do build_gem("sorbet-static-and-runtime", "0.5.10160") do |s| - s.add_runtime_dependency "sorbet", "= 0.5.10160" - s.add_runtime_dependency "sorbet-runtime", "= 0.5.10160" + s.add_dependency "sorbet", "= 0.5.10160" + s.add_dependency "sorbet-runtime", "= 0.5.10160" end build_gem("sorbet", "0.5.10160") do |s| - s.add_runtime_dependency "sorbet-static", "= 0.5.10160" + s.add_dependency "sorbet-static", "= 0.5.10160" end build_gem("sorbet-runtime", "0.5.10160") @@ -499,14 +499,14 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "sorbet-static-and-runtime" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet (0.5.10160) sorbet-static (= 0.5.10160) @@ -528,7 +528,7 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "sorbet", "0.5.10160" c.checksum gem_repo4, "sorbet-runtime", "0.5.10160" c.checksum gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local @@ -537,7 +537,7 @@ RSpec.describe "bundle install with specific platforms" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet (0.5.10160) sorbet-static (= 0.5.10160) @@ -558,7 +558,7 @@ RSpec.describe "bundle install with specific platforms" do L end - it "automatically fixes the lockfile if both RUBY platform and a more specific platform are locked, and some gem has no RUBY variant available" do + it "automatically fixes the lockfile if both ruby platform and a more specific platform are locked, and some gem has no ruby variant available" do build_repo4 do build_gem "nokogiri", "1.12.0" build_gem "nokogiri", "1.12.0" do |s| @@ -577,21 +577,21 @@ RSpec.describe "bundle install with specific platforms" do simulate_platform "x86_64-darwin-22" do install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" gem "sorbet-static" G end - checksums = checksums_section_when_existing do |c| - c.no_checksum "nokogiri", "1.13.0", "x86_64-darwin" - c.no_checksum "sorbet-static", "0.5.10601", "x86_64-darwin" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "nokogiri", "1.13.0", "x86_64-darwin" + c.checksum gem_repo4, "sorbet-static", "0.5.10601", "x86_64-darwin" end lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.12.0) nokogiri (1.12.0-x86_64-darwin) @@ -615,7 +615,7 @@ RSpec.describe "bundle install with specific platforms" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.13.0-x86_64-darwin) sorbet-static (0.5.10601-x86_64-darwin) @@ -632,15 +632,15 @@ RSpec.describe "bundle install with specific platforms" do L end - it "automatically fixes the lockfile if only RUBY platform is locked and some gem has no RUBY variant available" do + it "automatically fixes the lockfile if only ruby platform is locked and some gem has no ruby variant available" do build_repo4 do build_gem("sorbet-static-and-runtime", "0.5.10160") do |s| - s.add_runtime_dependency "sorbet", "= 0.5.10160" - s.add_runtime_dependency "sorbet-runtime", "= 0.5.10160" + s.add_dependency "sorbet", "= 0.5.10160" + s.add_dependency "sorbet-runtime", "= 0.5.10160" end build_gem("sorbet", "0.5.10160") do |s| - s.add_runtime_dependency "sorbet-static", "= 0.5.10160" + s.add_dependency "sorbet-static", "= 0.5.10160" end build_gem("sorbet-runtime", "0.5.10160") @@ -651,14 +651,14 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "sorbet-static-and-runtime" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet (0.5.10160) sorbet-static (= 0.5.10160) @@ -680,7 +680,7 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "sorbet", "0.5.10160" c.checksum gem_repo4, "sorbet-runtime", "0.5.10160" c.checksum gem_repo4, "sorbet-static", "0.5.10160", Gem::Platform.local @@ -689,7 +689,7 @@ RSpec.describe "bundle install with specific platforms" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet (0.5.10160) sorbet-static (= 0.5.10160) @@ -726,7 +726,7 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" gem "sorbet-static" @@ -734,7 +734,7 @@ RSpec.describe "bundle install with specific platforms" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0-arm-linux) nokogiri (1.14.0-x86_64-linux) @@ -755,14 +755,14 @@ RSpec.describe "bundle install with specific platforms" do bundle "update" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.14.0", "x86_64-linux" c.checksum gem_repo4, "sorbet-static", "0.5.10696", "x86_64-linux" end expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0-x86_64-linux) sorbet-static (0.5.10696-x86_64-linux) @@ -794,12 +794,12 @@ RSpec.describe "bundle install with specific platforms" do # Make sure sorbet-static-0.5.10549-universal-darwin-21 is installed install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "sorbet-static", "= 0.5.10549" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "sorbet-static", "0.5.10549", "universal-darwin-20" c.checksum gem_repo4, "sorbet-static", "0.5.10549", "universal-darwin-21" end @@ -807,7 +807,7 @@ RSpec.describe "bundle install with specific platforms" do # Make sure the lockfile is missing sorbet-static-0.5.10549-universal-darwin-21 lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet-static (0.5.10549-universal-darwin-20) @@ -823,11 +823,9 @@ RSpec.describe "bundle install with specific platforms" do bundle "install" - checksums.no_checksum "sorbet-static", "0.5.10549", "universal-darwin-21" - expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet-static (0.5.10549-universal-darwin-20) sorbet-static (0.5.10549-universal-darwin-21) @@ -844,6 +842,63 @@ RSpec.describe "bundle install with specific platforms" do end end + it "automatically fixes the lockfile if locked only to ruby, and some locked specs don't meed locked dependencies" do + simulate_platform "x86_64-linux" do + build_repo4 do + build_gem("ibandit", "0.7.0") do |s| + s.add_dependency "i18n", "~> 0.7.0" + end + + build_gem("i18n", "0.7.0.beta1") + build_gem("i18n", "0.7.0") + end + + gemfile <<~G + source "https://gem.repo4" + + gem "ibandit", "~> 0.7.0" + G + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + i18n (0.7.0.beta1) + ibandit (0.7.0) + i18n (~> 0.7.0) + + PLATFORMS + ruby + + DEPENDENCIES + ibandit (~> 0.7.0) + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "lock --update i18n" + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + i18n (0.7.0) + ibandit (0.7.0) + i18n (~> 0.7.0) + + PLATFORMS + ruby + + DEPENDENCIES + ibandit (~> 0.7.0) + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile" do build_repo4 do build_gem "nokogiri", "1.13.8" @@ -853,16 +908,21 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" gem "tzinfo", "~> 1.2", platform: :#{not_local_tag} G + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "nokogiri", "1.13.8" + c.checksum gem_repo4, "nokogiri", "1.13.8", Gem::Platform.local + end + original_lockfile = <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.13.8) nokogiri (1.13.8-#{Gem::Platform.local}) @@ -873,9 +933,7 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES nokogiri tzinfo (~> 1.2) - - CHECKSUMS - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -884,20 +942,37 @@ RSpec.describe "bundle install with specific platforms" do bundle "lock --update" - checksums = checksums_section_when_existing do |c| - c.no_checksum "nokogiri", "1.13.8" - c.no_checksum "nokogiri", "1.13.8", Gem::Platform.local + expect(lockfile).to eq(original_lockfile) + end + + it "does not remove ruby if gems for other platforms, and not present in the lockfile, exist in the Gemfile, and the lockfile only has ruby" do + build_repo4 do + build_gem "nokogiri", "1.13.8" + build_gem "nokogiri", "1.13.8" do |s| + s.platform = "arm64-darwin" + end + end + + gemfile <<~G + source "https://gem.repo4" + + gem "nokogiri" + + gem "tzinfo", "~> 1.2", platforms: %i[mingw mswin x64_mingw jruby] + G + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "nokogiri", "1.13.8" end - updated_lockfile = <<~L + original_lockfile = <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.13.8) - nokogiri (1.13.8-#{Gem::Platform.local}) PLATFORMS - #{lockfile_platforms("ruby")} + ruby DEPENDENCIES nokogiri @@ -907,30 +982,36 @@ RSpec.describe "bundle install with specific platforms" do #{Bundler::VERSION} L - expect(lockfile).to eq(updated_lockfile) + lockfile original_lockfile + + simulate_platform "arm64-darwin-23" do + bundle "lock --update" + end + + expect(lockfile).to eq(original_lockfile) end it "does not remove ruby when adding a new gem to the Gemfile" do build_repo4 do build_gem "concurrent-ruby", "1.2.2" - build_gem "rack", "3.0.7" + build_gem "myrack", "3.0.7" end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "concurrent-ruby" - gem "rack" + gem "myrack" G - checksums = checksums_section_when_existing do |c| - c.no_checksum "concurrent-ruby", "1.2.2" - c.no_checksum "rack", "3.0.7" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "concurrent-ruby", "1.2.2" + c.checksum gem_repo4, "myrack", "3.0.7" end lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: concurrent-ruby (1.2.2) @@ -948,17 +1029,17 @@ RSpec.describe "bundle install with specific platforms" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: concurrent-ruby (1.2.2) - rack (3.0.7) + myrack (3.0.7) PLATFORMS #{lockfile_platforms("ruby", generic_local_platform, defaults: [])} DEPENDENCIES concurrent-ruby - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -968,10 +1049,8 @@ RSpec.describe "bundle install with specific platforms" do it "can fallback to a source gem when platform gems are incompatible with current ruby version" do setup_multiplatform_gem_with_source_gem - source = file_uri_for(gem_repo2) - gemfile <<~G - source "#{source}" + source "https://gem.repo2" gem "my-precompiled-gem" G @@ -981,7 +1060,7 @@ RSpec.describe "bundle install with specific platforms" do # - A source gem with compatible ruby version lockfile <<-L GEM - remote: #{source}/ + remote: https://gem.repo2/ specs: my-precompiled-gem (3.0.0) my-precompiled-gem (3.0.0-#{Bundler.local_platform}) @@ -1017,18 +1096,18 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri", "1.14.0" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.14.0", "x86_64-linux" end lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0-x86_64-linux) @@ -1044,13 +1123,13 @@ RSpec.describe "bundle install with specific platforms" do bundle :install - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.14.0" end expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0) @@ -1066,6 +1145,60 @@ RSpec.describe "bundle install with specific platforms" do end end + it "automatically fixes the lockfile when only ruby platform locked, and adding a dependency with subdependencies not valid for ruby" do + simulate_platform "x86_64-linux" do + build_repo4 do + build_gem("sorbet", "0.5.10160") do |s| + s.add_dependency "sorbet-static", "= 0.5.10160" + end + + build_gem("sorbet-static", "0.5.10160") do |s| + s.platform = "x86_64-linux" + end + end + + gemfile <<~G + source "https://gem.repo4" + + gem "sorbet" + G + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + + PLATFORMS + ruby + + DEPENDENCIES + + BUNDLED WITH + #{Bundler::VERSION} + L + + bundle "lock" + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + sorbet (0.5.10160) + sorbet-static (= 0.5.10160) + sorbet-static (0.5.10160-x86_64-linux) + + PLATFORMS + x86_64-linux + + DEPENDENCIES + sorbet + + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + it "locks specific platforms automatically" do simulate_platform "x86_64-linux" do build_repo4 do @@ -1092,23 +1225,23 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" G bundle "lock" - checksums = checksums_section_when_existing do |c| - c.no_checksum "nokogiri", "1.14.0" - c.no_checksum "nokogiri", "1.14.0", "arm-linux" - c.no_checksum "nokogiri", "1.14.0", "x86_64-linux" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "nokogiri", "1.14.0" + c.checksum gem_repo4, "nokogiri", "1.14.0", "arm-linux" + c.checksum gem_repo4, "nokogiri", "1.14.0", "x86_64-linux" end # locks all compatible platforms, excluding Java and Windows expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0) nokogiri (1.14.0-arm-linux) @@ -1127,7 +1260,7 @@ RSpec.describe "bundle install with specific platforms" do L gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" gem "sorbet-static" @@ -1138,13 +1271,13 @@ RSpec.describe "bundle install with specific platforms" do bundle "lock" checksums.delete "nokogiri", "arm-linux" - checksums.no_checksum "sorbet-static", "0.5.10696", "universal-darwin-22" - checksums.no_checksum "sorbet-static", "0.5.10696", "x86_64-linux" + checksums.checksum gem_repo4, "sorbet-static", "0.5.10696", "universal-darwin-22" + checksums.checksum gem_repo4, "sorbet-static", "0.5.10696", "x86_64-linux" # locks only platforms compatible with all gems in the bundle expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0) nokogiri (1.14.0-x86_64-linux) @@ -1182,25 +1315,25 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" gem "sass-embedded" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.15.5" - c.no_checksum "sass-embedded", "1.69.5" + c.checksum gem_repo4, "sass-embedded", "1.69.5" c.checksum gem_repo4, "sass-embedded", "1.69.5", "x86_64-linux-gnu" end simulate_platform "x86_64-linux" do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install --verbose" # locks all compatible platforms, excluding Java and Windows expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.15.5) sass-embedded (1.69.5) @@ -1232,21 +1365,21 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo4, "nokogiri", "1.15.5", "x86_64-linux" end simulate_platform "x86_64-linux" do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install --verbose" expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.15.5-x86_64-linux) @@ -1276,17 +1409,22 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rcee_precompiled", "0.5.0" G simulate_platform host_platform do - bundle "lock", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "lock" + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "rcee_precompiled", "0.5.0", "x86_64-linux" + c.checksum gem_repo4, "rcee_precompiled", "0.5.0", "x86_64-linux-musl" + end expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: rcee_precompiled (0.5.0-x86_64-linux) rcee_precompiled (0.5.0-x86_64-linux-musl) @@ -1297,7 +1435,7 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES rcee_precompiled (= 0.5.0) - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -1318,17 +1456,22 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rcee_precompiled", "0.5.0" G simulate_platform "x86_64-linux-musl" do - bundle "lock", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "lock" + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "rcee_precompiled", "0.5.0", "x86_64-linux-gnu" + c.checksum gem_repo4, "rcee_precompiled", "0.5.0", "x86_64-linux-musl" + end expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: rcee_precompiled (0.5.0-x86_64-linux-gnu) rcee_precompiled (0.5.0-x86_64-linux-musl) @@ -1339,7 +1482,7 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES rcee_precompiled (= 0.5.0) - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -1354,17 +1497,21 @@ RSpec.describe "bundle install with specific platforms" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "rcee_precompiled", "0.5.0" G simulate_platform "x86_64-darwin-15" do - bundle "lock", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "lock" + + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "rcee_precompiled", "0.5.0", "universal-darwin" + end expect(lockfile).to eq(<<~L) GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: rcee_precompiled (0.5.0-universal-darwin) @@ -1373,13 +1520,143 @@ RSpec.describe "bundle install with specific platforms" do DEPENDENCIES rcee_precompiled (= 0.5.0) - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L end end + it "does not re-resolve when a specific platform, but less specific than the current platform, is locked" do + build_repo4 do + build_gem "nokogiri" + end + + gemfile <<~G + source "https://gem.repo4" + + gem "nokogiri" + G + + lockfile <<~L + GEM + remote: https://gem.repo4/ + specs: + nokogiri (1.0) + + PLATFORMS + arm64-darwin + + DEPENDENCIES + nokogiri! + + BUNDLED WITH + #{Bundler::VERSION} + L + + simulate_platform "arm64-darwin-23" do + bundle "install --verbose" + + expect(out).to include("Found no changes, using resolution from the lockfile") + end + end + + it "does not remove generic platform gems locked for a specific platform from lockfile when unlocking an unrelated gem" do + build_repo4 do + build_gem "ffi" + + build_gem "ffi" do |s| + s.platform = "x86_64-linux" + end + + build_gem "nokogiri" + end + + gemfile <<~G + source "https://gem.repo4" + + gem "ffi" + gem "nokogiri" + G + + original_lockfile = <<~L + GEM + remote: https://gem.repo4/ + specs: + ffi (1.0) + nokogiri (1.0) + + PLATFORMS + x86_64-linux + + DEPENDENCIES + ffi + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + + lockfile original_lockfile + + simulate_platform "x86_64-linux" do + bundle "lock --update nokogiri" + + expect(lockfile).to eq(original_lockfile) + end + end + + it "does not remove generic platform gems locked for a specific platform from lockfile when unlocking an unrelated gem, and variants for other platform also locked" do + build_repo4 do + build_gem "ffi" + + build_gem "ffi" do |s| + s.platform = "x86_64-linux" + end + + build_gem "ffi" do |s| + s.platform = "java" + end + + build_gem "nokogiri" + end + + gemfile <<~G + source "https://gem.repo4" + + gem "ffi" + gem "nokogiri" + G + + original_lockfile = <<~L + GEM + remote: https://gem.repo4/ + specs: + ffi (1.0) + ffi (1.0-java) + nokogiri (1.0) + + PLATFORMS + java + x86_64-linux + + DEPENDENCIES + ffi + nokogiri + + BUNDLED WITH + #{Bundler::VERSION} + L + + lockfile original_lockfile + + simulate_platform "x86_64-linux" do + bundle "lock --update nokogiri" + + expect(lockfile).to eq(original_lockfile) + end + end + private def setup_multiplatform_gem @@ -1405,7 +1682,7 @@ RSpec.describe "bundle install with specific platforms" do build_gem("facter", "2.4.6") build_gem("facter", "2.4.6") do |s| s.platform = "universal-darwin" - s.add_runtime_dependency "CFPropertyList" + s.add_dependency "CFPropertyList" end build_gem("CFPropertyList") end diff --git a/spec/bundler/install/gemfile_spec.rb b/spec/bundler/install/gemfile_spec.rb index 158645d3eb..96ed174e9b 100644 --- a/spec/bundler/install/gemfile_spec.rb +++ b/spec/bundler/install/gemfile_spec.rb @@ -4,7 +4,7 @@ RSpec.describe "bundle install" do context "with duplicated gems" do it "will display a warning" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'rails', '~> 4.0.0' gem 'rails', '~> 4.0.0' @@ -16,8 +16,8 @@ RSpec.describe "bundle install" do context "with --gemfile" do it "finds the gemfile" do gemfile bundled_app("NotGemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle :install, gemfile: bundled_app("NotGemfile") @@ -25,15 +25,15 @@ RSpec.describe "bundle install" do # Specify BUNDLE_GEMFILE for `the_bundle` # to retrieve the proper Gemfile ENV["BUNDLE_GEMFILE"] = "NotGemfile" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end context "with gemfile set via config" do before do gemfile bundled_app("NotGemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle "config set --local gemfile #{bundled_app("NotGemfile")}" @@ -42,34 +42,59 @@ RSpec.describe "bundle install" do bundle "install" bundle "list" - expect(out).to include("rack (1.0.0)") + expect(out).to include("myrack (1.0.0)") end it "uses the gemfile while in a subdirectory" do bundled_app("subdir").mkpath bundle "install", dir: bundled_app("subdir") bundle "list", dir: bundled_app("subdir") - expect(out).to include("rack (1.0.0)") + expect(out).to include("myrack (1.0.0)") end end context "with deprecated features" do it "reports that lib is an invalid option" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack", :lib => "rack" + gem "myrack", :lib => "myrack" G bundle :install, raise_on_error: false - expect(err).to match(/You passed :lib as an option for gem 'rack', but it is invalid/) + expect(err).to match(/You passed :lib as an option for gem 'myrack', but it is invalid/) + end + end + + context "when an internal error happens" do + let(:bundler_bug) do + create_file("bundler_bug.rb", <<~RUBY) + require "bundler" + + module Bundler + class Dsl + def source(source, *args, &blk) + nil.name + end + end + end + RUBY + + bundled_app("bundler_bug.rb").to_s + end + + it "shows culprit file and line" do + skip "ruby-core test setup has always \"lib\" in $LOAD_PATH so `require \"bundler\"` always activates the local version rather than using RubyGems gem activation stuff, causing conflicts" if ruby_core? + + install_gemfile "source 'https://gem.repo1'", requires: [bundler_bug], artifice: nil, raise_on_error: false + expect(err).to include("bundler_bug.rb:6") end end context "with engine specified in symbol", :jruby_only do it "does not raise any error parsing Gemfile" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "#{RUBY_VERSION}", :engine => :jruby, :engine_version => "#{RUBY_ENGINE_VERSION}" G @@ -78,19 +103,19 @@ RSpec.describe "bundle install" do it "installation succeeds" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" ruby "#{RUBY_VERSION}", :engine => :jruby, :engine_version => "#{RUBY_ENGINE_VERSION}" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end context "with a Gemfile containing non-US-ASCII characters" do it "reads the Gemfile with the UTF-8 encoding by default" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" str = "Il était une fois ..." puts "The source encoding is: " + str.encoding.name @@ -105,7 +130,7 @@ RSpec.describe "bundle install" do # NOTE: This works thanks to #eval interpreting the magic encoding comment install_gemfile <<-G # encoding: iso-8859-1 - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" str = "Il #{"\xE9".dup.force_encoding("binary")}tait une fois ..." puts "The source encoding is: " + str.encoding.name diff --git a/spec/bundler/install/gems/compact_index_spec.rb b/spec/bundler/install/gems/compact_index_spec.rb index 50add8743b..39064e3b80 100644 --- a/spec/bundler/install/gems/compact_index_spec.rb +++ b/spec/bundler/install/gems/compact_index_spec.rb @@ -7,12 +7,27 @@ RSpec.describe "compact index api" do it "should use the API" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" + end + + it "has a debug mode" do + gemfile <<-G + source "#{source_uri}" + gem "myrack" + G + + bundle :install, artifice: "compact_index", env: { "DEBUG_COMPACT_INDEX" => "true" } + expect(out).to include("Fetching gem metadata from #{source_uri}") + expect(err).to include("[Bundler::CompactIndexClient] available?") + expect(err).to include("[Bundler::CompactIndexClient] fetching versions") + expect(err).to include("[Bundler::CompactIndexClient] info(myrack)") + expect(err).to include("[Bundler::CompactIndexClient] fetching info/myrack") + expect(the_bundle).to include_gems "myrack 1.0.0" end it "should URI encode gem names" do @@ -45,22 +60,22 @@ RSpec.describe "compact index api" do it "should handle case sensitivity conflicts" do build_repo4(build_compact_index: false) do - build_gem "rack", "1.0" do |s| - s.add_runtime_dependency("Rack", "0.1") + build_gem "myrack", "1.0" do |s| + s.add_dependency("Myrack", "0.1") end - build_gem "Rack", "0.1" + build_gem "Myrack", "0.1" end install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem "rack", "1.0" - gem "Rack", "0.1" + gem "myrack", "1.0" + gem "Myrack", "0.1" G # can't use `include_gems` here since the `require` will conflict on a # case-insensitive FS - run "Bundler.require; puts Gem.loaded_specs.values_at('rack', 'Rack').map(&:full_name)" - expect(out).to eq("rack-1.0\nRack-0.1") + run "Bundler.require; puts Gem.loaded_specs.values_at('myrack', 'Myrack').map(&:full_name)" + expect(out).to eq("myrack-1.0\nMyrack-0.1") end it "should handle multiple gem dependencies on the same gem" do @@ -76,7 +91,7 @@ RSpec.describe "compact index api" do it "should use the endpoint when using deployment mode" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index" @@ -84,7 +99,7 @@ RSpec.describe "compact index api" do bundle "config set --local path vendor/bundle" bundle :install, artifice: "compact_index" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "handles git dependencies that are in rubygems" do @@ -95,7 +110,7 @@ RSpec.describe "compact index api" do gemfile <<-G source "#{source_uri}" - git "#{file_uri_for(lib_path("foo-1.0"))}" do + git "#{lib_path("foo-1.0")}" do gem 'foo' end G @@ -113,7 +128,7 @@ RSpec.describe "compact index api" do gemfile <<-G source "#{source_uri}" - gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}" + gem 'foo', :git => "#{lib_path("foo-1.0")}" G bundle :install, artifice: "compact_index" @@ -128,7 +143,7 @@ RSpec.describe "compact index api" do build_git "foo" gemfile <<-G source "#{source_uri}" - gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}" + gem 'foo', :git => "#{lib_path("foo-1.0")}" G bundle "install", artifice: "compact_index" @@ -141,31 +156,31 @@ RSpec.describe "compact index api" do it "falls back when the API URL returns 403 Forbidden" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, verbose: true, artifice: "compact_index_forbidden" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "falls back when the versions endpoint has a checksum mismatch" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, verbose: true, artifice: "compact_index_checksum_mismatch" expect(out).to include("Fetching gem metadata from #{source_uri}") expect(out).to include("The checksum of /versions does not match the checksum provided by the server!") expect(out).to include('Calculated checksums {"sha-256"=>"8KfZiM/fszVkqhP/m5s9lvE6M9xKu4I1bU4Izddp5Ms="} did not match expected {"sha-256"=>"ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="}') - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "shows proper path when permission errors happen", :permissions do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G versions = Pathname.new(Bundler.rubygems.user_home).join( @@ -188,28 +203,28 @@ RSpec.describe "compact index api" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "handles host redirects" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index_host_redirect" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "handles host redirects without Gem::Net::HTTP::Persistent" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G FileUtils.mkdir_p lib_path @@ -227,13 +242,13 @@ RSpec.describe "compact index api" do bundle :install, artifice: "compact_index_host_redirect", requires: [lib_path("disable_net_http_persistent.rb")] expect(out).to_not match(/Too many redirects/) - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "times out when Bundler::Fetcher redirects too much" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index_redirects", raise_on_error: false @@ -244,23 +259,23 @@ RSpec.describe "compact index api" do it "should use the modern index for install" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --full-index", artifice: "compact_index" expect(out).to include("Fetching source index from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "should use the modern index for update" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "update --full-index", artifice: "compact_index", all: true expect(out).to include("Fetching source index from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end @@ -288,16 +303,16 @@ RSpec.describe "compact index api" do end end - system_gems %w[rack-1.0.0 thin-1.0 net_a-1.0], gem_repo: gem_repo2 + system_gems %w[myrack-1.0.0 thin-1.0 net_a-1.0], gem_repo: gem_repo2 bundle "config set --local path.system true" ENV["BUNDLER_SPEC_ALL_REQUESTS"] = <<~EOS.strip #{source_uri}/versions - #{source_uri}/info/rack + #{source_uri}/info/myrack EOS install_gemfile <<-G, artifice: "compact_index", verbose: true, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } source "#{source_uri}" - gem "rack" + gem "myrack" G expect(last_command.stdboth).not_to include "Double checking" @@ -342,24 +357,24 @@ RSpec.describe "compact index api" do it "fetches gem versions even when those gems are already installed" do gemfile <<-G source "#{source_uri}" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G bundle :install, artifice: "compact_index_extra_api" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" build_repo4 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end end gemfile <<-G source "#{source_uri}" do; end source "#{source_uri}/extra" - gem "rack", "1.2" + gem "myrack", "1.2" G bundle :install, artifice: "compact_index_extra_api" - expect(the_bundle).to include_gems "rack 1.2" + expect(the_bundle).to include_gems "myrack 1.2" end it "considers all possible versions of dependencies from all api gem sources", bundler: "< 3" do @@ -519,56 +534,56 @@ RSpec.describe "compact index api" do it "installs the binstubs", bundler: "< 3" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --binstubs", artifice: "compact_index" - gembin "rackup" + gembin "myrackup" expect(out).to eq("1.0.0") end it "installs the bins when using --path and uses autoclean", bundler: "< 3" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --path vendor/bundle", artifice: "compact_index" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "installs the bins when using --path and uses bundle clean", bundler: "< 3" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --path vendor/bundle --no-clean", artifice: "compact_index" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "prints post_install_messages" do gemfile <<-G source "#{source_uri}" - gem 'rack-obama' + gem 'myrack-obama' G bundle :install, artifice: "compact_index" - expect(out).to include("Post-install message from rack:") + expect(out).to include("Post-install message from myrack:") end it "should display the post install message for a dependency" do gemfile <<-G source "#{source_uri}" - gem 'rack_middleware' + gem 'myrack_middleware' G bundle :install, artifice: "compact_index" - expect(out).to include("Post-install message from rack:") - expect(out).to include("Rack's post install message") + expect(out).to include("Post-install message from myrack:") + expect(out).to include("Myrack's post install message") end context "when using basic authentication" do @@ -585,53 +600,53 @@ RSpec.describe "compact index api" do it "passes basic authentication details and strips out creds" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index_basic_authentication" expect(out).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "passes basic authentication details and strips out creds also in verbose mode" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, verbose: true, artifice: "compact_index_basic_authentication" expect(out).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "strips http basic auth creds when warning about ambiguous sources", bundler: "< 3" do gemfile <<-G source "#{basic_auth_source_uri}" source "#{file_uri_for(gem_repo1)}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index_basic_authentication" - expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") + expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.") expect(err).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "does not pass the user / password to different hosts on redirect" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index_creds_diff_host" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end describe "with authentication details in bundle config" do before do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G end @@ -641,7 +656,7 @@ RSpec.describe "compact index api" do bundle :install, artifice: "compact_index_strict_basic_authentication" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "reads authentication details by full url from bundle config" do @@ -651,26 +666,26 @@ RSpec.describe "compact index api" do bundle :install, artifice: "compact_index_strict_basic_authentication" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "should use the API" do bundle "config set #{source_hostname} #{user}:#{password}" bundle :install, artifice: "compact_index_strict_basic_authentication" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "prefers auth supplied in the source uri" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle "config set #{source_hostname} otheruser:wrong" bundle :install, artifice: "compact_index_strict_basic_authentication" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "shows instructions if auth is not provided for the source" do @@ -701,11 +716,11 @@ RSpec.describe "compact index api" do it "passes basic authentication details" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index_basic_authentication" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end end @@ -726,10 +741,10 @@ RSpec.describe "compact index api" do it "explains what to do to get it" do gemfile <<-G source "#{source_uri.gsub(/http/, "https")}" - gem "rack" + gem "myrack" G - bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false + bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false, artifice: nil expect(err).to include("OpenSSL") end end @@ -746,7 +761,7 @@ RSpec.describe "compact index api" do end source "#{source_uri.gsub(/http/, "https")}" - gem "rack" + gem "myrack" G bundle :install, raise_on_error: false @@ -763,7 +778,7 @@ RSpec.describe "compact index api" do begin gemfile <<-G source "#{source_uri}" - gem 'rack' + gem 'myrack' G bundle :install, artifice: "compact_index_forbidden" @@ -782,7 +797,7 @@ RSpec.describe "compact index api" do gemfile <<-G source "#{source_uri}" - gem 'rack', '0.9.1' + gem 'myrack', '0.9.1' G # Initial install creates the cached versions file and etag file @@ -794,20 +809,20 @@ RSpec.describe "compact index api" do # Update the Gemfile so we can check subsequent install was successful gemfile <<-G source "#{source_uri}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G # Second install should match etag bundle :install, artifice: "compact_index_etag_match" expect(versions_etag.binread).to eq(previous_content) - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "performs full update when range is ignored" do gemfile <<-G source "#{source_uri}" - gem 'rack', '0.9.1' + gem 'myrack', '0.9.1' G # Initial install creates the cached versions file and etag file @@ -815,7 +830,7 @@ RSpec.describe "compact index api" do gemfile <<-G source "#{source_uri}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G versions = Pathname.new(Bundler.rubygems.user_home).join( @@ -828,36 +843,36 @@ RSpec.describe "compact index api" do bundle :install, artifice: "compact_index_range_ignored" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "performs partial update with a non-empty range" do build_repo4 do - build_gem "rack", "0.9.1" + build_gem "myrack", "0.9.1" end # Initial install creates the cached versions file install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem 'rack', '0.9.1' + gem 'myrack', '0.9.1' G update_repo4 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end install_gemfile <<-G, artifice: "compact_index_partial_update", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "performs partial update while local cache is updated by another process" do gemfile <<-G source "#{source_uri}" - gem 'rack' + gem 'myrack' G # Create a partial cache versions file @@ -871,92 +886,92 @@ RSpec.describe "compact index api" do bundle :install, artifice: "compact_index_concurrent_download" expect(versions.read).to start_with("created_at") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "performs a partial update that fails digest check, then a full update" do build_repo4 do - build_gem "rack", "0.9.1" + build_gem "myrack", "0.9.1" end install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem 'rack', '0.9.1' + gem 'myrack', '0.9.1' G update_repo4 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end install_gemfile <<-G, artifice: "compact_index_partial_update_bad_digest", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "performs full update if server endpoints serve partial content responses but don't have incremental content and provide no digest" do build_repo4 do - build_gem "rack", "0.9.1" + build_gem "myrack", "0.9.1" end install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem 'rack', '0.9.1' + gem 'myrack', '0.9.1' G update_repo4 do - build_gem "rack", "1.0.0" + build_gem "myrack", "1.0.0" end install_gemfile <<-G, artifice: "compact_index_partial_update_no_digest_not_incremental", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } source "#{source_uri}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "performs full update of compact index info cache if range is not satisfiable" do gemfile <<-G source "#{source_uri}" - gem 'rack', '0.9.1' + gem 'myrack', '0.9.1' G bundle :install, artifice: "compact_index" + cache_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5") + # We must remove the etag so that we don't ignore the range and get a 304 Not Modified. - rake_info_etag_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index", - "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "info-etags", "rack-11690b09f16021ff06a6857d784a1870") - File.unlink(rake_info_etag_path) if File.exist?(rake_info_etag_path) + myrack_info_etag_path = File.join(cache_path, "info-etags", "myrack-92f3313ce5721296f14445c3a6b9c073") + File.unlink(myrack_info_etag_path) if File.exist?(myrack_info_etag_path) - rake_info_path = File.join(Bundler.rubygems.user_home, ".bundle", "cache", "compact_index", - "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "info", "rack") - expected_rack_info_content = File.read(rake_info_path) + myrack_info_path = File.join(cache_path, "info", "myrack") + expected_myrack_info_content = File.read(myrack_info_path) # Modify the cache files to make the range not satisfiable - File.open(rake_info_path, "a") {|f| f << "0.9.2 |checksum:c55b525b421fd833a93171ad3d7f04528ca8e87d99ac273f8933038942a5888c" } + File.open(myrack_info_path, "a") {|f| f << "0.9.2 |checksum:c55b525b421fd833a93171ad3d7f04528ca8e87d99ac273f8933038942a5888c" } # Update the Gemfile so the next install does its normal things gemfile <<-G source "#{source_uri}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G # The cache files now being longer means the requested range is going to be not satisfiable # Bundler must end up requesting the whole file to fix things up. bundle :install, artifice: "compact_index_range_not_satisfiable" - resulting_rack_info_content = File.read(rake_info_path) + resulting_myrack_info_content = File.read(myrack_info_path) - expect(resulting_rack_info_content).to eq(expected_rack_info_content) + expect(resulting_myrack_info_content).to eq(expected_myrack_info_content) end it "fails gracefully when the source URI has an invalid scheme" do install_gemfile <<-G, raise_on_error: false source "htps://rubygems.org" - gem "rack" + gem "myrack" G expect(exitstatus).to eq(15) expect(err).to end_with(<<-E.strip) @@ -970,7 +985,7 @@ RSpec.describe "compact index api" do GEM remote: #{source_uri} specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS ruby @@ -983,35 +998,35 @@ RSpec.describe "compact index api" do end it "handles checksums from the server in base64" do - api_checksum = checksum_digest(gem_repo1, "rack", "1.0.0") - rack_checksum = [[api_checksum].pack("H*")].pack("m0") - install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => rack_checksum } + api_checksum = checksum_digest(gem_repo1, "myrack", "1.0.0") + myrack_checksum = [[api_checksum].pack("H*")].pack("m0") + install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_MYRACK_CHECKSUM" => myrack_checksum } source "#{source_uri}" - gem "rack" + gem "myrack" G expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") end it "raises when the checksum does not match" do install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum", raise_on_error: false source "#{source_uri}" - gem "rack" + gem "myrack" G gem_path = if Bundler.feature_flag.global_gem_cache? - default_cache_path.dirname.join("cache", "gems", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "rack-1.0.0.gem") + default_cache_path.dirname.join("cache", "gems", "localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5", "myrack-1.0.0.gem") else - default_cache_path.dirname.join("rack-1.0.0.gem") + default_cache_path.dirname.join("myrack-1.0.0.gem") end expect(exitstatus).to eq(37) expect(err).to eq <<~E.strip Bundler found mismatched checksums. This is a potential security risk. - rack (1.0.0) sha256=2222222222222222222222222222222222222222222222222222222222222222 + myrack (1.0.0) sha256=2222222222222222222222222222222222222222222222222222222222222222 from the API at http://localgemserver.test/ - #{checksum_to_lock(gem_repo1, "rack", "1.0.0")} + #{checksum_to_lock(gem_repo1, "myrack", "1.0.0")} from the gem at #{gem_path} If you trust the API at http://localgemserver.test/, to resolve this issue you can: @@ -1024,19 +1039,19 @@ RSpec.describe "compact index api" do end it "raises when the checksum is the wrong length" do - install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum", env: { "BUNDLER_SPEC_RACK_CHECKSUM" => "checksum!", "DEBUG" => "1" }, verbose: true, raise_on_error: false + install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum", env: { "BUNDLER_SPEC_MYRACK_CHECKSUM" => "checksum!", "DEBUG" => "1" }, verbose: true, raise_on_error: false source "#{source_uri}" - gem "rack" + gem "myrack" G expect(exitstatus).to eq(14) - expect(err).to include('Invalid checksum for rack-0.9.1: "checksum!" is not a valid SHA256 hex or base64 digest') + expect(err).to include('Invalid checksum for myrack-0.9.1: "checksum!" is not a valid SHA256 hex or base64 digest') end it "does not raise when disable_checksum_validation is set" do bundle "config set disable_checksum_validation true" install_gemfile <<-G, artifice: "compact_index_wrong_gem_checksum" source "#{source_uri}" - gem "rack" + gem "myrack" G end end @@ -1045,7 +1060,7 @@ RSpec.describe "compact index api" do install_gemfile <<-G, artifice: "compact_index" File.umask(0000) source "#{source_uri}" - gem "rack" + gem "myrack" G end @@ -1068,7 +1083,7 @@ Running `bundle update rails` should fix the problem. it "does not duplicate specs in the lockfile when updating and a dependency is not installed" do install_gemfile <<-G, artifice: "compact_index" - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" source "#{source_uri}" do gem "rails" gem "activemerchant" diff --git a/spec/bundler/realworld/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_fallback_spec.rb index ee5c0e3d0a..5e700ea976 100644 --- a/spec/bundler/realworld/dependency_api_spec.rb +++ b/spec/bundler/install/gems/dependency_api_fallback_spec.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require_relative "../support/silent_logger" +require_relative "../../support/silent_logger" -RSpec.describe "gemcutter's dependency API", realworld: true do +RSpec.describe "gemcutter's dependency API" do context "when Gemcutter API takes too long to respond" do before do require_rack @@ -10,7 +10,10 @@ RSpec.describe "gemcutter's dependency API", realworld: true do port = find_unused_port @server_uri = "http://127.0.0.1:#{port}" - require_relative "../support/artifice/endpoint_timeout" + require_relative "../../support/artifice/endpoint_timeout" + + # mustermann depends on URI::RFC2396_PARSER behavior + URI.parser = URI::RFC2396_PARSER if URI.respond_to?(:parser=) @t = Thread.new do server = Rack::Server.start(app: EndpointTimeout, @@ -31,16 +34,18 @@ RSpec.describe "gemcutter's dependency API", realworld: true do Artifice.deactivate @t.kill @t.join + + URI.parser = URI::DEFAULT_PARSER if URI.respond_to?(:parser=) end it "times out and falls back on the modern index" do - install_gemfile <<-G, artifice: nil + install_gemfile <<-G, artifice: nil, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } source "#{@server_uri}" - gem "rack" + gem "myrack" G expect(out).to include("Fetching source index from #{@server_uri}/") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end end diff --git a/spec/bundler/install/gems/dependency_api_spec.rb b/spec/bundler/install/gems/dependency_api_spec.rb index 35468b3a1c..7396843f1d 100644 --- a/spec/bundler/install/gems/dependency_api_spec.rb +++ b/spec/bundler/install/gems/dependency_api_spec.rb @@ -7,12 +7,12 @@ RSpec.describe "gemcutter's dependency API" do it "should use the API" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "should URI encode gem names" do @@ -56,7 +56,7 @@ RSpec.describe "gemcutter's dependency API" do it "should use the endpoint when using deployment mode" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint" @@ -64,7 +64,7 @@ RSpec.describe "gemcutter's dependency API" do bundle "config set --local path vendor/bundle" bundle :install, artifice: "endpoint" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "handles git dependencies that are in rubygems" do @@ -75,7 +75,7 @@ RSpec.describe "gemcutter's dependency API" do gemfile <<-G source "#{source_uri}" - git "#{file_uri_for(lib_path("foo-1.0"))}" do + git "#{lib_path("foo-1.0")}" do gem 'foo' end G @@ -93,7 +93,7 @@ RSpec.describe "gemcutter's dependency API" do gemfile <<-G source "#{source_uri}" - gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}" + gem 'foo', :git => "#{lib_path("foo-1.0")}" G bundle :install, artifice: "endpoint" @@ -108,7 +108,7 @@ RSpec.describe "gemcutter's dependency API" do build_git "foo" gemfile <<-G source "#{source_uri}" - gem 'foo', :git => "#{file_uri_for(lib_path("foo-1.0"))}" + gem 'foo', :git => "#{lib_path("foo-1.0")}" G bundle "install", artifice: "endpoint" @@ -119,24 +119,24 @@ RSpec.describe "gemcutter's dependency API" do end it "falls back when the API errors out" do - simulate_platform x86_mswin32 - - build_repo2 do - # The rcov gem is platform mswin32, but has no arch - build_gem "rcov" do |s| - s.platform = Gem::Platform.new([nil, "mswin32", nil]) - s.write "lib/rcov.rb", "RCOV = '1.0.0'" + simulate_platform x86_mswin32 do + build_repo2 do + # The rcov gem is platform mswin32, but has no arch + build_gem "rcov" do |s| + s.platform = Gem::Platform.new([nil, "mswin32", nil]) + s.write "lib/rcov.rb", "RCOV = '1.0.0'" + end end - end - gemfile <<-G - source "#{source_uri}" - gem "rcov" - G + gemfile <<-G + source "#{source_uri}" + gem "rcov" + G - bundle :install, artifice: "windows", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } - expect(out).to include("Fetching source index from #{source_uri}") - expect(the_bundle).to include_gems "rcov 1.0.0" + bundle :install, artifice: "windows", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + expect(out).to include("Fetching source index from #{source_uri}") + expect(the_bundle).to include_gems "rcov 1.0.0" + end end it "falls back when hitting the Gemcutter Dependency Limit" do @@ -147,7 +147,7 @@ RSpec.describe "gemcutter's dependency API" do gem "actionmailer" gem "activeresource" gem "thin" - gem "rack" + gem "myrack" gem "rails" G bundle :install, artifice: "endpoint_fallback" @@ -160,7 +160,7 @@ RSpec.describe "gemcutter's dependency API" do "activeresource 2.3.2", "activesupport 2.3.2", "thin 1.0.0", - "rack 1.0.0", + "myrack 1.0.0", "rails 2.3.2" ) end @@ -168,39 +168,39 @@ RSpec.describe "gemcutter's dependency API" do it "falls back when Gemcutter API doesn't return proper Marshal format" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, verbose: true, artifice: "endpoint_marshal_fail" expect(out).to include("could not fetch from the dependency API, trying the full index") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "falls back when the API URL returns 403 Forbidden" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, verbose: true, artifice: "endpoint_api_forbidden" expect(out).to include("Fetching source index from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "handles host redirects" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_host_redirect" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "handles host redirects without Gem::Net::HTTP::Persistent" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G FileUtils.mkdir_p lib_path @@ -218,13 +218,13 @@ RSpec.describe "gemcutter's dependency API" do bundle :install, artifice: "endpoint_host_redirect", requires: [lib_path("disable_net_http_persistent.rb")] expect(out).to_not match(/Too many redirects/) - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "timeouts when Bundler::Fetcher redirects too much" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_redirect", raise_on_error: false @@ -235,23 +235,23 @@ RSpec.describe "gemcutter's dependency API" do it "should use the modern index for install" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --full-index", artifice: "endpoint" expect(out).to include("Fetching source index from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "should use the modern index for update" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "update --full-index", artifice: "endpoint", all: true expect(out).to include("Fetching source index from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end @@ -295,23 +295,23 @@ RSpec.describe "gemcutter's dependency API" do it "fetches gem versions even when those gems are already installed" do gemfile <<-G source "#{source_uri}" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G bundle :install, artifice: "endpoint_extra_api" build_repo4 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end end gemfile <<-G source "#{source_uri}" do; end source "#{source_uri}/extra" - gem "rack", "1.2" + gem "myrack", "1.2" G bundle :install, artifice: "endpoint_extra_api" - expect(the_bundle).to include_gems "rack 1.2" + expect(the_bundle).to include_gems "myrack 1.2" end it "considers all possible versions of dependencies from all api gem sources", bundler: "< 3" do @@ -475,56 +475,56 @@ RSpec.describe "gemcutter's dependency API" do it "installs the binstubs", bundler: "< 3" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --binstubs", artifice: "endpoint" - gembin "rackup" + gembin "myrackup" expect(out).to eq("1.0.0") end it "installs the bins when using --path and uses autoclean", bundler: "< 3" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --path vendor/bundle", artifice: "endpoint" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "installs the bins when using --path and uses bundle clean", bundler: "< 3" do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G bundle "install --path vendor/bundle --no-clean", artifice: "endpoint" - expect(vendored_gems("bin/rackup")).to exist + expect(vendored_gems("bin/myrackup")).to exist end it "prints post_install_messages" do gemfile <<-G source "#{source_uri}" - gem 'rack-obama' + gem 'myrack-obama' G bundle :install, artifice: "endpoint" - expect(out).to include("Post-install message from rack:") + expect(out).to include("Post-install message from myrack:") end it "should display the post install message for a dependency" do gemfile <<-G source "#{source_uri}" - gem 'rack_middleware' + gem 'myrack_middleware' G bundle :install, artifice: "endpoint" - expect(out).to include("Post-install message from rack:") - expect(out).to include("Rack's post install message") + expect(out).to include("Post-install message from myrack:") + expect(out).to include("Myrack's post install message") end context "when using basic authentication" do @@ -541,40 +541,40 @@ RSpec.describe "gemcutter's dependency API" do it "passes basic authentication details and strips out creds" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_basic_authentication" expect(out).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "passes basic authentication details and strips out creds also in verbose mode" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, verbose: true, artifice: "endpoint_basic_authentication" expect(out).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "strips http basic authentication creds for modern index" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_marshal_fail_basic_authentication" expect(out).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "strips http basic auth creds when it can't reach the server" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_500", raise_on_error: false @@ -585,30 +585,30 @@ RSpec.describe "gemcutter's dependency API" do gemfile <<-G source "#{basic_auth_source_uri}" source "#{file_uri_for(gem_repo1)}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_basic_authentication" - expect(err).to include("Warning: the gem 'rack' was found in multiple sources.") + expect(err).to include("Warning: the gem 'myrack' was found in multiple sources.") expect(err).not_to include("#{user}:#{password}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "does not pass the user / password to different hosts on redirect" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_creds_diff_host" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end describe "with host including dashes" do before do gemfile <<-G source "http://local-gemserver.test" - gem "rack" + gem "myrack" G end @@ -616,7 +616,7 @@ RSpec.describe "gemcutter's dependency API" do bundle :install, artifice: "endpoint_strict_basic_authentication", env: { "BUNDLE_LOCAL___GEMSERVER__TEST" => "#{user}:#{password}" } expect(out).to include("Fetching gem metadata from http://local-gemserver.test") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end @@ -624,7 +624,7 @@ RSpec.describe "gemcutter's dependency API" do before do gemfile <<-G source "#{source_uri}" - gem "rack" + gem "myrack" G end @@ -634,7 +634,7 @@ RSpec.describe "gemcutter's dependency API" do bundle :install, artifice: "endpoint_strict_basic_authentication" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "reads authentication details by full url from bundle config" do @@ -644,26 +644,26 @@ RSpec.describe "gemcutter's dependency API" do bundle :install, artifice: "endpoint_strict_basic_authentication" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "should use the API" do bundle "config set #{source_hostname} #{user}:#{password}" bundle :install, artifice: "endpoint_strict_basic_authentication" expect(out).to include("Fetching gem metadata from #{source_uri}") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "prefers auth supplied in the source uri" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle "config set #{source_hostname} otheruser:wrong" bundle :install, artifice: "endpoint_strict_basic_authentication" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "shows instructions if auth is not provided for the source" do @@ -685,11 +685,11 @@ RSpec.describe "gemcutter's dependency API" do it "passes basic authentication details" do gemfile <<-G source "#{basic_auth_source_uri}" - gem "rack" + gem "myrack" G bundle :install, artifice: "endpoint_basic_authentication" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end end @@ -710,10 +710,10 @@ RSpec.describe "gemcutter's dependency API" do it "explains what to do to get it" do gemfile <<-G source "#{source_uri.gsub(/http/, "https")}" - gem "rack" + gem "myrack" G - bundle :install, env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false + bundle :install, artifice: "fail", env: { "RUBYOPT" => opt_add("-I#{bundled_app("broken_ssl")}", ENV["RUBYOPT"]) }, raise_on_error: false expect(err).to include("OpenSSL") end end @@ -730,7 +730,7 @@ RSpec.describe "gemcutter's dependency API" do end source "#{source_uri.gsub(/http/, "https")}" - gem "rack" + gem "myrack" G bundle :install, raise_on_error: false @@ -747,7 +747,7 @@ RSpec.describe "gemcutter's dependency API" do begin gemfile <<-G source "#{source_uri}" - gem 'rack' + gem 'myrack' G bundle "install", artifice: "endpoint_marshal_fail" diff --git a/spec/bundler/install/gems/env_spec.rb b/spec/bundler/install/gems/env_spec.rb index a6dfadcfc8..6d5aa456fe 100644 --- a/spec/bundler/install/gems/env_spec.rb +++ b/spec/bundler/install/gems/env_spec.rb @@ -4,104 +4,104 @@ RSpec.describe "bundle install with ENV conditionals" do describe "when just setting an ENV key as a string" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" env "BUNDLER_TEST" do - gem "rack" + gem "myrack" end G end it "excludes the gems when the ENV variable is not set" do bundle :install - expect(the_bundle).not_to include_gems "rack" + expect(the_bundle).not_to include_gems "myrack" end it "includes the gems when the ENV variable is set" do ENV["BUNDLER_TEST"] = "1" bundle :install - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end describe "when just setting an ENV key as a symbol" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" env :BUNDLER_TEST do - gem "rack" + gem "myrack" end G end it "excludes the gems when the ENV variable is not set" do bundle :install - expect(the_bundle).not_to include_gems "rack" + expect(the_bundle).not_to include_gems "myrack" end it "includes the gems when the ENV variable is set" do ENV["BUNDLER_TEST"] = "1" bundle :install - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end describe "when setting a string to match the env" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" env "BUNDLER_TEST" => "foo" do - gem "rack" + gem "myrack" end G end it "excludes the gems when the ENV variable is not set" do bundle :install - expect(the_bundle).not_to include_gems "rack" + expect(the_bundle).not_to include_gems "myrack" end it "excludes the gems when the ENV variable is set but does not match the condition" do ENV["BUNDLER_TEST"] = "1" bundle :install - expect(the_bundle).not_to include_gems "rack" + expect(the_bundle).not_to include_gems "myrack" end it "includes the gems when the ENV variable is set and matches the condition" do ENV["BUNDLER_TEST"] = "foo" bundle :install - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end describe "when setting a regex to match the env" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" env "BUNDLER_TEST" => /foo/ do - gem "rack" + gem "myrack" end G end it "excludes the gems when the ENV variable is not set" do bundle :install - expect(the_bundle).not_to include_gems "rack" + expect(the_bundle).not_to include_gems "myrack" end it "excludes the gems when the ENV variable is set but does not match the condition" do ENV["BUNDLER_TEST"] = "fo" bundle :install - expect(the_bundle).not_to include_gems "rack" + expect(the_bundle).not_to include_gems "myrack" end it "includes the gems when the ENV variable is set and matches the condition" do ENV["BUNDLER_TEST"] = "foobar" bundle :install - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end end diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb index 8ef3984975..b7e1b5f1bd 100644 --- a/spec/bundler/install/gems/flex_spec.rb +++ b/spec/bundler/install/gems/flex_spec.rb @@ -3,30 +3,30 @@ RSpec.describe "bundle flex_install" do it "installs the gems as expected" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(the_bundle).to be_locked end it "installs even when the lockfile is invalid" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(the_bundle).to be_locked gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', '1.0' + source "https://gem.repo1" + gem 'myrack', '1.0' G bundle :install - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(the_bundle).to be_locked end @@ -34,19 +34,19 @@ RSpec.describe "bundle flex_install" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack-obama" + source "https://gem.repo2" + gem "myrack-obama" G - expect(the_bundle).to include_gems "rack 1.0.0", "rack-obama 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0", "myrack-obama 1.0.0" update_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack-obama", "1.0" + source "https://gem.repo2" + gem "myrack-obama", "1.0" G - expect(the_bundle).to include_gems "rack 1.0.0", "rack-obama 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0", "myrack-obama 1.0.0" end describe "adding new gems" do @@ -54,38 +54,38 @@ RSpec.describe "bundle flex_install" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G update_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' gem 'activesupport', '2.3.5' G - expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.5" + expect(the_bundle).to include_gems "myrack 1.0.0", "activesupport 2.3.5" end it "keeps child dependencies pinned" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack-obama" + source "https://gem.repo2" + gem "myrack-obama" G update_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack-obama" + source "https://gem.repo2" + gem "myrack-obama" gem "thin" G - expect(the_bundle).to include_gems "rack 1.0.0", "rack-obama 1.0", "thin 1.0" + expect(the_bundle).to include_gems "myrack 1.0.0", "myrack-obama 1.0", "thin 1.0" end end @@ -93,43 +93,43 @@ RSpec.describe "bundle flex_install" do it "removes gems without changing the versions of remaining gems" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' gem 'activesupport', '2.3.5' G update_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(the_bundle).not_to include_gems "activesupport 2.3.5" install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' gem 'activesupport', '2.3.2' G - expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.2" + expect(the_bundle).to include_gems "myrack 1.0.0", "activesupport 2.3.2" end it "removes top level dependencies when removed from the Gemfile while leaving other dependencies intact" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' gem 'activesupport', '2.3.5' G update_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G expect(the_bundle).not_to include_gems "activesupport 2.3.5" @@ -138,21 +138,21 @@ RSpec.describe "bundle flex_install" do it "removes child dependencies" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem 'rack-obama' + source "https://gem.repo2" + gem 'myrack-obama' gem 'activesupport' G - expect(the_bundle).to include_gems "rack 1.0.0", "rack-obama 1.0.0", "activesupport 2.3.5" + expect(the_bundle).to include_gems "myrack 1.0.0", "myrack-obama 1.0.0", "activesupport 2.3.5" update_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'activesupport' G expect(the_bundle).to include_gems "activesupport 2.3.5" - expect(the_bundle).not_to include_gems "rack-obama", "rack" + expect(the_bundle).not_to include_gems "myrack-obama", "myrack" end end @@ -160,25 +160,25 @@ RSpec.describe "bundle flex_install" do before(:each) do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack_middleware" + source "https://gem.repo2" + gem "myrack_middleware" G - expect(the_bundle).to include_gems "rack_middleware 1.0", "rack 0.9.1" + expect(the_bundle).to include_gems "myrack_middleware 1.0", "myrack 0.9.1" build_repo2 do - build_gem "rack-obama", "2.0" do |s| - s.add_dependency "rack", "=1.2" + build_gem "myrack-obama", "2.0" do |s| + s.add_dependency "myrack", "=1.2" end - build_gem "rack_middleware", "2.0" do |s| - s.add_dependency "rack", ">=1.0" + build_gem "myrack_middleware", "2.0" do |s| + s.add_dependency "myrack", ">=1.0" end end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack-obama", "2.0" - gem "rack_middleware" + source "https://gem.repo2" + gem "myrack-obama", "2.0" + gem "myrack_middleware" G end @@ -187,7 +187,7 @@ RSpec.describe "bundle flex_install" do ruby <<-RUBY, raise_on_error: false require 'bundler/setup' RUBY - expect(err).to match(/could not find gem 'rack-obama/i) + expect(err).to match(/could not find gem 'myrack-obama/i) end it "discards the locked gems when the Gemfile requires different versions than the lock" do @@ -196,10 +196,10 @@ RSpec.describe "bundle flex_install" do nice_error = <<~E.strip Could not find compatible versions - Because rack-obama >= 2.0 depends on rack = 1.2 - and rack = 1.2 could not be found in rubygems repository #{file_uri_for(gem_repo2)}/, cached gems or installed locally, - rack-obama >= 2.0 cannot be used. - So, because Gemfile depends on rack-obama = 2.0, + Because myrack-obama >= 2.0 depends on myrack = 1.2 + and myrack = 1.2 could not be found in rubygems repository https://gem.repo2/ or installed locally, + myrack-obama >= 2.0 cannot be used. + So, because Gemfile depends on myrack-obama = 2.0, version solving has failed. E @@ -211,12 +211,12 @@ RSpec.describe "bundle flex_install" do bundle "config set force_ruby_platform true" bad_error = <<~E.strip - Bundler could not find compatible versions for gem "rack-obama": + Bundler could not find compatible versions for gem "myrack-obama": In Gemfile: - rack-obama (= 2.0) + myrack-obama (= 2.0) E - bundle "update rack_middleware", retry: 0, raise_on_error: false + bundle "update myrack_middleware", retry: 0, raise_on_error: false expect(err).not_to end_with(bad_error) end end @@ -233,12 +233,12 @@ RSpec.describe "bundle flex_install" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "jekyll-feed", "~> 0.12" G gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "github-pages", "~> 226" gem "jekyll-feed", "~> 0.12" G @@ -253,40 +253,40 @@ RSpec.describe "bundle flex_install" do describe "subtler cases" do before :each do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack" + gem "myrack-obama" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" - gem "rack-obama" + source "https://gem.repo1" + gem "myrack", "0.9.1" + gem "myrack-obama" G end it "should work when you install" do bundle "install" - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo1, "rack", "0.9.1" - c.checksum gem_repo1, "rack-obama", "1.0" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo1, "myrack", "0.9.1" + c.checksum gem_repo1, "myrack-obama", "1.0" end expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (0.9.1) - rack-obama (1.0) - rack + myrack (0.9.1) + myrack-obama (1.0) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (= 0.9.1) - rack-obama + myrack (= 0.9.1) + myrack-obama #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -294,7 +294,7 @@ RSpec.describe "bundle flex_install" do end it "should work when you update" do - bundle "update rack" + bundle "update myrack" end end @@ -302,36 +302,36 @@ RSpec.describe "bundle flex_install" do it "updates the lockfile" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - source "#{file_uri_for(gem_repo2)}" do + source "https://gem.repo1" + source "https://gem.repo2" do end - gem "rack" + gem "myrack" G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo1, "rack", "1.0.0" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo1, "myrack", "1.0.0" end expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -344,17 +344,17 @@ RSpec.describe "bundle flex_install" do before(:each) do build_repo2 do build_gem "capybara", "0.3.9" do |s| - s.add_dependency "rack", ">= 1.0.0" + s.add_dependency "myrack", ">= 1.0.0" end - build_gem "rack", "1.1.0" + build_gem "myrack", "1.1.0" build_gem "rails", "3.0.0.rc4" do |s| - s.add_dependency "rack", "~> 1.1.0" + s.add_dependency "myrack", "~> 1.1.0" end - build_gem "rack", "1.2.1" + build_gem "myrack", "1.2.1" build_gem "rails", "3.0.0" do |s| - s.add_dependency "rack", "~> 1.2.1" + s.add_dependency "myrack", "~> 1.2.1" end end end @@ -362,14 +362,14 @@ RSpec.describe "bundle flex_install" do it "resolves them" do # install Rails 3.0.0.rc install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0.0.rc4" gem "capybara", "0.3.9" G # upgrade Rails to 3.0.0 and then install again install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "rails", "3.0.0" gem "capybara", "0.3.9" G diff --git a/spec/bundler/install/gems/fund_spec.rb b/spec/bundler/install/gems/fund_spec.rb index 9aadc9ed25..0855a62b86 100644 --- a/spec/bundler/install/gems/fund_spec.rb +++ b/spec/bundler/install/gems/fund_spec.rb @@ -32,10 +32,10 @@ RSpec.describe "bundle install" do context "when gems include a fund URI" do it "displays the plural fund message after installing" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding_and_other_metadata' gem 'has_funding' - gem 'rack-obama' + gem 'myrack-obama' G expect(out).to include("2 installed gems you directly depend on are looking for funding.") @@ -43,9 +43,9 @@ RSpec.describe "bundle install" do it "displays the singular fund message after installing" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding' - gem 'rack-obama' + gem 'myrack-obama' G expect(out).to include("1 installed gem you directly depend on is looking for funding.") @@ -59,10 +59,10 @@ RSpec.describe "bundle install" do it "does not display the plural fund message after installing" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding_and_other_metadata' gem 'has_funding' - gem 'rack-obama' + gem 'myrack-obama' G expect(out).not_to include("2 installed gems you directly depend on are looking for funding.") @@ -70,9 +70,9 @@ RSpec.describe "bundle install" do it "does not display the singular fund message after installing" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding' - gem 'rack-obama' + gem 'myrack-obama' G expect(out).not_to include("1 installed gem you directly depend on is looking for funding.") @@ -82,7 +82,7 @@ RSpec.describe "bundle install" do context "when gems do not include fund messages" do it "does not display any fund messages" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "activesupport" G @@ -93,7 +93,7 @@ RSpec.describe "bundle install" do context "when a dependency includes a fund message" do it "does not display the fund message" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'gem_with_dependent_funding' G @@ -111,7 +111,7 @@ RSpec.describe "bundle install" do } end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}' G @@ -125,7 +125,7 @@ RSpec.describe "bundle install" do } end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}' G @@ -135,7 +135,7 @@ RSpec.describe "bundle install" do } end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.1")}' G @@ -149,7 +149,7 @@ RSpec.describe "bundle install" do } end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'also_has_funding', :git => '#{lib_path("also_has_funding-1.0")}' G diff --git a/spec/bundler/install/gems/mirror_spec.rb b/spec/bundler/install/gems/mirror_spec.rb index 9611973701..70c0da50ef 100644 --- a/spec/bundler/install/gems/mirror_spec.rb +++ b/spec/bundler/install/gems/mirror_spec.rb @@ -4,17 +4,17 @@ RSpec.describe "bundle install with a mirror configured" do describe "when the mirror does not match the gem source" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G bundle "config set --local mirror.http://gems.example.org http://gem-mirror.example.org" end it "installs from the normal location" do bundle :install - expect(out).to include("Fetching source index from #{file_uri_for(gem_repo1)}") - expect(the_bundle).to include_gems "rack 1.0" + expect(out).to include("Fetching gem metadata from https://gem.repo1") + expect(the_bundle).to include_gems "myrack 1.0" end end @@ -22,18 +22,18 @@ RSpec.describe "bundle install with a mirror configured" do before :each do gemfile <<-G # This source is bogus and doesn't have the gem we're looking for - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack" + gem "myrack" G - bundle "config set --local mirror.#{file_uri_for(gem_repo2)} #{file_uri_for(gem_repo1)}" + bundle "config set --local mirror.https://gem.repo2 https://gem.repo1" end it "installs the gem from the mirror" do - bundle :install - expect(out).to include("Fetching source index from #{file_uri_for(gem_repo1)}") - expect(out).not_to include("Fetching source index from #{file_uri_for(gem_repo2)}") - expect(the_bundle).to include_gems "rack 1.0" + bundle :install, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } + expect(out).to include("Fetching gem metadata from https://gem.repo1") + expect(out).not_to include("Fetching gem metadata from https://gem.repo2") + expect(the_bundle).to include_gems "myrack 1.0" end end end diff --git a/spec/bundler/install/gems/native_extensions_spec.rb b/spec/bundler/install/gems/native_extensions_spec.rb index 907778a384..874818fa87 100644 --- a/spec/bundler/install/gems/native_extensions_spec.rb +++ b/spec/bundler/install/gems/native_extensions_spec.rb @@ -33,7 +33,7 @@ RSpec.describe "installing a gem with native extensions" do end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "c_extension" G @@ -78,7 +78,7 @@ RSpec.describe "installing a gem with native extensions" do bundle "config set build.c_extension --with-c_extension=hello" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "c_extension", :git => #{lib_path("c_extension-1.0").to_s.dump} G @@ -127,13 +127,13 @@ RSpec.describe "installing a gem with native extensions" do # 1st time, require only one gem -- only one of the extensions gets built. install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "c_extension_one", :git => #{lib_path("gems").to_s.dump} G # 2nd time, require both gems -- we need both extensions to be built now. install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "c_extension_one", :git => #{lib_path("gems").to_s.dump} gem "c_extension_two", :git => #{lib_path("gems").to_s.dump} G @@ -174,7 +174,7 @@ RSpec.describe "installing a gem with native extensions" do bundle "config set build.c_extension --with-c_extension=hello --with-c_extension_bundle-dir=hola" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "c_extension", :git => #{lib_path("c_extension-1.0").to_s.dump} G diff --git a/spec/bundler/install/gems/post_install_spec.rb b/spec/bundler/install/gems/post_install_spec.rb index 7426f54877..af753dba3e 100644 --- a/spec/bundler/install/gems/post_install_spec.rb +++ b/spec/bundler/install/gems/post_install_spec.rb @@ -5,26 +5,26 @@ RSpec.describe "bundle install" do context "when gems include post install messages" do it "should display the post-install messages after installing" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' gem 'thin' - gem 'rack-obama' + gem 'myrack-obama' G bundle :install - expect(out).to include("Post-install message from rack:") - expect(out).to include("Rack's post install message") + expect(out).to include("Post-install message from myrack:") + expect(out).to include("Myrack's post install message") expect(out).to include("Post-install message from thin:") expect(out).to include("Thin's post install message") - expect(out).to include("Post-install message from rack-obama:") - expect(out).to include("Rack-obama's post install message") + expect(out).to include("Post-install message from myrack-obama:") + expect(out).to include("Myrack-obama's post install message") end end context "when gems do not include post install messages" do it "should not display any post-install messages" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" G @@ -36,13 +36,13 @@ RSpec.describe "bundle install" do context "when a dependency includes a post install message" do it "should display the post install message" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack_middleware' + source "https://gem.repo1" + gem 'myrack_middleware' G bundle :install - expect(out).to include("Post-install message from rack:") - expect(out).to include("Rack's post install message") + expect(out).to include("Post-install message from myrack:") + expect(out).to include("Myrack's post install message") end end end @@ -54,7 +54,7 @@ RSpec.describe "bundle install" do s.post_install_message = "Foo's post install message" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => '#{lib_path("foo-1.0")}' G @@ -68,7 +68,7 @@ RSpec.describe "bundle install" do s.post_install_message = "Foo's post install message" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => '#{lib_path("foo-1.0")}' G bundle :install @@ -77,7 +77,7 @@ RSpec.describe "bundle install" do s.post_install_message = "Foo's 1.1 post install message" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => '#{lib_path("foo-1.1")}' G bundle :install @@ -91,7 +91,7 @@ RSpec.describe "bundle install" do s.post_install_message = "Foo's post install message" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => '#{lib_path("foo-1.0")}' G @@ -110,7 +110,7 @@ RSpec.describe "bundle install" do s.post_install_message = nil end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => '#{lib_path("foo-1.0")}' G @@ -123,11 +123,11 @@ RSpec.describe "bundle install" do context "when ignore post-install messages for gem is set" do it "doesn't display any post-install messages" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - bundle "config set ignore_messages.rack true" + bundle "config set ignore_messages.myrack true" bundle :install expect(out).not_to include("Post-install message") @@ -137,8 +137,8 @@ RSpec.describe "bundle install" do context "when ignore post-install messages for all gems" do it "doesn't display any post-install messages" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set ignore_messages true" diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb index c5f9c4a3d3..694bc7c131 100644 --- a/spec/bundler/install/gems/resolving_spec.rb +++ b/spec/bundler/install/gems/resolving_spec.rb @@ -66,7 +66,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs gems with implicit rake dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "with_implicit_rake_dep" gem "another_implicit_rake_dep" gem "rake" @@ -84,7 +84,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs gems with implicit rake dependencies without rake previously installed" do with_path_as("") do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "with_implicit_rake_dep" gem "another_implicit_rake_dep" gem "rake" @@ -100,7 +100,7 @@ RSpec.describe "bundle install with install-time dependencies" do expect(out).to eq("YES\nYES") end - it "installs gems with a dependency with no type" do + it "does not install gems with a dependency with no type" do build_repo2 path = "#{gem_repo2}/#{Gem::MARSHAL_SPEC_DIR}/actionpack-2.3.2.gemspec.rz" @@ -112,18 +112,20 @@ RSpec.describe "bundle install with install-time dependencies" do f.write Gem.deflate(Marshal.dump(spec)) end - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" gem "actionpack", "2.3.2" G - expect(the_bundle).to include_gems "actionpack 2.3.2", "activesupport 2.3.2" + expect(err).to include("Downloading actionpack-2.3.2 revealed dependencies not in the API or the lockfile (activesupport (= 2.3.2)).") + + expect(the_bundle).not_to include_gems "actionpack 2.3.2", "activesupport 2.3.2" end describe "with crazy rubygem plugin stuff" do it "installs plugins" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_b" G @@ -132,7 +134,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs plugins depended on by other plugins" do install_gemfile <<-G, env: { "DEBUG" => "1" } - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_a" G @@ -141,7 +143,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs multiple levels of dependencies" do install_gemfile <<-G, env: { "DEBUG" => "1" } - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G @@ -152,7 +154,7 @@ RSpec.describe "bundle install with install-time dependencies" do context "with ENV['BUNDLER_DEBUG_RESOLVER'] set" do it "produces debug output" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G @@ -166,7 +168,7 @@ RSpec.describe "bundle install with install-time dependencies" do context "with ENV['DEBUG_RESOLVER'] set" do it "produces debug output" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G @@ -180,7 +182,7 @@ RSpec.describe "bundle install with install-time dependencies" do context "with ENV['DEBUG_RESOLVER_TREE'] set" do it "produces debug output" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "net_c" gem "net_e" G @@ -199,44 +201,44 @@ RSpec.describe "bundle install with install-time dependencies" do context "allows only an older version" do it "installs the older version" do build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end end - install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + install_gemfile <<-G ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end it "installs the older version when using servers not implementing the compact index API" do build_repo2 do - build_gem "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end end - install_gemfile <<-G, artifice: "endpoint", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + install_gemfile <<-G, artifice: "endpoint" ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo2" + gem 'myrack' G - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end context "when there is a lockfile using the newer incompatible version" do @@ -252,7 +254,7 @@ RSpec.describe "bundle install with install-time dependencies" do end gemfile <<-G - source "http://localgemserver.test/" + source "https://gem.repo2" gem 'parallel_tests' G @@ -262,7 +264,7 @@ RSpec.describe "bundle install with install-time dependencies" do lockfile <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: parallel_tests (3.8.0) @@ -278,15 +280,15 @@ RSpec.describe "bundle install with install-time dependencies" do end it "automatically updates lockfile to use the older version" do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + bundle "install --verbose" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo2, "parallel_tests", "3.7.0" end expect(lockfile).to eq <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: parallel_tests (3.7.0) @@ -303,7 +305,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "gives a meaningful error if we're in frozen mode" do expect do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s, "BUNDLE_FROZEN" => "true" }, raise_on_error: false + bundle "install --verbose", env: { "BUNDLE_FROZEN" => "true" }, raise_on_error: false end.not_to change { lockfile } expect(err).to include("parallel_tests-3.8.0 requires ruby version >= #{next_ruby_minor}") @@ -336,7 +338,7 @@ RSpec.describe "bundle install with install-time dependencies" do end gemfile <<-G - source "http://localgemserver.test/" + source "https://gem.repo2" gem 'rubocop' G @@ -347,7 +349,7 @@ RSpec.describe "bundle install with install-time dependencies" do lockfile <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: rubocop (1.35.0) rubocop-ast (>= 1.20.1, < 2.0) @@ -365,16 +367,16 @@ RSpec.describe "bundle install with install-time dependencies" do end it "automatically updates lockfile to use the older compatible versions" do - bundle "install --verbose", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } + bundle "install --verbose" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum gem_repo2, "rubocop", "1.28.2" c.checksum gem_repo2, "rubocop-ast", "1.17.0" end expect(lockfile).to eq <<~L GEM - remote: http://localgemserver.test/ + remote: https://gem.repo2/ specs: rubocop (1.28.2) rubocop-ast (>= 1.17.0, < 2.0) @@ -405,13 +407,13 @@ RSpec.describe "bundle install with install-time dependencies" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem 'sorbet', '= 0.5.10554' G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: sorbet (0.5.10554) sorbet-static (= 0.5.10554) @@ -434,7 +436,7 @@ RSpec.describe "bundle install with install-time dependencies" do end nice_error = <<~E.strip - Could not find gems matching 'sorbet-static (= 0.5.10554)' valid for all resolution platforms (arm64-darwin-21, aarch64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally. + Could not find gems matching 'sorbet-static (= 0.5.10554)' valid for all resolution platforms (arm64-darwin-21, aarch64-linux) in rubygems repository https://gem.repo4/ or installed locally. The source contains the following gems matching 'sorbet-static (= 0.5.10554)': * sorbet-static-0.5.10554-universal-darwin-21 @@ -461,7 +463,7 @@ RSpec.describe "bundle install with install-time dependencies" do lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: nokogiri (1.14.0-arm-linux) nokogiri (1.14.0-x86_64-linux) @@ -478,7 +480,7 @@ RSpec.describe "bundle install with install-time dependencies" do L gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri" gem "sorbet-static" @@ -490,7 +492,7 @@ RSpec.describe "bundle install with install-time dependencies" do it "raises a proper error" do nice_error = <<~E.strip - Could not find gems matching 'sorbet-static' valid for all resolution platforms (arm-linux, x86_64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally. + Could not find gems matching 'sorbet-static' valid for all resolution platforms (arm-linux, x86_64-linux) in rubygems repository https://gem.repo4/ or installed locally. The source contains the following gems matching 'sorbet-static': * sorbet-static-0.5.10696-x86_64-linux @@ -513,7 +515,7 @@ RSpec.describe "bundle install with install-time dependencies" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gemspec G @@ -531,47 +533,47 @@ RSpec.describe "bundle install with install-time dependencies" do it "installs the older version under rate limiting conditions" do build_repo4 do - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end - build_gem "rack", "1.2" + build_gem "myrack", "1.2" build_gem "foo1", "1.0" end - install_gemfile <<-G, artifice: "compact_index_rate_limited", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + install_gemfile <<-G, artifice: "compact_index_rate_limited" ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo4" + gem 'myrack' gem 'foo1' G - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end it "installs the older not platform specific version" do build_repo4 do - build_gem "rack", "9001.0.0" do |s| + build_gem "myrack", "9001.0.0" do |s| s.required_ruby_version = "> 9000" end - build_gem "rack", "1.2" do |s| + build_gem "myrack", "1.2" do |s| s.platform = x86_mingw32 s.required_ruby_version = "> 9000" end - build_gem "rack", "1.2" + build_gem "myrack", "1.2" end simulate_platform x86_mingw32 do - install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + install_gemfile <<-G, artifice: "compact_index" ruby "#{Gem.ruby_version}" - source "http://localgemserver.test/" - gem 'rack' + source "https://gem.repo4" + gem 'myrack' G end - expect(err).to_not include("rack-9001.0.0 requires ruby version > 9000") - expect(err).to_not include("rack-1.2-#{Bundler.local_platform} requires ruby version > 9000") - expect(the_bundle).to include_gems("rack 1.2") + expect(err).to_not include("myrack-9001.0.0 requires ruby version > 9000") + expect(err).to_not include("myrack-1.2-#{Bundler.local_platform} requires ruby version > 9000") + expect(the_bundle).to include_gems("myrack 1.2") end end @@ -588,8 +590,8 @@ RSpec.describe "bundle install with install-time dependencies" do let(:error_message_requirement) { "= #{Gem.ruby_version}" } it "raises a proper error that mentions the current Ruby version during resolution" do - install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, raise_on_error: false - source "http://localgemserver.test/" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" gem 'require_ruby' G @@ -609,8 +611,8 @@ RSpec.describe "bundle install with install-time dependencies" do shared_examples_for "ruby version conflicts" do it "raises an error during resolution" do - install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s }, raise_on_error: false - source "http://localgemserver.test/" + install_gemfile <<-G, raise_on_error: false + source "https://gem.repo2" ruby #{ruby_requirement} gem 'require_ruby' G @@ -656,7 +658,7 @@ RSpec.describe "bundle install with install-time dependencies" do end install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'require_rubygems' G @@ -671,4 +673,55 @@ RSpec.describe "bundle install with install-time dependencies" do expect(err).to end_with(nice_error) end end + + context "when non platform specific gems bring more dependencies", :truffleruby_only do + before do + build_repo4 do + build_gem "foo", "1.0" do |s| + s.add_dependency "bar" + end + + build_gem "foo", "2.0" do |s| + s.platform = "x86_64-linux" + end + + build_gem "bar" + end + + gemfile <<-G + source "https://gem.repo4" + gem "foo" + G + end + + it "locks both ruby and current platform, and resolve to ruby variants that install on truffleruby" do + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo4, "foo", "1.0" + c.checksum gem_repo4, "bar", "1.0" + end + + simulate_platform "x86_64-linux" do + bundle "install" + + expect(lockfile).to eq <<~L + GEM + remote: https://gem.repo4/ + specs: + bar (1.0) + foo (1.0) + bar + + PLATFORMS + ruby + x86_64-linux + + DEPENDENCIES + foo + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + L + end + end + end end diff --git a/spec/bundler/install/gems/standalone_spec.rb b/spec/bundler/install/gems/standalone_spec.rb index 46cab2dfeb..ee8d9c6d3a 100644 --- a/spec/bundler/install/gems/standalone_spec.rb +++ b/spec/bundler/install/gems/standalone_spec.rb @@ -8,9 +8,9 @@ RSpec.shared_examples "bundle install --standalone" do end it "still makes system gems unavailable to normal bundler" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" - expect(the_bundle).to_not include_gems("rack") + expect(the_bundle).to_not include_gems("myrack") end it "generates a bundle/bundler/setup.rb" do @@ -63,14 +63,14 @@ RSpec.shared_examples "bundle install --standalone" do end it "makes system gems unavailable without bundler" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" testrb = String.new <<-RUBY $:.unshift File.expand_path("bundle") require "bundler/setup" begin - require "rack" + require "myrack" rescue LoadError puts "LoadError" end @@ -122,7 +122,7 @@ RSpec.shared_examples "bundle install --standalone" do describe "with simple gems" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G bundle "config set --local path #{bundled_app("bundle")}" @@ -141,12 +141,18 @@ RSpec.shared_examples "bundle install --standalone" do describe "with default gems and a lockfile", :ruby_repo do before do - realworld_system_gems "tsort --version 0.1.0" + skip "Does not work on old Windows Rubies" if Gem.ruby_version < Gem::Version.new("3.2") && Gem.win_platform? - necessary_system_gems = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.2.0", "stringio --version 3.1.0"] - necessary_system_gems += ["shellwords --version 0.1.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.a") - necessary_system_gems += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a") - realworld_system_gems(*necessary_system_gems, path: scoped_gem_path(bundled_app("bundle"))) + necessary_system_gems = ["tsort --version 0.1.0"] + necessary_system_gems += ["etc --version 1.4.3"] if Gem.ruby_version >= Gem::Version.new("3.3.2") && Gem.win_platform? + realworld_system_gems(*necessary_system_gems) + end + + it "works and points to the vendored copies, not to the default copies" do + necessary_gems_in_bundle_path = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.4.3", "stringio --version 3.1.0"] + necessary_gems_in_bundle_path += ["shellwords --version 0.2.0", "base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.a") + necessary_gems_in_bundle_path += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a") + realworld_system_gems(*necessary_gems_in_bundle_path, path: scoped_gem_path(bundled_app("bundle"))) build_gem "foo", "1.0.0", to_system: true, default: true do |s| s.add_dependency "bar" @@ -167,12 +173,10 @@ RSpec.shared_examples "bundle install --standalone" do gem "foo" G - bundle "lock", dir: cwd, artifice: "compact_index" - end + bundle "lock", dir: cwd - it "works and points to the vendored copies, not to the default copies", :realworld do bundle "config set --local path #{bundled_app("bundle")}" - bundle :install, standalone: true, dir: cwd, artifice: "compact_index", env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } + bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") } @@ -181,6 +185,39 @@ RSpec.shared_examples "bundle install --standalone" do '$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/foo-1.0.0/lib")', ] end + + it "works for gems with extensions and points to the vendored copies, not to the default copies" do + necessary_gems_in_bundle_path = ["optparse --version 0.1.1", "psych --version 3.3.2", "logger --version 1.4.3", "etc --version 1.4.3", "stringio --version 3.1.0", "shellwords --version 0.2.0", "open3 --version 0.2.1"] + necessary_gems_in_bundle_path += ["base64 --version 0.1.0", "resolv --version 0.2.1"] if Gem.rubygems_version < Gem::Version.new("3.3.a") + necessary_gems_in_bundle_path += ["yaml --version 0.1.1"] if Gem.rubygems_version < Gem::Version.new("3.4.a") + realworld_system_gems(*necessary_gems_in_bundle_path, path: scoped_gem_path(bundled_app("bundle"))) + + build_gem "baz", "1.0.0", to_system: true, default: true, &:add_c_extension + + build_repo4 do + build_gem "baz", "1.0.0", &:add_c_extension + end + + gemfile <<-G + source "https://gem.repo4" + gem "baz" + G + + bundle "config set --local path #{bundled_app("bundle")}" + + simulate_platform "arm64-darwin-23" do + bundle "lock", dir: cwd + + bundle :install, standalone: true, dir: cwd, env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } + end + + load_path_lines = bundled_app("bundle/bundler/setup.rb").read.split("\n").select {|line| line.start_with?("$:.unshift") } + + expect(load_path_lines).to eq [ + '$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/extensions/arm64-darwin-23/#{Gem.extension_api_version}/baz-1.0.0")', + '$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/baz-1.0.0/lib")', + ] + end end describe "with Gemfiles using absolute path sources and resulting bundle moved to a folder hierarchy with different nesting" do @@ -190,7 +227,7 @@ RSpec.shared_examples "bundle install --standalone" do Dir.mkdir bundled_app("app") gemfile bundled_app("app/Gemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "minitest", :path => "#{lib_path("minitest")}" G @@ -220,7 +257,7 @@ RSpec.shared_examples "bundle install --standalone" do build_lib "minitest", "1.0.0", path: bundled_app("app/vendor/minitest") gemfile bundled_app("app/Gemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "minitest", :path => "vendor/minitest" G @@ -246,7 +283,7 @@ RSpec.shared_examples "bundle install --standalone" do before do bundle "config set --local path #{bundled_app("bundle")}" install_gemfile <<-G, standalone: true, dir: cwd - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "very_simple_binary" G end @@ -284,14 +321,14 @@ RSpec.shared_examples "bundle install --standalone" do end bundle "config set --local path #{bundled_app("bundle")}" install_gemfile <<-G, standalone: true, dir: cwd, raise_on_error: false - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :git => "#{lib_path("bar-1.0")}" G end it "outputs a helpful error message" do expect(err).to include("You have one or more invalid gemspecs that need to be fixed.") - expect(err).to include("bar 1.0 has an invalid gemspec") + expect(err).to include("bar.gemspec is not valid") end end @@ -300,7 +337,7 @@ RSpec.shared_examples "bundle install --standalone" do build_git "devise", "1.0" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" gem "devise", :git => "#{lib_path("devise-1.0")}" G @@ -324,12 +361,12 @@ RSpec.shared_examples "bundle install --standalone" do build_git "devise", "1.0" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" group :test do gem "rspec" - gem "rack-test" + gem "myrack-test" end G bundle "config set --local path #{bundled_app("bundle")}" @@ -442,7 +479,7 @@ RSpec.shared_examples "bundle install --standalone" do describe "with --binstubs", bundler: "< 3" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G bundle "config set --local path #{bundled_app("bundle")}" @@ -502,23 +539,23 @@ end RSpec.describe "bundle install --standalone --local" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path end it "generates script pointing to system gems" do bundle "install --standalone --local --verbose" - expect(out).to include("Using rack 1.0.0") + expect(out).to include("Using myrack 1.0.0") load_error_ruby <<-RUBY, "spec" require "./bundler/setup" - require "rack" - puts RACK + require "myrack" + puts MYRACK require "spec" RUBY diff --git a/spec/bundler/install/gems/win32_spec.rb b/spec/bundler/install/gems/win32_spec.rb index 419b14ff0f..be37673aa1 100644 --- a/spec/bundler/install/gems/win32_spec.rb +++ b/spec/bundler/install/gems/win32_spec.rb @@ -4,22 +4,22 @@ RSpec.describe "bundle install with win32-generated lockfile" do it "should read lockfile" do File.open(bundled_app_lock, "wb") do |f| f << "GEM\r\n" - f << " remote: #{file_uri_for(gem_repo1)}/\r\n" + f << " remote: https://gem.repo1/\r\n" f << " specs:\r\n" f << "\r\n" - f << " rack (1.0.0)\r\n" + f << " myrack (1.0.0)\r\n" f << "\r\n" f << "PLATFORMS\r\n" f << " ruby\r\n" f << "\r\n" f << "DEPENDENCIES\r\n" - f << " rack\r\n" + f << " myrack\r\n" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - gem "rack" + gem "myrack" G end end diff --git a/spec/bundler/install/gemspecs_spec.rb b/spec/bundler/install/gemspecs_spec.rb index 51aa0ed14f..7629870db2 100644 --- a/spec/bundler/install/gemspecs_spec.rb +++ b/spec/bundler/install/gemspecs_spec.rb @@ -10,7 +10,7 @@ RSpec.describe "bundle install" do it "still installs correctly" do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "yaml_spec" G bundle :install @@ -21,7 +21,7 @@ RSpec.describe "bundle install" do build_lib "yaml_spec", gemspec: :yaml install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'yaml_spec', :path => "#{lib_path("yaml_spec-1.0")}" G expect(err).to be_empty @@ -31,22 +31,22 @@ RSpec.describe "bundle install" do it "should use gemspecs in the system cache when available" do gemfile <<-G source "http://localtestserver.gem" - gem 'rack' + gem 'myrack' G - system_gems "rack-1.0.0", path: default_bundle_path + system_gems "myrack-1.0.0", path: default_bundle_path FileUtils.mkdir_p "#{default_bundle_path}/specifications" - File.open("#{default_bundle_path}/specifications/rack-1.0.0.gemspec", "w+") do |f| + File.open("#{default_bundle_path}/specifications/myrack-1.0.0.gemspec", "w+") do |f| spec = Gem::Specification.new do |s| - s.name = "rack" + s.name = "myrack" s.version = "1.0.0" - s.add_runtime_dependency "activesupport", "2.3.2" + s.add_dependency "activesupport", "2.3.2" end f.write spec.to_ruby end bundle :install, artifice: "endpoint_marshal_fail" # force gemspec load - expect(the_bundle).to include_gems "rack 1.0.0", "activesupport 2.3.2" + expect(the_bundle).to include_gems "myrack 1.0.0", "activesupport 2.3.2" end it "does not hang when gemspec has incompatible encoding" do @@ -60,7 +60,7 @@ RSpec.describe "bundle install" do G install_gemfile <<-G, env: { "LANG" => "C" } - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G @@ -86,7 +86,7 @@ RSpec.describe "bundle install" do G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G @@ -102,7 +102,7 @@ RSpec.describe "bundle install" do install_gemfile <<-G ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G expect(the_bundle).to include_gems "foo 1.0" @@ -116,7 +116,7 @@ RSpec.describe "bundle install" do install_gemfile <<-G, raise_on_error: false ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby', :patchlevel => '#{RUBY_PATCHLEVEL}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G expect(the_bundle).to include_gems "foo 1.0" @@ -131,7 +131,7 @@ RSpec.describe "bundle install" do install_gemfile <<-G, raise_on_error: false ruby '#{RUBY_VERSION}', :engine_version => '#{RUBY_VERSION}', :engine => 'ruby', :patchlevel => '#{patchlevel}' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G @@ -149,7 +149,7 @@ RSpec.describe "bundle install" do install_gemfile <<-G, raise_on_error: false ruby '#{version}', :engine_version => '#{version}', :engine => 'ruby' - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G @@ -157,5 +157,25 @@ RSpec.describe "bundle install" do expect(err).to include("but your Gemfile specified") expect(exitstatus).to eq(18) end + + it "validates gemspecs just once when everything installed and lockfile up to date" do + build_lib "foo" + + install_gemfile <<-G + source "https://gem.repo1" + gemspec path: "#{lib_path("foo-1.0")}" + + module Monkey + def validate(spec) + puts "Validate called on \#{spec.full_name}" + end + end + Bundler.rubygems.extend(Monkey) + G + + bundle "install" + + expect(out).to include("Validate called on foo-1.0").once + end end end diff --git a/spec/bundler/install/git_spec.rb b/spec/bundler/install/git_spec.rb index c8d574baf3..d1f6b7a7ca 100644 --- a/spec/bundler/install/git_spec.rb +++ b/spec/bundler/install/git_spec.rb @@ -6,11 +6,24 @@ RSpec.describe "bundle install" do build_git "foo", "1.0", path: lib_path("foo") install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo"))}" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo")}" G - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{revision_for(lib_path("foo"))[0..6]})") + expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at main@#{revision_for(lib_path("foo"))[0..6]})") + expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}" + end + + it "displays the revision hash of the gem repository when passed a relative local path" do + build_git "foo", "1.0", path: lib_path("foo") + + relative_path = lib_path("foo").relative_path_from(bundled_app) + install_gemfile <<-G, verbose: true + source "https://gem.repo1" + gem "foo", :git => "#{relative_path}" + G + + expect(out).to include("Using foo 1.0 from #{relative_path} (at main@#{revision_for(lib_path("foo"))[0..6]})") expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}" end @@ -18,11 +31,11 @@ RSpec.describe "bundle install" do build_git "foo", "1.0", path: lib_path("foo"), default_branch: "main" install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo"))}" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo")}" G - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{revision_for(lib_path("foo"))[0..6]})") + expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at main@#{revision_for(lib_path("foo"))[0..6]})") expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}" end @@ -36,31 +49,31 @@ RSpec.describe "bundle install" do update_git "foo", "3.0", path: lib_path("foo"), gemspec: true install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo"))}", :ref => "main~2" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo")}", :ref => "main~2" G - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main~2@#{rev})") + expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at main~2@#{rev})") expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}" update_git "foo", "4.0", path: lib_path("foo"), gemspec: true bundle :update, all: true, verbose: true - expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at main~2@#{rev2})") + expect(out).to include("Using foo 2.0 (was 1.0) from #{lib_path("foo")} (at main~2@#{rev2})") expect(the_bundle).to include_gems "foo 2.0", source: "git@#{lib_path("foo")}" end - it "should allows git repos that are missing but not being installed" do + it "allows git repos that are missing but not being installed" do revision = build_git("foo").ref_for("HEAD") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}", :group => :development + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo-1.0")}", :group => :development G lockfile <<-L GIT - remote: #{file_uri_for(lib_path("foo-1.0"))} + remote: #{lib_path("foo-1.0")} revision: #{revision} specs: foo (1.0) @@ -87,9 +100,9 @@ RSpec.describe "bundle install" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "foo", :git => "#{file_uri_for(lib_path("gems"))}", :glob => "foo/*.gemspec" - gem "zebra", :git => "#{file_uri_for(lib_path("gems"))}", :glob => "zebra/*.gemspec" + source "https://gem.repo2" + gem "foo", :git => "#{lib_path("gems")}", :glob => "foo/*.gemspec" + gem "zebra", :git => "#{lib_path("gems")}", :glob => "zebra/*.gemspec" G bundle "info foo" @@ -112,7 +125,7 @@ RSpec.describe "bundle install" do other_ref = other.ref_for("HEAD") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "test", git: #{test.path.to_s.inspect} gem "other", ref: #{other_ref.inspect}, git: #{other.path.to_s.inspect} @@ -133,7 +146,7 @@ RSpec.describe "bundle install" do other (1.0.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -178,11 +191,11 @@ RSpec.describe "bundle install" do bundle "config set path vendor/bundle" bundle "config set clean true" install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo"))}" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo")}" G - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{rev[0..6]})") + expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at main@#{rev[0..6]})") expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}" old_lockfile = lockfile @@ -191,14 +204,14 @@ RSpec.describe "bundle install" do rev2 = revision_for(lib_path("foo")) bundle :update, all: true, verbose: true - expect(out).to include("Using foo 2.0 (was 1.0) from #{file_uri_for(lib_path("foo"))} (at main@#{rev2[0..6]})") + expect(out).to include("Using foo 2.0 (was 1.0) from #{lib_path("foo")} (at main@#{rev2[0..6]})") expect(out).to include("Removing foo (#{rev[0..11]})") expect(the_bundle).to include_gems "foo 2.0", source: "git@#{lib_path("foo")}" lockfile(old_lockfile) bundle :install, verbose: true - expect(out).to include("Using foo 1.0 from #{file_uri_for(lib_path("foo"))} (at main@#{rev[0..6]})") + expect(out).to include("Using foo 1.0 from #{lib_path("foo")} (at main@#{rev[0..6]})") expect(the_bundle).to include_gems "foo 1.0", source: "git@#{lib_path("foo")}" end end diff --git a/spec/bundler/install/global_cache_spec.rb b/spec/bundler/install/global_cache_spec.rb index 0da4de05b2..df4559c42e 100644 --- a/spec/bundler/install/global_cache_spec.rb +++ b/spec/bundler/install/global_cache_spec.rb @@ -18,133 +18,133 @@ RSpec.describe "global gem caching" do it "caches gems into the global cache on download" do install_gemfile <<-G, artifice: "compact_index" source "#{source}" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" - expect(source_global_cache("rack-1.0.0.gem")).to exist + expect(the_bundle).to include_gems "myrack 1.0.0" + expect(source_global_cache("myrack-1.0.0.gem")).to exist end it "uses globally cached gems if they exist" do source_global_cache.mkpath - FileUtils.cp(gem_repo1("gems/rack-1.0.0.gem"), source_global_cache("rack-1.0.0.gem")) + FileUtils.cp(gem_repo1("gems/myrack-1.0.0.gem"), source_global_cache("myrack-1.0.0.gem")) install_gemfile <<-G, artifice: "compact_index_no_gem" source "#{source}" - gem "rack" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "shows a proper error message if a cached gem is corrupted" do source_global_cache.mkpath - FileUtils.touch(source_global_cache("rack-1.0.0.gem")) + FileUtils.touch(source_global_cache("myrack-1.0.0.gem")) install_gemfile <<-G, artifice: "compact_index_no_gem", raise_on_error: false source "#{source}" - gem "rack" + gem "myrack" G - expect(err).to include("Gem::Package::FormatError: package metadata is missing in #{source_global_cache("rack-1.0.0.gem")}") + expect(err).to include("Gem::Package::FormatError: package metadata is missing in #{source_global_cache("myrack-1.0.0.gem")}") end describe "when the same gem from different sources is installed" do it "should use the appropriate one from the global cache" do install_gemfile <<-G, artifice: "compact_index" source "#{source}" - gem "rack" + gem "myrack" G simulate_new_machine - expect(the_bundle).not_to include_gems "rack 1.0.0" - expect(source_global_cache("rack-1.0.0.gem")).to exist - # rack 1.0.0 is not installed and it is in the global cache + expect(the_bundle).not_to include_gems "myrack 1.0.0" + expect(source_global_cache("myrack-1.0.0.gem")).to exist + # myrack 1.0.0 is not installed and it is in the global cache install_gemfile <<-G, artifice: "compact_index" source "#{source2}" - gem "rack", "0.9.1" + gem "myrack", "0.9.1" G simulate_new_machine - expect(the_bundle).not_to include_gems "rack 0.9.1" - expect(source2_global_cache("rack-0.9.1.gem")).to exist - # rack 0.9.1 is not installed and it is in the global cache + expect(the_bundle).not_to include_gems "myrack 0.9.1" + expect(source2_global_cache("myrack-0.9.1.gem")).to exist + # myrack 0.9.1 is not installed and it is in the global cache gemfile <<-G source "#{source}" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G bundle :install, artifice: "compact_index_no_gem" - # rack 1.0.0 is installed and rack 0.9.1 is not - expect(the_bundle).to include_gems "rack 1.0.0" - expect(the_bundle).not_to include_gems "rack 0.9.1" + # myrack 1.0.0 is installed and myrack 0.9.1 is not + expect(the_bundle).to include_gems "myrack 1.0.0" + expect(the_bundle).not_to include_gems "myrack 0.9.1" simulate_new_machine gemfile <<-G source "#{source2}" - gem "rack", "0.9.1" + gem "myrack", "0.9.1" G bundle :install, artifice: "compact_index_no_gem" - # rack 0.9.1 is installed and rack 1.0.0 is not - expect(the_bundle).to include_gems "rack 0.9.1" - expect(the_bundle).not_to include_gems "rack 1.0.0" + # myrack 0.9.1 is installed and myrack 1.0.0 is not + expect(the_bundle).to include_gems "myrack 0.9.1" + expect(the_bundle).not_to include_gems "myrack 1.0.0" end it "should not install if the wrong source is provided" do gemfile <<-G source "#{source}" - gem "rack" + gem "myrack" G bundle :install, artifice: "compact_index" simulate_new_machine - expect(the_bundle).not_to include_gems "rack 1.0.0" - expect(source_global_cache("rack-1.0.0.gem")).to exist - # rack 1.0.0 is not installed and it is in the global cache + expect(the_bundle).not_to include_gems "myrack 1.0.0" + expect(source_global_cache("myrack-1.0.0.gem")).to exist + # myrack 1.0.0 is not installed and it is in the global cache gemfile <<-G source "#{source2}" - gem "rack", "0.9.1" + gem "myrack", "0.9.1" G bundle :install, artifice: "compact_index" simulate_new_machine - expect(the_bundle).not_to include_gems "rack 0.9.1" - expect(source2_global_cache("rack-0.9.1.gem")).to exist - # rack 0.9.1 is not installed and it is in the global cache + expect(the_bundle).not_to include_gems "myrack 0.9.1" + expect(source2_global_cache("myrack-0.9.1.gem")).to exist + # myrack 0.9.1 is not installed and it is in the global cache gemfile <<-G source "#{source2}" - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G - expect(source_global_cache("rack-1.0.0.gem")).to exist - expect(source2_global_cache("rack-0.9.1.gem")).to exist + expect(source_global_cache("myrack-1.0.0.gem")).to exist + expect(source2_global_cache("myrack-0.9.1.gem")).to exist bundle :install, artifice: "compact_index_no_gem", raise_on_error: false expect(err).to include("Internal Server Error 500") expect(err).not_to include("ERROR REPORT TEMPLATE") - # rack 1.0.0 is not installed and rack 0.9.1 is not - expect(the_bundle).not_to include_gems "rack 1.0.0" - expect(the_bundle).not_to include_gems "rack 0.9.1" + # myrack 1.0.0 is not installed and myrack 0.9.1 is not + expect(the_bundle).not_to include_gems "myrack 1.0.0" + expect(the_bundle).not_to include_gems "myrack 0.9.1" gemfile <<-G source "#{source}" - gem "rack", "0.9.1" + gem "myrack", "0.9.1" G - expect(source_global_cache("rack-1.0.0.gem")).to exist - expect(source2_global_cache("rack-0.9.1.gem")).to exist + expect(source_global_cache("myrack-1.0.0.gem")).to exist + expect(source2_global_cache("myrack-0.9.1.gem")).to exist bundle :install, artifice: "compact_index_no_gem", raise_on_error: false expect(err).to include("Internal Server Error 500") expect(err).not_to include("ERROR REPORT TEMPLATE") - # rack 0.9.1 is not installed and rack 1.0.0 is not - expect(the_bundle).not_to include_gems "rack 0.9.1" - expect(the_bundle).not_to include_gems "rack 1.0.0" + # myrack 0.9.1 is not installed and myrack 1.0.0 is not + expect(the_bundle).not_to include_gems "myrack 0.9.1" + expect(the_bundle).not_to include_gems "myrack 1.0.0" end end @@ -152,29 +152,29 @@ RSpec.describe "global gem caching" do it "uses the global cache as a source" do install_gemfile <<-G, artifice: "compact_index" source "#{source}" - gem "rack" + gem "myrack" gem "activesupport" G # Both gems are installed and in the global cache - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" expect(the_bundle).to include_gems "activesupport 2.3.5" - expect(source_global_cache("rack-1.0.0.gem")).to exist + expect(source_global_cache("myrack-1.0.0.gem")).to exist expect(source_global_cache("activesupport-2.3.5.gem")).to exist simulate_new_machine # Both gems are now only in the global cache - expect(the_bundle).not_to include_gems "rack 1.0.0" + expect(the_bundle).not_to include_gems "myrack 1.0.0" expect(the_bundle).not_to include_gems "activesupport 2.3.5" install_gemfile <<-G, artifice: "compact_index_no_gem" source "#{source}" - gem "rack" + gem "myrack" G - # rack is installed and both are in the global cache - expect(the_bundle).to include_gems "rack 1.0.0" + # myrack is installed and both are in the global cache + expect(the_bundle).to include_gems "myrack 1.0.0" expect(the_bundle).not_to include_gems "activesupport 2.3.5" - expect(source_global_cache("rack-1.0.0.gem")).to exist + expect(source_global_cache("myrack-1.0.0.gem")).to exist expect(source_global_cache("activesupport-2.3.5.gem")).to exist create_file bundled_app2("gems.rb"), <<-G @@ -183,9 +183,9 @@ RSpec.describe "global gem caching" do G # Neither gem is installed and both are in the global cache - expect(the_bundle).not_to include_gems "rack 1.0.0", dir: bundled_app2 + expect(the_bundle).not_to include_gems "myrack 1.0.0", dir: bundled_app2 expect(the_bundle).not_to include_gems "activesupport 2.3.5", dir: bundled_app2 - expect(source_global_cache("rack-1.0.0.gem")).to exist + expect(source_global_cache("myrack-1.0.0.gem")).to exist expect(source_global_cache("activesupport-2.3.5.gem")).to exist # Install using the global cache instead of by downloading the .gem @@ -193,10 +193,10 @@ RSpec.describe "global gem caching" do bundle :install, artifice: "compact_index_no_gem", dir: bundled_app2 # activesupport is installed and both are in the global cache - expect(the_bundle).not_to include_gems "rack 1.0.0", dir: bundled_app2 + expect(the_bundle).not_to include_gems "myrack 1.0.0", dir: bundled_app2 expect(the_bundle).to include_gems "activesupport 2.3.5", dir: bundled_app2 - expect(source_global_cache("rack-1.0.0.gem")).to exist + expect(source_global_cache("myrack-1.0.0.gem")).to exist expect(source_global_cache("activesupport-2.3.5.gem")).to exist end end @@ -211,7 +211,7 @@ RSpec.describe "global gem caching" do revision = revision_for(lib_path("very_simple_git_binary-1.0"))[0, 12] install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "very_simple_binary" gem "very_simple_git_binary", :git => "#{lib_path("very_simple_git_binary-1.0")}" @@ -219,7 +219,7 @@ RSpec.describe "global gem caching" do G gem_binary_cache = home(".bundle", "cache", "extensions", local_platform.to_s, Bundler.ruby_scope, - Digest(:MD5).hexdigest("#{gem_repo1}/"), "very_simple_binary-1.0") + "gem.repo1.443.#{Digest(:MD5).hexdigest("gem.repo1.443./")}", "very_simple_binary-1.0") git_binary_cache = home(".bundle", "cache", "extensions", local_platform.to_s, Bundler.ruby_scope, "very_simple_git_binary-1.0-#{revision}", "very_simple_git_binary-1.0") diff --git a/spec/bundler/install/path_spec.rb b/spec/bundler/install/path_spec.rb index 0a30e402b7..8d32e033d6 100644 --- a/spec/bundler/install/path_spec.rb +++ b/spec/bundler/install/path_spec.rb @@ -3,27 +3,27 @@ RSpec.describe "bundle install" do describe "with path configured" do before :each do - build_gem "rack", "1.0.0", to_system: true do |s| - s.write "lib/rack.rb", "puts 'FAIL'" + build_gem "myrack", "1.0.0", to_system: true do |s| + s.write "lib/myrack.rb", "puts 'FAIL'" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end it "does not use available system gems with `vendor/bundle" do bundle "config set --local path vendor/bundle" bundle :install - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "uses system gems with `path.system` configured with more priority than `path`" do bundle "config set --local path.system true" bundle "config set --global path vendor/bundle" bundle :install - run "require 'rack'", raise_on_error: false + run "require 'myrack'", raise_on_error: false expect(out).to include("FAIL") end @@ -55,8 +55,8 @@ RSpec.describe "bundle install" do FileUtils.rm_rf bundled_app("vendor") bundle "install" - expect(vendored_gems("gems/rack-1.0.0")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(vendored_gems("gems/myrack-1.0.0")).to be_directory + expect(the_bundle).to include_gems "myrack 1.0.0" end context "with path_relative_to_cwd set to true" do @@ -66,7 +66,7 @@ RSpec.describe "bundle install" do bundle "install --gemfile='#{bundled_app}/Gemfile' --path vendor/bundle", dir: bundled_app.parent expect(out).to include("installed into `./vendor/bundle`") expect(bundled_app("../vendor/bundle")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs the standalone bundle relative to the cwd" do @@ -87,13 +87,13 @@ RSpec.describe "bundle install" do describe "when BUNDLE_PATH or the global path config is set" do before :each do - build_lib "rack", "1.0.0", to_system: true do |s| - s.write "lib/rack.rb", "raise 'FAIL'" + build_lib "myrack", "1.0.0", to_system: true do |s| + s.write "lib/myrack.rb", "raise 'FAIL'" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -112,9 +112,9 @@ RSpec.describe "bundle install" do bundle "config set --local path vendor/bundle" bundle :install - expect(vendored_gems("gems/rack-1.0.0")).to be_directory + expect(vendored_gems("gems/myrack-1.0.0")).to be_directory expect(bundled_app("vendor2")).not_to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs gems to ." do @@ -123,9 +123,9 @@ RSpec.describe "bundle install" do bundle :install - paths_to_exist = %w[cache/rack-1.0.0.gem gems/rack-1.0.0 specifications/rack-1.0.0.gemspec].map {|path| bundled_app(Bundler.ruby_scope, path) } + paths_to_exist = %w[cache/myrack-1.0.0.gem gems/myrack-1.0.0 specifications/myrack-1.0.0.gemspec].map {|path| bundled_app(Bundler.ruby_scope, path) } expect(paths_to_exist).to all exist - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs gems to the path" do @@ -133,8 +133,8 @@ RSpec.describe "bundle install" do bundle :install - expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(bundled_app("vendor", Bundler.ruby_scope, "gems/myrack-1.0.0")).to be_directory + expect(the_bundle).to include_gems "myrack 1.0.0" end it "installs gems to the path relative to root when relative" do @@ -143,8 +143,8 @@ RSpec.describe "bundle install" do FileUtils.mkdir_p bundled_app("lol") bundle :install, dir: bundled_app("lol") - expect(bundled_app("vendor", Bundler.ruby_scope, "gems/rack-1.0.0")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(bundled_app("vendor", Bundler.ruby_scope, "gems/myrack-1.0.0")).to be_directory + expect(the_bundle).to include_gems "myrack 1.0.0" end end end @@ -154,26 +154,26 @@ RSpec.describe "bundle install" do bundle :install - expect(vendored_gems("gems/rack-1.0.0")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(vendored_gems("gems/myrack-1.0.0")).to be_directory + expect(the_bundle).to include_gems "myrack 1.0.0" end it "sets BUNDLE_PATH as the first argument to bundle install" do bundle "config set --local path ./vendor/bundle" bundle :install - expect(vendored_gems("gems/rack-1.0.0")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(vendored_gems("gems/myrack-1.0.0")).to be_directory + expect(the_bundle).to include_gems "myrack 1.0.0" end it "disables system gems when passing a path to install" do # This is so that vendored gems can be distributed to others - build_gem "rack", "1.1.0", to_system: true + build_gem "myrack", "1.1.0", to_system: true bundle "config set --local path ./vendor/bundle" bundle :install - expect(vendored_gems("gems/rack-1.0.0")).to be_directory - expect(the_bundle).to include_gems "rack 1.0.0" + expect(vendored_gems("gems/myrack-1.0.0")).to be_directory + expect(the_bundle).to include_gems "myrack 1.0.0" end it "re-installs gems whose extensions have been deleted" do @@ -182,7 +182,7 @@ RSpec.describe "bundle install" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "very_simple_binary" G @@ -214,8 +214,8 @@ RSpec.describe "bundle install" do it "reports the file exists" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "config set --local path bundle" diff --git a/spec/bundler/install/prereleases_spec.rb b/spec/bundler/install/prereleases_spec.rb index 629eb89dac..57764ce722 100644 --- a/spec/bundler/install/prereleases_spec.rb +++ b/spec/bundler/install/prereleases_spec.rb @@ -13,7 +13,7 @@ RSpec.describe "bundle install" do describe "when prerelease gems are available" do it "finds prereleases" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "not_released" G expect(the_bundle).to include_gems "not_released 1.0.pre" @@ -21,7 +21,7 @@ RSpec.describe "bundle install" do it "uses regular releases if available" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "has_prerelease" G expect(the_bundle).to include_gems "has_prerelease 1.0" @@ -29,7 +29,7 @@ RSpec.describe "bundle install" do it "uses prereleases if requested" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "has_prerelease", "1.1.pre" G expect(the_bundle).to include_gems "has_prerelease 1.1.pre" @@ -38,17 +38,17 @@ RSpec.describe "bundle install" do describe "when prerelease gems are not available" do it "still works" do - build_repo gem_repo3 do - build_gem "rack" + build_repo3 do + build_gem "myrack" end FileUtils.rm_rf Dir[gem_repo3("prerelease*")] install_gemfile <<-G - source "#{file_uri_for(gem_repo3)}" - gem "rack" + source "https://gem.repo3" + gem "myrack" G - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end end diff --git a/spec/bundler/install/process_lock_spec.rb b/spec/bundler/install/process_lock_spec.rb index 1f8c62f26e..8082ec40fa 100644 --- a/spec/bundler/install/process_lock_spec.rb +++ b/spec/bundler/install/process_lock_spec.rb @@ -8,17 +8,17 @@ RSpec.describe "process lock spec" do thread = Thread.new do Bundler::ProcessLock.lock(default_bundle_path) do sleep 1 # ignore quality_spec - expect(the_bundle).not_to include_gems "rack 1.0" + expect(the_bundle).not_to include_gems "myrack 1.0" end end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G thread.join - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end context "when creating a lock raises Errno::ENOTSUP" do diff --git a/spec/bundler/install/redownload_spec.rb b/spec/bundler/install/redownload_spec.rb index 3a72c356d9..b522e22bd5 100644 --- a/spec/bundler/install/redownload_spec.rb +++ b/spec/bundler/install/redownload_spec.rb @@ -3,29 +3,29 @@ RSpec.describe "bundle install" do before :each do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end shared_examples_for "an option to force redownloading gems" do it "re-installs installed gems" do - rack_lib = default_bundle_path("gems/rack-1.0.0/lib/rack.rb") + myrack_lib = default_bundle_path("gems/myrack-1.0.0/lib/myrack.rb") bundle :install - rack_lib.open("w") {|f| f.write("blah blah blah") } + myrack_lib.open("w") {|f| f.write("blah blah blah") } bundle :install, flag => true - expect(out).to include "Installing rack 1.0.0" - expect(rack_lib.open(&:read)).to eq("RACK = '1.0.0'\n") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(out).to include "Installing myrack 1.0.0" + expect(myrack_lib.open(&:read)).to eq("MYRACK = '1.0.0'\n") + expect(the_bundle).to include_gems "myrack 1.0.0" end it "works on first bundle install" do bundle :install, flag => true - expect(out).to include "Installing rack 1.0.0" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(out).to include "Installing myrack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end context "with a git gem" do @@ -33,7 +33,7 @@ RSpec.describe "bundle install" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G end diff --git a/spec/bundler/install/security_policy_spec.rb b/spec/bundler/install/security_policy_spec.rb index befeb81da5..e7f64dc227 100644 --- a/spec/bundler/install/security_policy_spec.rb +++ b/spec/bundler/install/security_policy_spec.rb @@ -9,8 +9,8 @@ RSpec.describe "policies with unsigned gems" do before do build_security_repo gemfile <<-G - source "#{file_uri_for(security_repo)}" - gem "rack" + source "https://gems.security" + gem "myrack" gem "signed_gem" G end @@ -18,7 +18,7 @@ RSpec.describe "policies with unsigned gems" do it "will work after you try to deploy without a lock" do bundle "install --deployment", raise_on_error: false bundle :install - expect(the_bundle).to include_gems "rack 1.0", "signed_gem 1.0" + expect(the_bundle).to include_gems "myrack 1.0", "signed_gem 1.0" end it "will fail when given invalid security policy" do @@ -45,7 +45,7 @@ RSpec.describe "policies with signed gems and no CA" do before do build_security_repo gemfile <<-G - source "#{file_uri_for(security_repo)}" + source "https://gems.security" gem "signed_gem" G end diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb index 7408c24327..b2edd11acd 100644 --- a/spec/bundler/install/yanked_spec.rb +++ b/spec/bundler/install/yanked_spec.rb @@ -10,7 +10,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do it "throws an error when the original gem version is yanked" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: foo (10.0.0) @@ -23,7 +23,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do L install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "foo", "10.0.0" G @@ -35,7 +35,8 @@ RSpec.context "when installing a bundle that includes yanked gems" do skip "Materialization on Windows is not yet strict, so the example does not detect the gem has been yanked" if Gem.win_platform? build_repo4 do - build_gem "foo", "1.0.0", "1.0.1" + build_gem "foo", "1.0.0" + build_gem "foo", "1.0.1" build_gem "actiontext", "6.1.7" do |s| s.add_dependency "nokogiri", ">= 1.8" end @@ -76,10 +77,10 @@ RSpec.context "when installing a bundle that includes yanked gems" do end context "and the old index is used" do - let(:source_uri) { file_uri_for(gem_repo4) } + let(:source_uri) { "https://gem.repo4" } it "reports the yanked gem properly" do - bundle "install", raise_on_error: false + bundle "install", artifice: "endpoint", raise_on_error: false, verbose: true expect(err).to include("Your bundle is locked to nokogiri (1.13.8-#{Bundler.local_platform})") end @@ -100,7 +101,7 @@ RSpec.context "when installing a bundle that includes yanked gems" do bundle "config set force_ruby_platform true" install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "foo", "10.0.0" G @@ -120,7 +121,7 @@ RSpec.context "when resolving a bundle that includes yanked gems, but unlocking lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)} + remote: https://gem.repo4 specs: foo (9.0.0) bar (1.0.0) @@ -137,7 +138,7 @@ RSpec.context "when resolving a bundle that includes yanked gems, but unlocking L gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "foo" gem "bar" G @@ -148,7 +149,7 @@ RSpec.context "when resolving a bundle that includes yanked gems, but unlocking expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: bar (2.0.0) foo (9.0.0) @@ -169,65 +170,65 @@ end RSpec.context "when using gem before installing" do it "does not suggest the author has yanked the gem" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)} + remote: https://gem.repo1 specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (= 0.9.1) + myrack (= 0.9.1) L bundle :list, raise_on_error: false - expect(err).to include("Could not find rack-0.9.1 in cached gems or installed locally") - expect(err).to_not include("Your bundle is locked to rack (0.9.1) from") - expect(err).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.") - expect(err).to_not include("You'll need to update your bundle to a different version of rack (0.9.1) that hasn't been removed in order to install.") + expect(err).to include("Could not find myrack-0.9.1 in locally installed gems") + expect(err).to_not include("Your bundle is locked to myrack (0.9.1) from") + expect(err).to_not include("If you haven't changed sources, that means the author of myrack (0.9.1) has removed it.") + expect(err).to_not include("You'll need to update your bundle to a different version of myrack (0.9.1) that hasn't been removed in order to install.") # Check error message is still correct when multiple platforms are locked lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}") bundle :list, raise_on_error: false - expect(err).to include("Could not find rack-0.9.1 in cached gems or installed locally") + expect(err).to include("Could not find myrack-0.9.1 in locally installed gems") end it "does not suggest the author has yanked the gem when using more than one gem, but shows all gems that couldn't be found in the source" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" - gem "rack_middleware", "1.0" + source "https://gem.repo1" + gem "myrack", "0.9.1" + gem "myrack_middleware", "1.0" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)} + remote: https://gem.repo1 specs: - rack (0.9.1) - rack_middleware (1.0) + myrack (0.9.1) + myrack_middleware (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (= 0.9.1) - rack_middleware (1.0) + myrack (= 0.9.1) + myrack_middleware (1.0) L bundle :list, raise_on_error: false - expect(err).to include("Could not find rack-0.9.1, rack_middleware-1.0 in cached gems or installed locally") + expect(err).to include("Could not find myrack-0.9.1, myrack_middleware-1.0 in locally installed gems") expect(err).to include("Install missing gems with `bundle install`.") - expect(err).to_not include("Your bundle is locked to rack (0.9.1) from") - expect(err).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.") - expect(err).to_not include("You'll need to update your bundle to a different version of rack (0.9.1) that hasn't been removed in order to install.") + expect(err).to_not include("Your bundle is locked to myrack (0.9.1) from") + expect(err).to_not include("If you haven't changed sources, that means the author of myrack (0.9.1) has removed it.") + expect(err).to_not include("You'll need to update your bundle to a different version of myrack (0.9.1) that hasn't been removed in order to install.") end end diff --git a/spec/bundler/lock/git_spec.rb b/spec/bundler/lock/git_spec.rb index ad13e8ffc6..13c661ae14 100644 --- a/spec/bundler/lock/git_spec.rb +++ b/spec/bundler/lock/git_spec.rb @@ -5,7 +5,7 @@ RSpec.describe "bundle lock with git gems" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{lib_path("foo-1.0")}" G end @@ -24,7 +24,7 @@ RSpec.describe "bundle lock with git gems" do it "prints a proper error when changing a locked Gemfile to point to a bad branch" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{lib_path("foo-1.0")}", :branch => "bad" G @@ -42,7 +42,7 @@ RSpec.describe "bundle lock with git gems" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -87,7 +87,7 @@ RSpec.describe "bundle lock with git gems" do git "branch -D foo ", lib_path("foo-1.0") gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{lib_path("foo-1.0")}" G @@ -99,7 +99,7 @@ RSpec.describe "bundle lock with git gems" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -123,7 +123,7 @@ RSpec.describe "bundle lock with git gems" do annotated_tag = git("rev-parse v1.0", lib_path("foo-1.0")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{lib_path("foo-1.0")}" G @@ -135,7 +135,7 @@ RSpec.describe "bundle lock with git gems" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS diff --git a/spec/bundler/lock/lockfile_spec.rb b/spec/bundler/lock/lockfile_spec.rb index 4fd081e7d0..95022e291b 100644 --- a/spec/bundler/lock/lockfile_spec.rb +++ b/spec/bundler/lock/lockfile_spec.rb @@ -6,27 +6,27 @@ RSpec.describe "the lockfile format" do end it "generates a simple lockfile for a single source, gem" do - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo2, "rack", "1.0.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo2, "myrack", "1.0.0") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack" + gem "myrack" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -43,25 +43,25 @@ RSpec.describe "the lockfile format" do specs: GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES omg! - rack + myrack BUNDLED WITH 1.8.2 L install_gemfile <<-G, verbose: true, env: { "BUNDLER_VERSION" => Bundler::VERSION } - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack" + gem "myrack" G expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with 1.8.2.") @@ -69,44 +69,50 @@ RSpec.describe "the lockfile format" do expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + 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", rubygems: ">= 3.3.0.a", realworld: true do + it "does not update the lockfile's bundler version if nothing changed during bundle install, but uses the locked version", rubygems: ">= 3.3.0.a" do version = "2.3.0" + build_repo4 do + build_gem "myrack", "1.0.0" + + build_bundler version + end + lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo4/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH #{version} L - install_gemfile <<-G, verbose: true, artifice: "vcr" - source "#{file_uri_for(gem_repo2)}" + install_gemfile <<-G, verbose: true, preserve_ruby_flags: true + source "https://gem.repo4" - gem "rack" + gem "myrack" G expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{version}.") @@ -114,15 +120,15 @@ RSpec.describe "the lockfile format" do expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo4/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH #{version} @@ -132,30 +138,36 @@ RSpec.describe "the lockfile format" do it "does not update the lockfile's bundler version if nothing changed during bundle install, and uses the latest version", rubygems: "< 3.3.0.a" do version = "#{Bundler::VERSION.split(".").first}.0.0.a" + build_repo4 do + build_gem "myrack", "1.0.0" + + build_bundler version + end + checksums = checksums_section do |c| - c.checksum(gem_repo2, "rack", "1.0.0") + c.checksum(gem_repo4, "myrack", "1.0.0") end lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo4/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{version} L install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo4" - gem "rack" + gem "myrack" G expect(out).not_to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{version}.") @@ -163,15 +175,15 @@ RSpec.describe "the lockfile format" do expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo4/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{version} @@ -181,34 +193,34 @@ RSpec.describe "the lockfile format" do it "adds the BUNDLED WITH section if not present" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack L install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" - gem "rack", "> 0" + gem "myrack", "> 0" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (> 0) + myrack (> 0) BUNDLED WITH #{Bundler::VERSION} @@ -223,39 +235,39 @@ RSpec.describe "the lockfile format" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH #{older_major} L install_gemfile <<-G, env: { "BUNDLER_VERSION" => Bundler::VERSION } - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack" + gem "myrack" G expect(err).to be_empty expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH #{current_version} @@ -264,29 +276,29 @@ RSpec.describe "the lockfile format" do it "generates a simple lockfile for a single source, gem with dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack-obama" + gem "myrack-obama" G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "rack", "1.0.0" - c.checksum gem_repo2, "rack-obama", "1.0" + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) - rack-obama (1.0) - rack + myrack (1.0.0) + myrack-obama (1.0) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack-obama + myrack-obama #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -295,29 +307,29 @@ RSpec.describe "the lockfile format" do it "generates a simple lockfile for a single source, gem with a version requirement" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack-obama", ">= 1.0" + gem "myrack-obama", ">= 1.0" G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "rack", "1.0.0" - c.checksum gem_repo2, "rack-obama", "1.0" + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) - rack-obama (1.0) - rack + myrack (1.0.0) + myrack-obama (1.0) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack-obama (>= 1.0) + myrack-obama (>= 1.0) #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -325,66 +337,180 @@ RSpec.describe "the lockfile format" do end it "generates a lockfile without credentials" do - bundle "config set http://localgemserver.test/ user:pass" + bundle "config set https://localgemserver.test/ user:pass" install_gemfile(<<-G, artifice: "endpoint_strict_basic_authentication", quiet: true) - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" - source "http://localgemserver.test/" do + source "https://localgemserver.test/" do end - source "http://user:pass@othergemserver.test/" do - gem "rack-obama", ">= 1.0" + source "https://user:pass@othergemserver.test/" do + gem "myrack-obama", ">= 1.0" end G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "rack", "1.0.0" - c.checksum gem_repo2, "rack-obama", "1.0" + 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: #{file_uri_for(gem_repo1)}/ + 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: - rack (1.0.0) - rack-obama (1.0) - rack + myrack (1.0.0) + myrack-obama (1.0) + myrack + + GEM + remote: https://gem.repo1/ + specs: PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack-obama (>= 1.0)! + 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 "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" gem "net-sftp" G - checksums = checksums_section_when_existing do |c| + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: net-sftp (1.1.1) net-ssh (>= 1.0.0, < 1.99.0) @@ -407,11 +533,11 @@ RSpec.describe "the lockfile format" do git = build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end @@ -423,7 +549,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -441,13 +567,13 @@ RSpec.describe "the lockfile format" do build_lib "omg", path: lib_path("omg") gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" platforms :#{not_local_tag} do gem "omg", :path => "#{lib_path("omg")}" end - gem "rack" + gem "myrack" G lockfile <<-L @@ -457,34 +583,34 @@ RSpec.describe "the lockfile format" do specs: GEM - remote: #{file_uri_for(gem_repo2)}// + remote: https://gem.repo2// specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{not_local} DEPENDENCIES omg! - rack + myrack BUNDLED WITH #{Bundler::VERSION} L bundle "install" - expect(the_bundle).to include_gems "rack 1.0.0" + 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_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}" do gem "foo" end @@ -498,7 +624,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -516,12 +642,12 @@ RSpec.describe "the lockfile format" do git = build_git "foo" update_git "foo", branch: "omg" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :branch => "omg" G @@ -534,7 +660,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -552,12 +678,12 @@ RSpec.describe "the lockfile format" do git = build_git "foo" update_git "foo", tag: "omg" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}", :tag => "omg" G @@ -570,7 +696,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -600,7 +726,7 @@ RSpec.describe "the lockfile format" do s.add_dependency "orm_adapter" end - update_git "ckeditor", path: lib_path("ckeditor"), remote: file_uri_for(@remote.path) + 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" @@ -614,7 +740,7 @@ RSpec.describe "the lockfile format" do new_git = update_git "ckeditor", path: lib_path("ckeditor"), push: "v4.0.8" gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "ckeditor", :git => "#{@remote.path}", :tag => "v4.0.8" G @@ -628,7 +754,7 @@ RSpec.describe "the lockfile format" do orm_adapter GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: orm_adapter (0.4.1) @@ -655,7 +781,7 @@ RSpec.describe "the lockfile format" do orm_adapter GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: orm_adapter (0.4.1) @@ -673,12 +799,12 @@ RSpec.describe "the lockfile format" do it "serializes pinned path sources to the lockfile" do build_lib "foo" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :path => "#{lib_path("foo-1.0")}" G @@ -689,7 +815,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -706,15 +832,15 @@ RSpec.describe "the lockfile format" do it "serializes pinned path sources to the lockfile even when packaging" do build_lib "foo" - checksums = checksums_section_when_existing do |c| - c.no_checksum "foo", "1.0" - end - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + 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 "config set cache_all true" bundle :cache bundle :install, local: true @@ -726,7 +852,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -744,16 +870,16 @@ RSpec.describe "the lockfile format" do build_lib "foo" bar = build_git "bar" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" c.no_checksum "bar", "1.0" - c.checksum gem_repo2, "rack", "1.0.0" + c.checksum gem_repo2, "myrack", "1.0.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack" + gem "myrack" gem "foo", :path => "#{lib_path("foo-1.0")}" gem "bar", :git => "#{lib_path("bar-1.0")}" G @@ -771,9 +897,9 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} @@ -781,7 +907,7 @@ RSpec.describe "the lockfile format" do DEPENDENCIES bar! foo! - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -790,26 +916,26 @@ RSpec.describe "the lockfile format" do it "removes redundant sources" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack", :source => "#{file_uri_for(gem_repo2)}/" + gem "myrack", :source => "https://gem.repo2/" G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "rack", "1.0.0" + checksums = checksums_section_when_enabled do |c| + c.checksum gem_repo2, "myrack", "1.0.0" end expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack! + myrack! #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -818,40 +944,40 @@ RSpec.describe "the lockfile format" do it "lists gems alphabetically" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" gem "thin" gem "actionpack" - gem "rack-obama" + gem "myrack-obama" G - checksums = checksums_section_when_existing do |c| + 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, "rack", "1.0.0" - c.checksum gem_repo2, "rack-obama", "1.0" + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: actionpack (2.3.2) activesupport (= 2.3.2) activesupport (2.3.2) - rack (1.0.0) - rack-obama (1.0) - rack + myrack (1.0.0) + myrack-obama (1.0) + myrack thin (1.0) - rack + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES actionpack - rack-obama + myrack-obama thin #{checksums} BUNDLED WITH @@ -861,12 +987,12 @@ RSpec.describe "the lockfile format" do it "orders dependencies' dependencies in alphabetical order" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" gem "rails" G - checksums = checksums_section_when_existing do |c| + 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" @@ -878,7 +1004,7 @@ RSpec.describe "the lockfile format" do expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: actionmailer (2.3.2) activesupport (= 2.3.2) @@ -920,18 +1046,18 @@ RSpec.describe "the lockfile format" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2" gem 'double_deps' G - checksums = checksums_section_when_existing do |c| + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: double_deps (1.0) net-ssh @@ -951,29 +1077,29 @@ RSpec.describe "the lockfile format" do it "does not add the :require option to the lockfile" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack-obama", ">= 1.0", :require => "rack/obama" + gem "myrack-obama", ">= 1.0", :require => "myrack/obama" G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "rack", "1.0.0" - c.checksum gem_repo2, "rack-obama", "1.0" + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) - rack-obama (1.0) - rack + myrack (1.0.0) + myrack-obama (1.0) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack-obama (>= 1.0) + myrack-obama (>= 1.0) #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -982,29 +1108,29 @@ RSpec.describe "the lockfile format" do it "does not add the :group option to the lockfile" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack-obama", ">= 1.0", :group => :test + gem "myrack-obama", ">= 1.0", :group => :test G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "rack", "1.0.0" - c.checksum gem_repo2, "rack-obama", "1.0" + 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: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) - rack-obama (1.0) - rack + myrack (1.0.0) + myrack-obama (1.0) + myrack PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack-obama (>= 1.0) + myrack-obama (>= 1.0) #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1014,12 +1140,12 @@ RSpec.describe "the lockfile format" do 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_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "foo" do gem "foo" end @@ -1032,7 +1158,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -1049,12 +1175,12 @@ RSpec.describe "the lockfile format" do 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_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "../foo" do gem "foo" end @@ -1067,7 +1193,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -1084,17 +1210,17 @@ RSpec.describe "the lockfile format" do it "stores relative paths when the path is provided in an absolute fashion but is relative" do build_lib "foo", path: bundled_app("foo") - checksums = checksums_section_when_existing do |c| - c.no_checksum "foo", "1.0" - end - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + 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 @@ -1102,7 +1228,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -1117,14 +1243,14 @@ RSpec.describe "the lockfile format" do end it "stores relative paths when the path is provided for gemspec" do - build_lib("foo", path: tmp.join("foo")) + build_lib("foo", path: tmp("foo")) - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "1.0" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec :path => "../foo" G @@ -1135,7 +1261,7 @@ RSpec.describe "the lockfile format" do foo (1.0) GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: PLATFORMS @@ -1150,52 +1276,52 @@ RSpec.describe "the lockfile format" do end it "keeps existing platforms in the lockfile" do - checksums = checksums_section_when_existing do |c| - c.no_checksum "rack", "1.0.0" + checksums = checksums_section_when_enabled do |c| + c.no_checksum "myrack", "1.0.0" end lockfile <<-G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS java DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} G install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" - gem "rack" + gem "myrack" G - checksums.checksum(gem_repo2, "rack", "1.0.0") + checksums.checksum(gem_repo2, "myrack", "1.0.0") expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms("java", local_platform, defaults: [])} DEPENDENCIES - rack + 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 + 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" @@ -1209,14 +1335,19 @@ RSpec.describe "the lockfile format" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + 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: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: google-protobuf (3.25.1) google-protobuf (3.25.1-arm64-darwin-23) @@ -1228,7 +1359,7 @@ RSpec.describe "the lockfile format" do DEPENDENCIES google-protobuf - + #{checksums} BUNDLED WITH #{Bundler::VERSION} L @@ -1242,64 +1373,64 @@ RSpec.describe "the lockfile format" do end end - simulate_platform "universal-java-16" - - install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "platform_specific" - G + simulate_platform "universal-java-16" do + install_gemfile <<-G + source "https://gem.repo2" + gem "platform_specific" + G - checksums = checksums_section_when_existing do |c| - c.checksum gem_repo2, "platform_specific", "1.0", "universal-java-16" - end + 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: #{file_uri_for(gem_repo2)}/ - specs: - platform_specific (1.0-universal-java-16) + expect(lockfile).to eq <<~G + GEM + remote: https://gem.repo2/ + specs: + platform_specific (1.0-universal-java-16) - PLATFORMS - universal-java-16 + PLATFORMS + universal-java-16 - DEPENDENCIES - platform_specific - #{checksums} - BUNDLED WITH - #{Bundler::VERSION} - G + DEPENDENCIES + platform_specific + #{checksums} + BUNDLED WITH + #{Bundler::VERSION} + G + end end it "does not add duplicate gems" do - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.checksum(gem_repo2, "activesupport", "2.3.5") - c.checksum(gem_repo2, "rack", "1.0.0") + c.checksum(gem_repo2, "myrack", "1.0.0") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" - gem "rack" + source "https://gem.repo2/" + gem "myrack" G install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" - gem "rack" + source "https://gem.repo2/" + gem "myrack" gem "activesupport" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: activesupport (2.3.5) - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES activesupport - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1307,27 +1438,27 @@ RSpec.describe "the lockfile format" do end it "does not add duplicate dependencies" do - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo2, "rack", "1.0.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo2, "myrack", "1.0.0") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" - gem "rack" - gem "rack" + source "https://gem.repo2/" + gem "myrack" + gem "myrack" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1335,27 +1466,27 @@ RSpec.describe "the lockfile format" do end it "does not add duplicate dependencies with versions" do - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo2, "rack", "1.0.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo2, "myrack", "1.0.0") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" - gem "rack", "1.0" - gem "rack", "1.0" + source "https://gem.repo2/" + gem "myrack", "1.0" + gem "myrack", "1.0" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (= 1.0) + myrack (= 1.0) #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1363,27 +1494,27 @@ RSpec.describe "the lockfile format" do end it "does not add duplicate dependencies in different groups" do - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo2, "rack", "1.0.0") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo2, "myrack", "1.0.0") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" - gem "rack", "1.0", :group => :one - gem "rack", "1.0", :group => :two + source "https://gem.repo2/" + gem "myrack", "1.0", :group => :one + gem "myrack", "1.0", :group => :two G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (= 1.0) + myrack (= 1.0) #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1392,47 +1523,47 @@ RSpec.describe "the lockfile format" do it "raises if two different versions are used" do install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}/" - gem "rack", "1.0" - gem "rack", "1.1" + source "https://gem.repo2/" + gem "myrack", "1.0" + gem "myrack", "1.1" G expect(bundled_app_lock).not_to exist - expect(err).to include "rack (= 1.0) and rack (= 1.1)" + 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 "#{file_uri_for(gem_repo2)}/" - gem "rack" - gem "rack", :git => "git://hubz.com" + source "https://gem.repo2/" + gem "myrack" + gem "myrack", :git => "git://hubz.com" G expect(bundled_app_lock).not_to exist - expect(err).to include "rack (>= 0) should come from an unspecified source and git://hubz.com" + 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_existing do |c| - c.checksum(gem_repo2, "rack", "0.9.1") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo2, "myrack", "0.9.1") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" - gem "rack", "> 0.9", "< 1.0" + source "https://gem.repo2/" + gem "myrack", "> 0.9", "< 1.0" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (> 0.9, < 1.0) + myrack (> 0.9, < 1.0) #{checksums} BUNDLED WITH #{Bundler::VERSION} @@ -1440,27 +1571,27 @@ RSpec.describe "the lockfile format" do end it "captures the Ruby version in the lockfile" do - checksums = checksums_section_when_existing do |c| - c.checksum(gem_repo2, "rack", "0.9.1") + checksums = checksums_section_when_enabled do |c| + c.checksum(gem_repo2, "myrack", "0.9.1") end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}/" + source "https://gem.repo2/" ruby '#{Gem.ruby_version}' - gem "rack", "> 0.9", "< 1.0" + gem "myrack", "> 0.9", "< 1.0" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack (> 0.9, < 1.0) + myrack (> 0.9, < 1.0) #{checksums} RUBY VERSION #{Bundler::RubyVersion.system} @@ -1473,24 +1604,24 @@ RSpec.describe "the lockfile format" do it "raises a helpful error message when the lockfile is missing deps" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack_middleware (1.0) + myrack_middleware (1.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack_middleware + myrack_middleware L install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}" - gem "rack_middleware" + source "https://gem.repo2" + gem "myrack_middleware" G - expect(err).to include("Downloading rack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("rack", "= 0.9.1")})."). - and include("Running `bundle update rack_middleware` should fix the problem.") + expect(err).to include("Downloading myrack_middleware-1.0 revealed dependencies not in the API or the lockfile (#{Gem::Dependency.new("myrack", "= 0.9.1")})."). + and include("Running `bundle update myrack_middleware` should fix the problem.") end it "regenerates a lockfile with no specs" do @@ -1506,7 +1637,7 @@ RSpec.describe "the lockfile format" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: PLATFORMS @@ -1520,14 +1651,14 @@ RSpec.describe "the lockfile format" do G install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "direct_dependency" G expect(lockfile).to eq <<~G GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: direct_dependency (4.5.6) indirect_dependency @@ -1555,14 +1686,14 @@ RSpec.describe "the lockfile format" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "minitest-bisect" G # Corrupt lockfile (completely missing path_expander) lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: minitest-bisect (1.6.0) @@ -1581,7 +1712,7 @@ RSpec.describe "the lockfile format" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: minitest-bisect (1.6.0) path_expander (~> 1.1) @@ -1621,13 +1752,13 @@ RSpec.describe "the lockfile format" do end gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "minitest-bisect" G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: minitest-bisect (1.6.0) path_expander (~> 1.1) @@ -1647,7 +1778,7 @@ RSpec.describe "the lockfile format" do expect(lockfile).to eq <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: minitest-bisect (1.6.0) path_expander (~> 1.1) @@ -1673,36 +1804,36 @@ RSpec.describe "the lockfile format" do build_repo2 install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - gem "rack" + 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 "rack 1.0" + 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 "rack", "1.2" do |s| - s.executables = "rackup" + 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 "rack 1.2" + 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 "rack", "1.2" do |s| - s.executables = "rackup" + build_gem "myrack", "1.2" do |s| + s.executables = "myrackup" end end @@ -1713,7 +1844,7 @@ RSpec.describe "the lockfile format" do 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 "rack 1.2" + expect(the_bundle).to include_gems "myrack 1.2" end end @@ -1745,27 +1876,27 @@ RSpec.describe "the lockfile format" do it "refuses to install if Gemfile.lock contains conflict markers" do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}// + remote: https://gem.repo2// specs: <<<<<<< - rack (1.0.0) + myrack (1.0.0) ======= - rack (1.0.1) + myrack (1.0.1) >>>>>>> PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH #{Bundler::VERSION} L install_gemfile <<-G, raise_on_error: false - source "#{file_uri_for(gem_repo2)}/" - gem "rack" + source "https://gem.repo2/" + gem "myrack" G expect(err).to match(/your Gemfile.lock contains merge conflicts/i) diff --git a/spec/bundler/other/ext_spec.rb b/spec/bundler/other/ext_spec.rb index 4d954b474f..9fc0414b4d 100644 --- a/spec/bundler/other/ext_spec.rb +++ b/spec/bundler/other/ext_spec.rb @@ -53,8 +53,8 @@ end RSpec.describe "Gem::SourceIndex#refresh!" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb index 939b68a0bb..f05a8c43f8 100644 --- a/spec/bundler/other/major_deprecation_spec.rb +++ b/spec/bundler/other/major_deprecation_spec.rb @@ -6,8 +6,8 @@ RSpec.describe "major deprecations" do describe "Bundler" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -114,8 +114,8 @@ RSpec.describe "major deprecations" do context "bundle check --path" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "check --path vendor/bundle", raise_on_error: false @@ -136,8 +136,8 @@ RSpec.describe "major deprecations" do context "bundle check --path=" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "check --path=vendor/bundle", raise_on_error: false @@ -158,8 +158,8 @@ RSpec.describe "major deprecations" do context "bundle cache --all" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "cache --all", raise_on_error: false @@ -180,8 +180,8 @@ RSpec.describe "major deprecations" do context "bundle cache --path" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "cache --path foo", raise_on_error: false @@ -300,8 +300,8 @@ RSpec.describe "major deprecations" do describe "bundle update" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -321,8 +321,8 @@ RSpec.describe "major deprecations" do describe "bundle install --binstubs" do before do install_gemfile <<-G, binstubs: true - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -335,9 +335,9 @@ RSpec.describe "major deprecations" do context "bundle install with both gems.rb and Gemfile present" do it "should not warn about gems.rb" do - create_file "gems.rb", <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + gemfile "gems.rb", <<-G + source "https://gem.repo1" + gem "myrack" G bundle :install @@ -345,17 +345,17 @@ RSpec.describe "major deprecations" do end it "should print a proper warning, and use gems.rb" do - create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\"" + gemfile "gems.rb", "source 'https://gem.repo1'" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G expect(warnings).to include( "Multiple gemfiles (gems.rb and Gemfile) detected. Make sure you remove Gemfile and Gemfile.lock since bundler is ignoring them in favor of gems.rb and gems.locked." ) - expect(the_bundle).not_to include_gem "rack 1.0" + expect(the_bundle).not_to include_gem "myrack 1.0" end end @@ -364,8 +364,8 @@ RSpec.describe "major deprecations" do bundle "config set --local path vendor/bundle" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -407,8 +407,8 @@ RSpec.describe "major deprecations" do context "bundle install with multiple sources" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo3)}" - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo3" + source "https://gem.repo1" G end @@ -454,29 +454,29 @@ RSpec.describe "major deprecations" do context "bundle install in frozen mode with a lockfile with a single rubygems section with multiple remotes" do before do - build_repo gem_repo3 do - build_gem "rack", "0.9.1" + build_repo3 do + build_gem "myrack", "0.9.1" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - source "#{file_uri_for(gem_repo3)}" do - gem 'rack' + source "https://gem.repo1" + source "https://gem.repo3" do + gem 'myrack' end G lockfile <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ - remote: #{file_uri_for(gem_repo3)}/ + remote: https://gem.repo1/ + remote: https://gem.repo3/ specs: - rack (0.9.1) + myrack (0.9.1) PLATFORMS ruby DEPENDENCIES - rack! + myrack! BUNDLED WITH #{Bundler::VERSION} @@ -496,10 +496,10 @@ RSpec.describe "major deprecations" do context "when Bundler.setup is run in a ruby script" do before do - create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\"" + create_file "gems.rb", "source 'https://gem.repo1'" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :group => :test + source "https://gem.repo1" + gem "myrack", :group => :test G ruby <<-RUBY @@ -537,8 +537,8 @@ RSpec.describe "major deprecations" do context "bundle show" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -558,14 +558,14 @@ RSpec.describe "major deprecations" do context "bundle remove" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end context "with --install" do it "shows a deprecation warning", bundler: "< 3" do - bundle "remove rack --install" + bundle "remove myrack --install" expect(err).to include "[DEPRECATED] The `--install` flag has been deprecated. `bundle install` is triggered by default." end @@ -590,7 +590,7 @@ RSpec.describe "major deprecations" do context "bundle viz", :realworld do before do realworld_system_gems "ruby-graphviz --version 1.2.5" - create_file "gems.rb", "source \"#{file_uri_for(gem_repo1)}\"" + create_file "gems.rb", "source 'https://gem.repo1'" bundle "viz" end @@ -618,7 +618,12 @@ RSpec.describe "major deprecations" do pending "fails with a helpful message", bundler: "3" end - describe "deprecating rubocop", :readline do + describe "deprecating rubocop" do + before do + global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", + "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false" + end + context "bundle gem --rubocop" do before do bundle "gem my_new_gem --rubocop", raise_on_error: false diff --git a/spec/bundler/plugins/command_spec.rb b/spec/bundler/plugins/command_spec.rb index af132d6550..f8dacb0e51 100644 --- a/spec/bundler/plugins/command_spec.rb +++ b/spec/bundler/plugins/command_spec.rb @@ -18,7 +18,7 @@ RSpec.describe "command plugins" do end end - bundle "plugin install command-mah --source #{file_uri_for(gem_repo2)}" + bundle "plugin install command-mah --source https://gem.repo2" end it "executes without arguments" do @@ -29,7 +29,7 @@ RSpec.describe "command plugins" do end it "accepts the arguments" do - build_repo2 do + update_repo2 do build_plugin "the-echoer" do |s| s.write "plugins.rb", <<-RUBY module Resonance @@ -46,7 +46,7 @@ RSpec.describe "command plugins" do end end - bundle "plugin install the-echoer --source #{file_uri_for(gem_repo2)}" + bundle "plugin install the-echoer --source https://gem.repo2" expect(out).to include("Installed plugin the-echoer") bundle "echo tacos tofu lasange" @@ -54,7 +54,7 @@ RSpec.describe "command plugins" do end it "raises error on redeclaration of command" do - build_repo2 do + update_repo2 do build_plugin "copycat" do |s| s.write "plugins.rb", <<-RUBY module CopyCat @@ -69,7 +69,7 @@ RSpec.describe "command plugins" do end end - bundle "plugin install copycat --source #{file_uri_for(gem_repo2)}", raise_on_error: false + bundle "plugin install copycat --source https://gem.repo2", raise_on_error: false expect(out).not_to include("Installed plugin copycat") diff --git a/spec/bundler/plugins/hook_spec.rb b/spec/bundler/plugins/hook_spec.rb index f6ee0ba210..3f9053bbc8 100644 --- a/spec/bundler/plugins/hook_spec.rb +++ b/spec/bundler/plugins/hook_spec.rb @@ -13,17 +13,17 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install before-install-all-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install before-install-all-plugin --source https://gem.repo2" end it "runs before all rubygems are installed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" - gem "rack" + gem "myrack" G - expect(out).to include "gems to be installed rake, rack" + expect(out).to include "gems to be installed rake, myrack" end end @@ -39,18 +39,18 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install before-install-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install before-install-plugin --source https://gem.repo2" end it "runs before each rubygem is installed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" - gem "rack" + gem "myrack" G expect(out).to include "installing gem rake" - expect(out).to include "installing gem rack" + expect(out).to include "installing gem myrack" end end @@ -66,17 +66,17 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install after-install-all-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install after-install-all-plugin --source https://gem.repo2" end - it "runs after each rubygem is installed" do + it "runs after each all rubygems are installed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" - gem "rack" + gem "myrack" G - expect(out).to include "installed gems rake, rack" + expect(out).to include "installed gems rake, myrack" end end @@ -92,18 +92,18 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install after-install-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install after-install-plugin --source https://gem.repo2" end it "runs after each rubygem is installed" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" - gem "rack" + gem "myrack" G expect(out).to include "installed gem rake : installed" - expect(out).to include "installed gem rack : installed" + expect(out).to include "installed gem myrack : installed" end end @@ -119,12 +119,12 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install before-require-all-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install before-require-all-plugin --source https://gem.repo2" end it "runs before all rubygems are required" do install_gemfile_and_bundler_require - expect(out).to include "gems to be required rake, rack" + expect(out).to include "gems to be required rake, myrack" end end @@ -140,13 +140,13 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install before-require-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install before-require-plugin --source https://gem.repo2" end it "runs before each rubygem is required" do install_gemfile_and_bundler_require expect(out).to include "requiring gem rake" - expect(out).to include "requiring gem rack" + expect(out).to include "requiring gem myrack" end end @@ -162,12 +162,12 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install after-require-all-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install after-require-all-plugin --source https://gem.repo2" end it "runs after all rubygems are required" do install_gemfile_and_bundler_require - expect(out).to include "required gems rake, rack" + expect(out).to include "required gems rake, myrack" end end @@ -183,21 +183,21 @@ RSpec.describe "hook plugins" do end end - bundle "plugin install after-require-plugin --source #{file_uri_for(gem_repo2)}" + bundle "plugin install after-require-plugin --source https://gem.repo2" end it "runs after each rubygem is required" do install_gemfile_and_bundler_require expect(out).to include "required gem rake" - expect(out).to include "required gem rack" + expect(out).to include "required gem myrack" end end def install_gemfile_and_bundler_require install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" - gem "rack" + gem "myrack" G ruby <<-RUBY diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb index 20c2f1fd26..d0de607e6c 100644 --- a/spec/bundler/plugins/install_spec.rb +++ b/spec/bundler/plugins/install_spec.rb @@ -9,28 +9,28 @@ RSpec.describe "bundler plugin install" do end it "shows proper message when gem in not found in the source" do - bundle "plugin install no-foo --source #{file_uri_for(gem_repo1)}", raise_on_error: false + bundle "plugin install no-foo --source https://gem.repo1", raise_on_error: false expect(err).to include("Could not find") plugin_should_not_be_installed("no-foo") end it "installs from rubygems source" do - bundle "plugin install foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo --source https://gem.repo2" expect(out).to include("Installed plugin foo") plugin_should_be_installed("foo") end it "installs from rubygems source in frozen mode" do - bundle "plugin install foo --source #{file_uri_for(gem_repo2)}", env: { "BUNDLE_DEPLOYMENT" => "true" } + bundle "plugin install foo --source https://gem.repo2", env: { "BUNDLE_DEPLOYMENT" => "true" } expect(out).to include("Installed plugin foo") plugin_should_be_installed("foo") end it "installs from sources configured as Gem.sources without any flags" do - bundle "plugin install foo", env: { "BUNDLER_SPEC_GEM_SOURCES" => file_uri_for(gem_repo2).to_s } + bundle "plugin install foo", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_SOURCES" => "https://gem.repo2" } expect(out).to include("Installed plugin foo") plugin_should_be_installed("foo") @@ -45,18 +45,18 @@ RSpec.describe "bundler plugin install" do context "plugin is already installed" do before do - bundle "plugin install foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo --source https://gem.repo2" end it "doesn't install plugin again" do - bundle "plugin install foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo --source https://gem.repo2" expect(out).not_to include("Installing plugin foo") expect(out).not_to include("Installed plugin foo") end end it "installs multiple plugins" do - bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo kung-foo --source https://gem.repo2" expect(out).to include("Installed plugin foo") expect(out).to include("Installed plugin kung-foo") @@ -70,7 +70,7 @@ RSpec.describe "bundler plugin install" do build_plugin "kung-foo", "1.1" end - bundle "plugin install foo kung-foo --version '1.0' --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo kung-foo --version '1.0' --source https://gem.repo2" expect(out).to include("Installing foo 1.0") expect(out).to include("Installing kung-foo 1.0") @@ -82,18 +82,18 @@ RSpec.describe "bundler plugin install" do build_plugin "foo", "1.1" end - bundle "plugin install foo --version 1.0 --source #{file_uri_for(gem_repo2)} --verbose" + bundle "plugin install foo --version 1.0 --source https://gem.repo2 --verbose" expect(out).to include("Installing foo 1.0") - bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --verbose" + bundle "plugin install foo --source https://gem.repo2 --verbose" expect(out).to include("Installing foo 1.1") - bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --verbose" + bundle "plugin install foo --source https://gem.repo2 --verbose" expect(out).to include("Using foo 1.1") end it "raises an error when when --branch specified" do - bundle "plugin install foo --branch main --source #{file_uri_for(gem_repo2)}", raise_on_error: false + bundle "plugin install foo --branch main --source https://gem.repo2", raise_on_error: false expect(out).not_to include("Installed plugin foo") @@ -101,13 +101,13 @@ RSpec.describe "bundler plugin install" do end it "raises an error when --ref specified" do - bundle "plugin install foo --ref v1.2.3 --source #{file_uri_for(gem_repo2)}", raise_on_error: false + bundle "plugin install foo --ref v1.2.3 --source https://gem.repo2", raise_on_error: false expect(err).to include("--ref can only be used with git sources") end it "raises error when both --branch and --ref options are specified" do - bundle "plugin install foo --source #{file_uri_for(gem_repo2)} --branch main --ref v1.2.3", raise_on_error: false + bundle "plugin install foo --source https://gem.repo2 --branch main --ref v1.2.3", raise_on_error: false expect(out).not_to include("Installed plugin foo") @@ -131,7 +131,7 @@ RSpec.describe "bundler plugin install" do s.write("src/fubar.rb") end end - bundle "plugin install testing --source #{file_uri_for(gem_repo2)}" + bundle "plugin install testing --source https://gem.repo2" bundle "check2", "no-color" => false expect(out).to eq("mate") @@ -144,17 +144,17 @@ RSpec.describe "bundler plugin install" do build_plugin "kung-foo", "1.1" end - bundle "plugin install foo kung-foo --version '1.0' --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo kung-foo --version '1.0' --source https://gem.repo2" expect(out).to include("Installing foo 1.0") expect(out).to include("Installing kung-foo 1.0") plugin_should_be_installed("foo", "kung-foo") - build_repo2 do + update_repo2 do build_gem "charlie" end - bundle "plugin install charlie --source #{file_uri_for(gem_repo2)}", raise_on_error: false + bundle "plugin install charlie --source https://gem.repo2", raise_on_error: false expect(err).to include("Failed to install plugin `charlie`, due to Bundler::Plugin::MalformattedPlugin (plugins.rb was not found in the plugin.)") @@ -173,7 +173,7 @@ RSpec.describe "bundler plugin install" do end end - bundle "plugin install chaplin --source #{file_uri_for(gem_repo2)}", raise_on_error: false + bundle "plugin install chaplin --source https://gem.repo2", raise_on_error: false expect(global_plugin_gem("chaplin-1.0")).not_to be_directory @@ -187,7 +187,7 @@ RSpec.describe "bundler plugin install" do s.write "plugins.rb" end - bundle "plugin install foo --git #{file_uri_for(lib_path("foo-1.0"))}" + bundle "plugin install foo --git #{lib_path("foo-1.0")}" expect(out).to include("Installed plugin foo") plugin_should_be_installed("foo") @@ -257,9 +257,9 @@ RSpec.describe "bundler plugin install" do it "installs plugins listed in gemfile" do gemfile <<-G - source '#{file_uri_for(gem_repo2)}' + source 'https://gem.repo2' plugin 'foo' - gem 'rack', "1.0.0" + gem 'myrack', "1.0.0" G bundle "install" @@ -268,7 +268,7 @@ RSpec.describe "bundler plugin install" do expect(out).to include("Bundle complete!") - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") plugin_should_be_installed("foo") end @@ -278,7 +278,7 @@ RSpec.describe "bundler plugin install" do end gemfile <<-G - source '#{file_uri_for(gem_repo2)}' + source 'https://gem.repo2' plugin 'foo', "1.0" G @@ -297,7 +297,7 @@ RSpec.describe "bundler plugin install" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" plugin 'ga-plugin', :git => "#{lib_path("ga-plugin-1.0")}" G @@ -311,7 +311,7 @@ RSpec.describe "bundler plugin install" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" plugin 'ga-plugin', :path => "#{lib_path("ga-plugin-1.0")}" G @@ -326,7 +326,7 @@ RSpec.describe "bundler plugin install" do path = lib_path("ga-plugin-1.0").relative_path_from(bundled_app) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" plugin 'ga-plugin', :path => "#{path}" G @@ -337,22 +337,22 @@ RSpec.describe "bundler plugin install" do context "in deployment mode" do it "installs plugins" do install_gemfile <<-G - source '#{file_uri_for(gem_repo2)}' - gem 'rack', "1.0.0" + source 'https://gem.repo2' + gem 'myrack', "1.0.0" G bundle "config set --local deployment true" install_gemfile <<-G - source '#{file_uri_for(gem_repo2)}' + source 'https://gem.repo2' plugin 'foo' - gem 'rack', "1.0.0" + gem 'myrack', "1.0.0" G expect(out).to include("Installed plugin foo") expect(out).to include("Bundle complete!") - expect(the_bundle).to include_gems("rack 1.0.0") + expect(the_bundle).to include_gems("myrack 1.0.0") plugin_should_be_installed("foo") end end @@ -364,12 +364,12 @@ RSpec.describe "bundler plugin install" do require "bundler/inline" gemfile do - source '#{file_uri_for(gem_repo2)}' + source 'https://gem.repo2' plugin 'foo' end RUBY - ruby code, env: { "BUNDLER_VERSION" => Bundler::VERSION } + ruby code, artifice: "compact_index", env: { "BUNDLER_VERSION" => Bundler::VERSION } expect(local_plugin_gem("foo-1.0", "plugins.rb")).to exist end end @@ -378,7 +378,7 @@ RSpec.describe "bundler plugin install" do it "is installed when inside an app" do allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) gemfile "" - bundle "plugin install foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo --source https://gem.repo2" plugin_should_be_installed("foo") expect(local_plugin_gem("foo-1.0")).to be_directory @@ -401,7 +401,7 @@ RSpec.describe "bundler plugin install" do end # inside the app - gemfile "source '#{file_uri_for(gem_repo2)}'\nplugin 'fubar'" + gemfile "source 'https://gem.repo2'\nplugin 'fubar'" bundle "install" update_repo2 do @@ -419,7 +419,7 @@ RSpec.describe "bundler plugin install" do end # outside the app - bundle "plugin install fubar --source #{file_uri_for(gem_repo2)}", dir: tmp + bundle "plugin install fubar --source https://gem.repo2", dir: tmp end it "inside the app takes precedence over global plugin" do diff --git a/spec/bundler/plugins/list_spec.rb b/spec/bundler/plugins/list_spec.rb index 4a686415ad..30e3f82467 100644 --- a/spec/bundler/plugins/list_spec.rb +++ b/spec/bundler/plugins/list_spec.rb @@ -38,7 +38,7 @@ RSpec.describe "bundler plugin list" do context "single plugin installed" do it "shows plugin name with commands list" do - bundle "plugin install foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo --source https://gem.repo2" plugin_should_be_installed("foo") bundle "plugin list" @@ -49,7 +49,7 @@ RSpec.describe "bundler plugin list" do context "multiple plugins installed" do it "shows plugin names with commands list" do - bundle "plugin install foo bar --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo bar --source https://gem.repo2" plugin_should_be_installed("foo", "bar") bundle "plugin list" diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb index e569f3e415..32940bf849 100644 --- a/spec/bundler/plugins/source/example_spec.rb +++ b/spec/bundler/plugins/source/example_spec.rb @@ -52,7 +52,7 @@ RSpec.describe "real source plugins" do build_lib "a-path-gem" gemfile <<-G - source "#{file_uri_for(gem_repo2)}" # plugin source + source "https://gem.repo2" # plugin source source "#{lib_path("a-path-gem-1.0")}", :type => :mpath do gem "a-path-gem" end @@ -70,7 +70,7 @@ RSpec.describe "real source plugins" do it "writes to lock file" do bundle "install" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "a-path-gem", "1.0" end @@ -82,7 +82,7 @@ RSpec.describe "real source plugins" do a-path-gem (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -110,7 +110,7 @@ RSpec.describe "real source plugins" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" # plugin source + source "https://gem.repo2" # plugin source source "#{lib_path("gem_with_bin-1.0")}", :type => :mpath do gem "gem_with_bin" end @@ -170,7 +170,7 @@ RSpec.describe "real source plugins" do a-path-gem (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -323,8 +323,8 @@ RSpec.describe "real source plugins" do build_git "ma-gitp-gem" gemfile <<-G - source "#{file_uri_for(gem_repo2)}" # plugin source - source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do + source "https://gem.repo2" # plugin source + source "#{lib_path("ma-gitp-gem-1.0")}", :type => :gitp do gem "ma-gitp-gem" end G @@ -340,20 +340,20 @@ RSpec.describe "real source plugins" do revision = revision_for(lib_path("ma-gitp-gem-1.0")) bundle "install" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "ma-gitp-gem", "1.0" end expect(lockfile).to eq <<~G PLUGIN SOURCE - remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))} + remote: #{lib_path("ma-gitp-gem-1.0")} type: gitp revision: #{revision} specs: ma-gitp-gem (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -372,14 +372,14 @@ RSpec.describe "real source plugins" do revision = revision_for(lib_path("ma-gitp-gem-1.0")) lockfile <<-G PLUGIN SOURCE - remote: #{file_uri_for(lib_path("ma-gitp-gem-1.0"))} + remote: #{lib_path("ma-gitp-gem-1.0")} type: gitp revision: #{revision} specs: ma-gitp-gem (1.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -423,8 +423,8 @@ RSpec.describe "real source plugins" do it "updates the deps on change in gemfile" do update_git "ma-gitp-gem", "1.1", path: lib_path("ma-gitp-gem-1.0"), gemspec: true gemfile <<-G - source "#{file_uri_for(gem_repo2)}" # plugin source - source "#{file_uri_for(lib_path("ma-gitp-gem-1.0"))}", :type => :gitp do + source "https://gem.repo2" # plugin source + source "#{lib_path("ma-gitp-gem-1.0")}", :type => :gitp do gem "ma-gitp-gem", "1.1" end G @@ -440,7 +440,7 @@ RSpec.describe "real source plugins" do ref = git.ref_for("main", 11) install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" # plugin source + source "https://gem.repo2" # plugin source source '#{lib_path("foo-1.0")}', :type => :gitp do gem "foo" end diff --git a/spec/bundler/plugins/source_spec.rb b/spec/bundler/plugins/source_spec.rb index 14643e5c81..995e50e653 100644 --- a/spec/bundler/plugins/source_spec.rb +++ b/spec/bundler/plugins/source_spec.rb @@ -16,8 +16,8 @@ RSpec.describe "bundler source plugin" do it "installs bundler-source-* gem when no handler for source is present" do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do + source "https://gem.repo2" + source "#{lib_path("gitp")}", :type => :psource do end G @@ -38,8 +38,8 @@ RSpec.describe "bundler source plugin" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" - source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do + source "https://gem.repo2" + source "#{lib_path("gitp")}", :type => :psource do end G @@ -62,11 +62,11 @@ RSpec.describe "bundler source plugin" do context "explicit presence in gemfile" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" plugin "another-psource" - source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do + source "#{lib_path("gitp")}", :type => :psource do end G end @@ -88,11 +88,11 @@ RSpec.describe "bundler source plugin" do context "explicit default source" do before do install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" plugin "bundler-source-psource" - source "#{file_uri_for(lib_path("gitp"))}", :type => :psource do + source "#{lib_path("gitp")}", :type => :psource do end G end diff --git a/spec/bundler/plugins/uninstall_spec.rb b/spec/bundler/plugins/uninstall_spec.rb index 555c6a7002..dedcc9f37c 100644 --- a/spec/bundler/plugins/uninstall_spec.rb +++ b/spec/bundler/plugins/uninstall_spec.rb @@ -14,7 +14,7 @@ RSpec.describe "bundler plugin uninstall" do end it "uninstalls specified plugins" do - bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo kung-foo --source https://gem.repo2" plugin_should_be_installed("foo") plugin_should_be_installed("kung-foo") @@ -40,9 +40,9 @@ RSpec.describe "bundler plugin uninstall" do allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) install_gemfile <<-G - source '#{file_uri_for(gem_repo2)}' + source 'https://gem.repo2' plugin 'path_plugin', :path => "#{path}" - gem 'rack', '1.0.0' + gem 'myrack', '1.0.0' G plugin_should_be_installed("path_plugin") @@ -57,7 +57,7 @@ RSpec.describe "bundler plugin uninstall" do describe "with --all" do it "uninstalls all installed plugins" do - bundle "plugin install foo kung-foo --source #{file_uri_for(gem_repo2)}" + bundle "plugin install foo kung-foo --source https://gem.repo2" plugin_should_be_installed("foo") plugin_should_be_installed("kung-foo") diff --git a/spec/bundler/quality_spec.rb b/spec/bundler/quality_spec.rb index 7cdb993017..c7fce17b62 100644 --- a/spec/bundler/quality_spec.rb +++ b/spec/bundler/quality_spec.rb @@ -236,6 +236,21 @@ RSpec.describe "The library itself" do expect(all_bad_requires).to be_empty, "#{all_bad_requires.size} internal requires that should use `require_relative`: #{all_bad_requires}" end + # We don't want our artifice code to activate bundler, but it needs to use the + # namespaced implementation of `Net::HTTP`. So we duplicate the file in + # bundler that loads that. + it "keeps vendored_net_http spec code in sync with the lib implementation" do + lib_implementation_path = File.join(source_lib_dir, "bundler", "vendored_net_http.rb") + expect(File.exist?(lib_implementation_path)).to be_truthy + lib_code = File.read(lib_implementation_path) + + spec_implementation_path = File.join(spec_dir, "support", "vendored_net_http.rb") + expect(File.exist?(spec_implementation_path)).to be_truthy + spec_code = File.read(spec_implementation_path) + + expect(lib_code).to eq(spec_code) + end + private def each_line(filename, &block) diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb index 94ca3554b1..dc15c56c79 100644 --- a/spec/bundler/realworld/edgecases_spec.rb +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -198,18 +198,7 @@ RSpec.describe "real world edgecases", realworld: true do expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0")) end - it "outputs a helpful error message when gems have invalid gemspecs", rubygems: "< 3.3.16" do - install_gemfile <<-G, standalone: true, raise_on_error: false, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" } - source 'https://rubygems.org' - gem "resque-scheduler", "2.2.0" - gem "redis-namespace", "1.6.0" # for a consistent resolution including ruby 2.3.0 - gem "ruby2_keywords", "0.0.5" - G - expect(err).to include("You have one or more invalid gemspecs that need to be fixed.") - expect(err).to include("resque-scheduler 2.2.0 has an invalid gemspec") - end - - it "outputs a helpful warning when gems have a gemspec with invalid `require_paths`", rubygems: ">= 3.3.16" do + it "outputs a helpful warning when gems have a gemspec with invalid `require_paths`" do install_gemfile <<-G, standalone: true, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "1" } source 'https://rubygems.org' gem "resque-scheduler", "2.2.0" diff --git a/spec/bundler/resolver/basic_spec.rb b/spec/bundler/resolver/basic_spec.rb index 4a0dd37bf9..f152907d35 100644 --- a/spec/bundler/resolver/basic_spec.rb +++ b/spec/bundler/resolver/basic_spec.rb @@ -6,15 +6,15 @@ RSpec.describe "Resolving" do end it "resolves a single gem" do - dep "rack" + dep "myrack" - should_resolve_as %w[rack-1.1] + should_resolve_as %w[myrack-1.1] end it "resolves a gem with dependencies" do dep "actionpack" - should_resolve_as %w[actionpack-2.3.5 activesupport-2.3.5 rack-1.0] + should_resolve_as %w[actionpack-2.3.5 activesupport-2.3.5 myrack-1.0] end it "resolves a conflicting index" do @@ -84,7 +84,7 @@ RSpec.describe "Resolving" do dep "activesupport", "= 3.0.0.beta" dep "actionpack" - should_resolve_as %w[activesupport-3.0.0.beta actionpack-3.0.0.beta rack-1.1 rack-mount-0.6] + should_resolve_as %w[activesupport-3.0.0.beta actionpack-3.0.0.beta myrack-1.1 myrack-mount-0.6] end it "prefers non-pre-releases when doing conservative updates" do @@ -313,10 +313,10 @@ RSpec.describe "Resolving" do it "handles versions that redundantly depend on themselves" do @index = build_index do - gem "rack", "3.0.0" + gem "myrack", "3.0.0" gem "standalone_migrations", "7.1.0" do - dep "rack", "~> 2.0" + dep "myrack", "~> 2.0" end gem "standalone_migrations", "2.0.4" do @@ -324,22 +324,22 @@ RSpec.describe "Resolving" do end gem "standalone_migrations", "1.0.13" do - dep "rack", ">= 0" + dep "myrack", ">= 0" end end - dep "rack", "~> 3.0" + dep "myrack", "~> 3.0" dep "standalone_migrations" - should_resolve_as %w[rack-3.0.0 standalone_migrations-2.0.4] + should_resolve_as %w[myrack-3.0.0 standalone_migrations-2.0.4] end it "ignores versions that incorrectly depend on themselves" do @index = build_index do - gem "rack", "3.0.0" + gem "myrack", "3.0.0" gem "standalone_migrations", "7.1.0" do - dep "rack", "~> 2.0" + dep "myrack", "~> 2.0" end gem "standalone_migrations", "2.0.4" do @@ -347,22 +347,22 @@ RSpec.describe "Resolving" do end gem "standalone_migrations", "1.0.13" do - dep "rack", ">= 0" + dep "myrack", ">= 0" end end - dep "rack", "~> 3.0" + dep "myrack", "~> 3.0" dep "standalone_migrations" - should_resolve_as %w[rack-3.0.0 standalone_migrations-1.0.13] + should_resolve_as %w[myrack-3.0.0 standalone_migrations-1.0.13] end it "does not ignore versions that incorrectly depend on themselves when dependency_api is not available" do @index = build_index do - gem "rack", "3.0.0" + gem "myrack", "3.0.0" gem "standalone_migrations", "7.1.0" do - dep "rack", "~> 2.0" + dep "myrack", "~> 2.0" end gem "standalone_migrations", "2.0.4" do @@ -370,13 +370,13 @@ RSpec.describe "Resolving" do end gem "standalone_migrations", "1.0.13" do - dep "rack", ">= 0" + dep "myrack", ">= 0" end end - dep "rack", "~> 3.0" + dep "myrack", "~> 3.0" dep "standalone_migrations" - should_resolve_without_dependency_api %w[rack-3.0.0 standalone_migrations-2.0.4] + should_resolve_without_dependency_api %w[myrack-3.0.0 standalone_migrations-2.0.4] end end diff --git a/spec/bundler/runtime/executable_spec.rb b/spec/bundler/runtime/executable_spec.rb index 36ce6dcf67..b11c48539a 100644 --- a/spec/bundler/runtime/executable_spec.rb +++ b/spec/bundler/runtime/executable_spec.rb @@ -3,83 +3,83 @@ RSpec.describe "Running bin/* commands" do before :each do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end it "runs the bundled command when in the bundle" do - bundle "binstubs rack" + bundle "binstubs myrack" - build_gem "rack", "2.0", to_system: true do |s| - s.executables = "rackup" + build_gem "myrack", "2.0", to_system: true do |s| + s.executables = "myrackup" end - gembin "rackup" + gembin "myrackup" expect(out).to eq("1.0.0") end it "allows the location of the gem stubs to be specified" do - bundle "binstubs rack", path: "gbin" + bundle "binstubs myrack", path: "gbin" expect(bundled_app("bin")).not_to exist - expect(bundled_app("gbin/rackup")).to exist + expect(bundled_app("gbin/myrackup")).to exist - gembin bundled_app("gbin/rackup") + gembin bundled_app("gbin/myrackup") expect(out).to eq("1.0.0") end it "allows absolute paths as a specification of where to install bin stubs" do - bundle "binstubs rack", path: tmp("bin") + bundle "binstubs myrack", path: tmp("bin") - gembin tmp("bin/rackup") + gembin tmp("bin/myrackup") expect(out).to eq("1.0.0") end it "uses the default ruby install name when shebang is not specified" do - bundle "binstubs rack" - expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env #{RbConfig::CONFIG["ruby_install_name"]}\n") + bundle "binstubs myrack" + expect(File.readlines(bundled_app("bin/myrackup")).first).to eq("#!/usr/bin/env #{RbConfig::CONFIG["ruby_install_name"]}\n") end it "allows the name of the shebang executable to be specified" do - bundle "binstubs rack", shebang: "ruby-foo" - expect(File.readlines(bundled_app("bin/rackup")).first).to eq("#!/usr/bin/env ruby-foo\n") + bundle "binstubs myrack", shebang: "ruby-foo" + expect(File.readlines(bundled_app("bin/myrackup")).first).to eq("#!/usr/bin/env ruby-foo\n") end it "runs the bundled command when out of the bundle" do - bundle "binstubs rack" + bundle "binstubs myrack" - build_gem "rack", "2.0", to_system: true do |s| - s.executables = "rackup" + build_gem "myrack", "2.0", to_system: true do |s| + s.executables = "myrackup" end - gembin "rackup", dir: tmp + gembin "myrackup", dir: tmp expect(out).to eq("1.0.0") end it "works with gems in path" do - build_lib "rack", path: lib_path("rack") do |s| - s.executables = "rackup" + build_lib "myrack", path: lib_path("myrack") do |s| + s.executables = "myrackup" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :path => "#{lib_path("rack")}" + source "https://gem.repo1" + gem "myrack", :path => "#{lib_path("myrack")}" G - bundle "binstubs rack" + bundle "binstubs myrack" - build_gem "rack", "2.0", to_system: true do |s| - s.executables = "rackup" + build_gem "myrack", "2.0", to_system: true do |s| + s.executables = "myrackup" end - gembin "rackup" + gembin "myrackup" expect(out).to eq("1.0") end it "creates a bundle binstub" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bundler" G @@ -91,17 +91,17 @@ RSpec.describe "Running bin/* commands" do it "does not generate bin stubs if the option was not specified" do bundle "install" - expect(bundled_app("bin/rackup")).not_to exist + expect(bundled_app("bin/myrackup")).not_to exist end it "allows you to stop installing binstubs", bundler: "< 3" do skip "delete permission error" if Gem.win_platform? bundle "install --binstubs bin/" - bundled_app("bin/rackup").rmtree + bundled_app("bin/myrackup").rmtree bundle "install --binstubs \"\"" - expect(bundled_app("bin/rackup")).not_to exist + expect(bundled_app("bin/myrackup")).not_to exist bundle "config bin" expect(out).to include("You have not configured a value for `bin`") @@ -109,34 +109,34 @@ RSpec.describe "Running bin/* commands" do it "remembers that the option was specified", bundler: "< 3" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" G bundle :install, binstubs: "bin" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" - gem "rack" + gem "myrack" G bundle "install" - expect(bundled_app("bin/rackup")).to exist + expect(bundled_app("bin/myrackup")).to exist end it "rewrites bins on binstubs (to maintain backwards compatibility)" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G - create_file("bin/rackup", "OMG") + create_file("bin/myrackup", "OMG") - bundle "binstubs rack" + bundle "binstubs myrack" - expect(bundled_app("bin/rackup").read).to_not eq("OMG") + expect(bundled_app("bin/myrackup").read).to_not eq("OMG") end it "use BUNDLE_GEMFILE gemfile for binstub" do @@ -148,8 +148,8 @@ RSpec.describe "Running bin/* commands" do build_gem("bindir") {|s| s.executables = "foo" } end - create_file("OtherGemfile", <<-G) - source "#{file_uri_for(gem_repo2)}" + gemfile("OtherGemfile", <<-G) + source "https://gem.repo2" gem 'bindir' G diff --git a/spec/bundler/runtime/gem_tasks_spec.rb b/spec/bundler/runtime/gem_tasks_spec.rb index f7afc0eb92..046300391b 100644 --- a/spec/bundler/runtime/gem_tasks_spec.rb +++ b/spec/bundler/runtime/gem_tasks_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true RSpec.describe "require 'bundler/gem_tasks'" do - before :each do + let(:define_local_gem_using_gem_tasks) do bundled_app("foo.gemspec").open("w") do |f| f.write <<-GEMSPEC Gem::Specification.new do |s| @@ -20,13 +20,52 @@ RSpec.describe "require 'bundler/gem_tasks'" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" + + gem "rake" + G + end + + let(:define_local_gem_with_extensions_using_gem_tasks_and_gemspec_dsl) do + bundled_app("foo.gemspec").open("w") do |f| + f.write <<-GEMSPEC + Gem::Specification.new do |s| + s.name = "foo" + s.version = "1.0" + s.summary = "dummy" + s.author = "Perry Mason" + s.extensions = "ext/extconf.rb" + end + GEMSPEC + end + + bundled_app("Rakefile").open("w") do |f| + f.write <<-RAKEFILE + require "bundler/gem_tasks" + RAKEFILE + end + + Dir.mkdir bundled_app("ext") + + bundled_app("ext/extconf.rb").open("w") do |f| + f.write <<-EXTCONF + require "mkmf" + File.write("Makefile", dummy_makefile($srcdir).join) + EXTCONF + end + + install_gemfile <<-G + source "https://gem.repo1" + + gemspec gem "rake" G end it "includes the relevant tasks" do + define_local_gem_using_gem_tasks + with_gem_path_as(base_system_gem_path.to_s) do sys_exec "#{rake} -T", env: { "GEM_HOME" => system_gem_path.to_s } end @@ -44,6 +83,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do end it "defines a working `rake install` task", :ruby_repo do + define_local_gem_using_gem_tasks + with_gem_path_as(base_system_gem_path.to_s) do sys_exec "#{rake} install", env: { "GEM_HOME" => system_gem_path.to_s } end @@ -55,9 +96,19 @@ RSpec.describe "require 'bundler/gem_tasks'" do expect(err).to be_empty end + it "defines a working `rake install` task for local gems with extensions", :ruby_repo do + define_local_gem_with_extensions_using_gem_tasks_and_gemspec_dsl + + bundle "exec rake install" + + expect(err).to be_empty + end + context "rake build when path has spaces", :ruby_repo do before do - spaced_bundled_app = tmp.join("bundled app") + define_local_gem_using_gem_tasks + + spaced_bundled_app = tmp("bundled app") FileUtils.cp_r bundled_app, spaced_bundled_app bundle "exec rake build", dir: spaced_bundled_app end @@ -69,7 +120,9 @@ RSpec.describe "require 'bundler/gem_tasks'" do context "rake build when path has brackets", :ruby_repo do before do - bracketed_bundled_app = tmp.join("bundled[app") + define_local_gem_using_gem_tasks + + bracketed_bundled_app = tmp("bundled[app") FileUtils.cp_r bundled_app, bracketed_bundled_app bundle "exec rake build", dir: bracketed_bundled_app end @@ -81,12 +134,14 @@ RSpec.describe "require 'bundler/gem_tasks'" do context "bundle path configured locally" do before do + define_local_gem_using_gem_tasks + bundle "config set path vendor/bundle" end it "works", :ruby_repo do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake" G @@ -98,6 +153,8 @@ RSpec.describe "require 'bundler/gem_tasks'" do end it "adds 'pkg' to rake/clean's CLOBBER" do + define_local_gem_using_gem_tasks + with_gem_path_as(base_system_gem_path.to_s) do sys_exec %(#{rake} -e 'load "Rakefile"; puts CLOBBER.inspect'), env: { "GEM_HOME" => system_gem_path.to_s } end diff --git a/spec/bundler/runtime/inline_spec.rb b/spec/bundler/runtime/inline_spec.rb index 50a5258dc7..5ff555ab0d 100644 --- a/spec/bundler/runtime/inline_spec.rb +++ b/spec/bundler/runtime/inline_spec.rb @@ -2,10 +2,9 @@ RSpec.describe "bundler/inline#gemfile" do def script(code, options = {}) - requires = ["bundler/inline"] - requires.unshift "#{spec_dir}/support/artifice/" + options.delete(:artifice) if options.key?(:artifice) - requires = requires.map {|r| "require '#{r}'" }.join("\n") - ruby("#{requires}\n\n" + code, options) + options[:artifice] ||= "compact_index" + options[:env] ||= { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } + ruby("require 'bundler/inline'\n\n" + code, options) end before :each do @@ -48,7 +47,7 @@ RSpec.describe "bundler/inline#gemfile" do it "requires the gems" do script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "two" end @@ -59,7 +58,7 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY, raise_on_error: false gemfile do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "eleven" end @@ -73,12 +72,12 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile(true) do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end RUBY - expect(out).to include("Rack's post install message") + expect(out).to include("Myrack's post install message") script <<-RUBY, artifice: "endpoint" gemfile(true) do @@ -143,7 +142,7 @@ RSpec.describe "bundler/inline#gemfile" do require 'bundler' options = { :ui => Bundler::UI::Shell.new } gemfile(false, options) do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "two" end @@ -157,11 +156,11 @@ RSpec.describe "bundler/inline#gemfile" do it "installs quietly if necessary when the install option is not set" do script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end - puts RACK + puts MYRACK RUBY expect(out).to eq("1.0.0") @@ -170,21 +169,21 @@ RSpec.describe "bundler/inline#gemfile" do it "installs subdependencies quietly if necessary when the install option is not set" do build_repo4 do - build_gem "rack" do |s| - s.add_dependency "rackdep" + build_gem "myrack" do |s| + s.add_dependency "myrackdep" end - build_gem "rackdep", "1.0.0" + build_gem "myrackdep", "1.0.0" end - script <<-RUBY + script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } gemfile do - source "#{file_uri_for(gem_repo4)}" - gem "rack" + source "https://gem.repo4" + gem "myrack" end - require "rackdep" - puts RACKDEP + require "myrackdep" + puts MYRACKDEP RUBY expect(out).to eq("1.0.0") @@ -193,23 +192,23 @@ RSpec.describe "bundler/inline#gemfile" do it "installs subdependencies quietly if necessary when the install option is not set, and multiple sources used" do build_repo4 do - build_gem "rack" do |s| - s.add_dependency "rackdep" + build_gem "myrack" do |s| + s.add_dependency "myrackdep" end - build_gem "rackdep", "1.0.0" + build_gem "myrackdep", "1.0.0" end - script <<-RUBY + script <<-RUBY, artifice: "compact_index_extra_api" gemfile do - source "#{file_uri_for(gem_repo1)}" - source "#{file_uri_for(gem_repo4)}" do - gem "rack" + source "https://test.repo" + source "https://test.repo/extra" do + gem "myrack" end end - require "rackdep" - puts RACKDEP + require "myrackdep" + puts MYRACKDEP RUBY expect(out).to eq("1.0.0") @@ -221,7 +220,7 @@ RSpec.describe "bundler/inline#gemfile" do baz_ref = build_git("baz", "2.0.0").ref_for("HEAD") script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => #{lib_path("foo-1.0.0").to_s.dump} gem "baz", :git => #{lib_path("baz-2.0.0").to_s.dump}, :ref => #{baz_ref.dump} end @@ -238,14 +237,14 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile do path "#{lib_path}" do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "two" end end gemfile do path "#{lib_path}" do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "four" end end @@ -256,7 +255,7 @@ RSpec.describe "bundler/inline#gemfile" do end it "doesn't reinstall already installed gems" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" script <<-RUBY require 'bundler' @@ -264,65 +263,65 @@ RSpec.describe "bundler/inline#gemfile" do ui.level = "confirm" gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" - gem "rack" + gem "myrack" end RUBY expect(out).to include("Installing activesupport") - expect(out).not_to include("Installing rack") + expect(out).not_to include("Installing myrack") expect(err).to be_empty end it "installs gems in later gemfile calls" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" script <<-RUBY require 'bundler' ui = Bundler::UI::Shell.new ui.level = "confirm" gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" end RUBY expect(out).to include("Installing activesupport") - expect(out).not_to include("Installing rack") + expect(out).not_to include("Installing myrack") expect(err).to be_empty end it "doesn't reinstall already installed gems in later gemfile calls" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" script <<-RUBY require 'bundler' ui = Bundler::UI::Shell.new ui.level = "confirm" gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" end gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end RUBY expect(out).to include("Installing activesupport") - expect(out).not_to include("Installing rack") + expect(out).not_to include("Installing myrack") expect(err).to be_empty end it "installs gems with native extensions in later gemfile calls" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" build_git "foo" do |s| s.add_dependency "rake" @@ -343,12 +342,12 @@ RSpec.describe "bundler/inline#gemfile" do ui = Bundler::UI::Shell.new ui.level = "confirm" gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end gemfile(true, ui: ui) do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" end @@ -386,11 +385,11 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end - puts RACK + puts MYRACK RUBY expect(err).to be_empty @@ -420,7 +419,7 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile(true) do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rake", "#{rake_version}" end RUBY @@ -431,26 +430,26 @@ RSpec.describe "bundler/inline#gemfile" do end it "installs inline gems when frozen is set" do - script <<-RUBY, env: { "BUNDLE_FROZEN" => "true" } + script <<-RUBY, env: { "BUNDLE_FROZEN" => "true", "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end - puts RACK + puts MYRACK RUBY expect(last_command.stderr).to be_empty end it "installs inline gems when deployment is set" do - script <<-RUBY, env: { "BUNDLE_DEPLOYMENT" => "true" } + script <<-RUBY, env: { "BUNDLE_DEPLOYMENT" => "true", "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end - puts RACK + puts MYRACK RUBY expect(last_command.stderr).to be_empty @@ -461,11 +460,11 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end - puts RACK + puts MYRACK RUBY expect(err).to be_empty @@ -476,11 +475,11 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" # has the rackup executable + source "https://gem.repo1" + gem "myrack" # has the myrackup executable end - puts RACK + puts MYRACK RUBY expect(last_command).to be_success expect(out).to eq "1.0.0" @@ -488,14 +487,14 @@ RSpec.describe "bundler/inline#gemfile" do context "when BUNDLE_PATH is set" do it "installs inline gems to the system path regardless" do - script <<-RUBY, env: { "BUNDLE_PATH" => "./vendor/inline" } + script <<-RUBY, env: { "BUNDLE_PATH" => "./vendor/inline", "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } gemfile(true) do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end RUBY expect(last_command).to be_success - expect(system_gem_path("gems/rack-1.0.0")).to exist + expect(system_gem_path("gems/myrack-1.0.0")).to exist end end @@ -504,8 +503,8 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile(true) do - source "#{file_uri_for(gem_repo1)}" - gem "rack", platform: :jruby + source "https://gem.repo1" + gem "myrack", platform: :jruby end RUBY @@ -517,21 +516,21 @@ RSpec.describe "bundler/inline#gemfile" do script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end RUBY expect(last_command).to be_success - expect(system_gem_path("gems/rack-1.0.0")).to exist + expect(system_gem_path("gems/myrack-1.0.0")).to exist end it "preserves previous BUNDLE_GEMFILE value" do ENV["BUNDLE_GEMFILE"] = "" script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end puts "BUNDLE_GEMFILE is empty" if ENV["BUNDLE_GEMFILE"].empty? @@ -547,8 +546,8 @@ RSpec.describe "bundler/inline#gemfile" do ENV["BUNDLE_GEMFILE"] = nil script <<-RUBY gemfile do - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" end puts "BUNDLE_GEMFILE is empty" if ENV["BUNDLE_GEMFILE"].empty? @@ -576,9 +575,9 @@ RSpec.describe "bundler/inline#gemfile" do s.write "lib/foo.rb", foo_code end - script <<-RUBY, dir: tmp("path_without_gemfile") + script <<-RUBY, dir: tmp("path_without_gemfile"), env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } gemfile do - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" path "#{lib_path}" do gem "foo", require: false end @@ -591,7 +590,7 @@ RSpec.describe "bundler/inline#gemfile" do expect(err).to be_empty end - it "when requiring fileutils after does not show redefinition warnings", :realworld do + it "when requiring fileutils after does not show redefinition warnings" do Dir.mkdir tmp("path_without_gemfile") default_fileutils_version = ruby "gem 'fileutils', '< 999999'; require 'fileutils'; puts FileUtils::VERSION", raise_on_error: false @@ -601,11 +600,11 @@ RSpec.describe "bundler/inline#gemfile" do realworld_system_gems "pathname --version 0.2.0" - script <<-RUBY, dir: tmp("path_without_gemfile"), env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s } + script <<-RUBY, dir: tmp("path_without_gemfile"), env: { "BUNDLER_GEM_DEFAULT_DIR" => system_gem_path.to_s, "BUNDLER_SPEC_GEM_REPO" => gem_repo2.to_s } require "bundler/inline" gemfile(true) do - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" end require "fileutils" @@ -626,11 +625,11 @@ RSpec.describe "bundler/inline#gemfile" do build_gem "timeout", "999" end - script <<-RUBY + script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } require "bundler/inline" gemfile(true) do - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "timeout" end @@ -647,7 +646,7 @@ RSpec.describe "bundler/inline#gemfile" do puts("before: \#{ENV.each_key.select { |key| key.match?(/test_variable/i) }}") gemfile do - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" end puts("after: \#{ENV.each_key.select { |key| key.match?(/test_variable/i) }}") @@ -656,4 +655,62 @@ RSpec.describe "bundler/inline#gemfile" do expect(out).to include("before: [\"Test_Variable\"]") expect(out).to include("after: [\"Test_Variable\"]") end + + it "does not create a lockfile" do + script <<-RUBY + require 'bundler/inline' + + gemfile do + source "https://gem.repo1" + end + + puts Dir.glob("Gemfile.lock") + RUBY + + expect(out).to be_empty + end + + it "does not load specified version of psych and stringio", :ruby_repo do + build_repo4 do + build_gem "psych", "999" + build_gem "stringio", "999" + end + + script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + require "bundler/inline" + + gemfile(true) do + source "https://gem.repo4" + + gem "psych" + gem "stringio" + end + RUBY + + expect(out).to include("Installing psych 999") + expect(out).to include("Installing stringio 999") + expect(out).to include("The psych gem was resolved to 999") + expect(out).to include("The stringio gem was resolved to 999") + end + + it "leaves a lockfile in the same directory as the inline script alone" do + install_gemfile <<~G + source "https://gem.repo1" + gem "foo" + G + + original_lockfile = lockfile + + script <<-RUBY, env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo1.to_s } + require "bundler/inline" + + gemfile(true) do + source "https://gem.repo1" + + gem "myrack" + end + RUBY + + expect(lockfile).to eq(original_lockfile) + end end diff --git a/spec/bundler/runtime/load_spec.rb b/spec/bundler/runtime/load_spec.rb index f28ffd9460..15f3d0eb5b 100644 --- a/spec/bundler/runtime/load_spec.rb +++ b/spec/bundler/runtime/load_spec.rb @@ -4,18 +4,18 @@ RSpec.describe "Bundler.load" do describe "with a gemfile" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app) end it "provides a list of the env dependencies" do - expect(Bundler.load.dependencies).to have_dep("rack", ">= 0") + expect(Bundler.load.dependencies).to have_dep("myrack", ">= 0") end it "provides a list of the resolved gems" do - expect(Bundler.load.gems).to have_gem("rack-1.0.0", "bundler-#{Bundler::VERSION}") + expect(Bundler.load.gems).to have_gem("myrack-1.0.0", "bundler-#{Bundler::VERSION}") end it "ignores blank BUNDLE_GEMFILEs" do @@ -28,20 +28,20 @@ RSpec.describe "Bundler.load" do describe "with a gems.rb file" do before(:each) do - create_file "gems.rb", <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + gemfile "gems.rb", <<-G + source "https://gem.repo1" + gem "myrack" G bundle :install allow(Bundler::SharedHelpers).to receive(:pwd).and_return(bundled_app) end it "provides a list of the env dependencies" do - expect(Bundler.load.dependencies).to have_dep("rack", ">= 0") + expect(Bundler.load.dependencies).to have_dep("myrack", ">= 0") end it "provides a list of the resolved gems" do - expect(Bundler.load.gems).to have_gem("rack-1.0.0", "bundler-#{Bundler::VERSION}") + expect(Bundler.load.gems).to have_gem("myrack-1.0.0", "bundler-#{Bundler::VERSION}") end end @@ -76,8 +76,8 @@ RSpec.describe "Bundler.load" do describe "when called twice" do it "doesn't try to load the runtime twice" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "activesupport", :group => :test G @@ -85,7 +85,7 @@ RSpec.describe "Bundler.load" do require "bundler" Bundler.setup :default Bundler.require :default - puts RACK + puts MYRACK begin require "activesupport" rescue LoadError @@ -100,7 +100,7 @@ RSpec.describe "Bundler.load" do describe "not hurting brittle rubygems" do it "does not inject #source into the generated YAML of the gem specs" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activerecord" G allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) diff --git a/spec/bundler/runtime/platform_spec.rb b/spec/bundler/runtime/platform_spec.rb index 1925e9bf2e..007733d3de 100644 --- a/spec/bundler/runtime/platform_spec.rb +++ b/spec/bundler/runtime/platform_spec.rb @@ -3,21 +3,21 @@ RSpec.describe "Bundler.setup with multi platform stuff" do it "raises a friendly error when gems are missing locally" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0) + myrack (1.0) PLATFORMS #{local_tag} DEPENDENCIES - rack + myrack G ruby <<-R @@ -35,7 +35,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do it "will resolve correctly on the current platform when the lockfile was targeted for a different one" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: nokogiri (1.4.2-java) weakling (= 0.0.3) @@ -48,13 +48,14 @@ RSpec.describe "Bundler.setup with multi platform stuff" do nokogiri G - simulate_platform "x86-darwin-10" - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "nokogiri" - G + simulate_platform "x86-darwin-10" do + install_gemfile <<-G + source "https://gem.repo1" + gem "nokogiri" + G - expect(the_bundle).to include_gems "nokogiri 1.4.2" + expect(the_bundle).to include_gems "nokogiri 1.4.2" + end end it "will keep both platforms when both ruby and a specific ruby platform are locked and the bundle is unlocked" do @@ -82,7 +83,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do good_lockfile = <<~L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: mini_portile2 (2.5.0) nokogiri (1.11.1) @@ -103,7 +104,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do L gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "nokogiri", "~> 1.11" G @@ -125,13 +126,13 @@ RSpec.describe "Bundler.setup with multi platform stuff" do end gemfile <<-G - source "https://gems.repo4" + source "https://gem.repo4" gem "nokogiri" G lockfile <<~L GEM - remote: https://gems.repo4/ + remote: https://gem.repo4/ specs: nokogiri (1.11.1) @@ -145,7 +146,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do #{Bundler::VERSION} L - bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s } + bundle "install" expect(out).to include("Fetching nokogiri 1.11.1") expect(the_bundle).to include_gems "nokogiri 1.11.1" @@ -154,13 +155,13 @@ RSpec.describe "Bundler.setup with multi platform stuff" do it "will use the java platform if both generic java and generic ruby platforms are locked", :jruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri" G lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: nokogiri (1.4.2) nokogiri (1.4.2-java) @@ -181,13 +182,13 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" expect(out).to include("Fetching nokogiri 1.4.2 (java)") - expect(the_bundle).to include_gems "nokogiri 1.4.2 JAVA" + expect(the_bundle).to include_gems "nokogiri 1.4.2 java" end it "will add the resolve for the current platform" do lockfile <<-G GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: nokogiri (1.4.2-java) weakling (= 0.0.3) @@ -200,20 +201,20 @@ RSpec.describe "Bundler.setup with multi platform stuff" do nokogiri G - simulate_platform "x86-darwin-100" - - install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "nokogiri" - gem "platform_specific" - G + simulate_platform "x86-darwin-100" do + install_gemfile <<-G + source "https://gem.repo1" + gem "nokogiri" + gem "platform_specific" + G - expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 x86-darwin-100" + expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 x86-darwin-100" + end end it "allows specifying only-ruby-platform on jruby", :jruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri" gem "platform_specific" G @@ -222,12 +223,12 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" - expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 ruby" end it "allows specifying only-ruby-platform" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri" gem "platform_specific" G @@ -236,12 +237,12 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" - expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 ruby" end it "allows specifying only-ruby-platform even if the lockfile is locked to a specific compatible platform" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri" gem "platform_specific" G @@ -250,27 +251,27 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" - expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "nokogiri 1.4.2", "platform_specific 1.0 ruby" end it "doesn't pull platform specific gems on truffleruby", :truffleruby_only do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G - expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" end - it "doesn't pull platform specific gems on truffleruby (except when whitelisted) even if lockfile was generated with an older version that declared RUBY as platform", :truffleruby_only do + it "doesn't pull platform specific gems on truffleruby (except when whitelisted) even if lockfile was generated with an older version that declared ruby as platform", :truffleruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: platform_specific (1.0) @@ -286,7 +287,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" - expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" simulate_platform "x86_64-linux" do build_repo4 do @@ -298,13 +299,13 @@ RSpec.describe "Bundler.setup with multi platform stuff" do end gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "libv8" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo4)}/ + remote: https://gem.repo4/ specs: libv8 (1.0) @@ -326,13 +327,13 @@ RSpec.describe "Bundler.setup with multi platform stuff" do it "doesn't pull platform specific gems on truffleruby, even if lockfile only includes those", :truffleruby_only do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific" G lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: platform_specific (1.0-x86-darwin-100) @@ -348,7 +349,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" - expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" end it "pulls platform specific gems correctly on musl" do @@ -359,8 +360,8 @@ RSpec.describe "Bundler.setup with multi platform stuff" do end simulate_platform "aarch64-linux-musl" do - install_gemfile <<-G, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }, verbose: true - source "https://gems.repo4" + install_gemfile <<-G, verbose: true + source "https://gem.repo4" gem "nokogiri" G end @@ -371,7 +372,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do it "allows specifying only-ruby-platform on windows with dependency platforms" do simulate_windows do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "nokogiri", :platforms => [:windows, :mswin, :mswin64, :mingw, :x64_mingw, :jruby] gem "platform_specific" G @@ -380,18 +381,18 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "install" - expect(the_bundle).to include_gems "platform_specific 1.0 RUBY" + expect(the_bundle).to include_gems "platform_specific 1.0 ruby" expect(the_bundle).to not_include_gems "nokogiri" end end it "allows specifying only-ruby-platform on windows with gemspec dependency" do build_lib("foo", "1.0", path: bundled_app) do |s| - s.add_dependency "rack" + s.add_dependency "myrack" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gemspec G bundle :lock @@ -400,7 +401,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do bundle "config set force_ruby_platform true" bundle "install" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end @@ -413,7 +414,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do simulate_windows x64_mingw32 do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: platform_specific (1.0-x86-mingw32) requires_platform_specific (1.0) @@ -428,7 +429,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do L install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "requires_platform_specific" G @@ -444,7 +445,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do simulate_windows platform do lockfile <<-L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: platform_specific (1.0-#{platform}) requires_platform_specific (1.0) @@ -458,7 +459,7 @@ RSpec.describe "Bundler.setup with multi platform stuff" do L install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "platform_specific", :platforms => [:windows] G diff --git a/spec/bundler/runtime/require_spec.rb b/spec/bundler/runtime/require_spec.rb index 76271a5593..ff45a3c5e2 100644 --- a/spec/bundler/runtime/require_spec.rb +++ b/spec/bundler/runtime/require_spec.rb @@ -46,7 +46,7 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "one", :group => :bar, :require => %w[baz qux] gem "two" @@ -113,7 +113,7 @@ RSpec.describe "Bundler.require" do it "raises an exception if a require is specified but the file does not exist" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "two", :require => 'fail' end @@ -132,7 +132,7 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "faulty" end @@ -149,7 +149,7 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "loadfuuu" end @@ -176,7 +176,7 @@ RSpec.describe "Bundler.require" do it "requires gem names that are namespaced" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path '#{lib_path}' do gem 'jquery-rails' end @@ -191,7 +191,7 @@ RSpec.describe "Bundler.require" do s.write "lib/brcrypt.rb", "BCrypt = '1.0.0'" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "bcrypt-ruby" @@ -209,7 +209,7 @@ RSpec.describe "Bundler.require" do it "does not mangle explicitly given requires" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem 'jquery-rails', :require => 'jquery-rails' end @@ -227,7 +227,7 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "load-fuuu" end @@ -251,7 +251,7 @@ RSpec.describe "Bundler.require" do end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "load-fuuu" end @@ -310,7 +310,7 @@ RSpec.describe "Bundler.require" do it "works when the gems are in the Gemfile in the correct order" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "two" gem "one" @@ -329,7 +329,7 @@ RSpec.describe "Bundler.require" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "multi_gem", :require => "one", :group => :one gem "multi_gem", :require => "two", :group => :two G @@ -353,7 +353,7 @@ RSpec.describe "Bundler.require" do it "fails when the gems are in the Gemfile in the wrong order" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" path "#{lib_path}" do gem "one" gem "two" @@ -371,7 +371,7 @@ RSpec.describe "Bundler.require" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "busted_require" G @@ -385,12 +385,12 @@ RSpec.describe "Bundler.require" do it "does not load rubygems gemspecs that are used" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G run <<-R - path = File.join(Gem.dir, "specifications", "rack-1.0.0.gemspec") + path = File.join(Gem.dir, "specifications", "myrack-1.0.0.gemspec") contents = File.read(path) contents = contents.lines.to_a.insert(-2, "\n raise 'broken gemspec'\n").join File.open(path, "w") do |f| @@ -410,7 +410,7 @@ RSpec.describe "Bundler.require" do build_git "foo" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "foo", :git => "#{lib_path("foo-1.0")}" G @@ -430,18 +430,42 @@ RSpec.describe "Bundler.require" do expect(out).to eq("WIN") end + + it "does not extract gemspecs from application cache packages" do + gemfile <<-G + source "https://gem.repo1" + gem "myrack" + G + + bundle :cache + + path = cached_gem("myrack-1.0.0") + + run <<-R + File.open("#{path}", "w") do |f| + f.write "broken package" + end + R + + run <<-R + Bundler.require + puts "WIN" + R + + expect(out).to eq("WIN") + end end RSpec.describe "Bundler.require with platform specific dependencies" do it "does not require the gems that are pinned to other platforms" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platforms :#{not_local_tag} do gem "platform_specific", :require => "omgomg" end - gem "rack", "1.0.0" + gem "myrack", "1.0.0" G run "Bundler.require" @@ -450,14 +474,14 @@ RSpec.describe "Bundler.require with platform specific dependencies" do it "requires gems pinned to multiple platforms, including the current one" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" platforms :#{not_local_tag}, :#{local_tag} do - gem "rack", :require => "rack" + gem "myrack", :require => "myrack" end G - run "Bundler.require; puts RACK" + run "Bundler.require; puts MYRACK" expect(out).to eq("1.0.0") expect(err).to be_empty diff --git a/spec/bundler/runtime/self_management_spec.rb b/spec/bundler/runtime/self_management_spec.rb index d15ca3189e..c6910e95c0 100644 --- a/spec/bundler/runtime/self_management_spec.rb +++ b/spec/bundler/runtime/self_management_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do +RSpec.describe "Self management", rubygems: ">= 3.3.0.dev" do describe "auto switching" do let(:previous_minor) do "2.3.0" @@ -11,12 +11,18 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do end before do - build_repo2 + build_repo4 do + build_bundler previous_minor + + build_bundler current_version + + build_gem "myrack", "1.0.0" + end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo4" - gem "rack" + gem "myrack" G end @@ -24,7 +30,7 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do lockfile_bundled_with(previous_minor) bundle "config set --local path.system true" - bundle "install", artifice: "vcr" + bundle "install", preserve_ruby_flags: true expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.") # It uninstalls the older system bundler @@ -35,6 +41,21 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do bundle "-v", artifice: nil expect(out).to end_with(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor) + # ruby-core test setup has always "lib" in $LOAD_PATH so `require "bundler/setup"` always activate the local version rather than using RubyGems gem activation stuff + unless ruby_core? + # App now uses locked version, even when not using the CLI directly + file = bundled_app("bin/bundle_version.rb") + create_file file, <<-RUBY + #!#{Gem.ruby} + require 'bundler/setup' + puts Bundler::VERSION + RUBY + file.chmod(0o777) + cmd = Gem.win_platform? ? "#{Gem.ruby} bin/bundle_version.rb" : "bin/bundle_version.rb" + sys_exec cmd, artifice: nil + expect(out).to eq(previous_minor) + end + # Subsequent installs use the locked version without reinstalling bundle "install --verbose", artifice: nil expect(out).to include("Using bundler #{previous_minor}") @@ -45,7 +66,7 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do lockfile_bundled_with(previous_minor) bundle "config set --local path vendor/bundle" - bundle "install", artifice: "vcr" + bundle "install", preserve_ruby_flags: true expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.") expect(vendored_gems("gems/bundler-#{previous_minor}")).to exist @@ -57,6 +78,21 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do bundle "-v" expect(out).to end_with(previous_minor[0] == "2" ? "Bundler version #{previous_minor}" : previous_minor) + # ruby-core test setup has always "lib" in $LOAD_PATH so `require "bundler/setup"` always activate the local version rather than using RubyGems gem activation stuff + unless ruby_core? + # App now uses locked version, even when not using the CLI directly + file = bundled_app("bin/bundle_version.rb") + create_file file, <<-RUBY + #!#{Gem.ruby} + require 'bundler/setup' + puts Bundler::VERSION + RUBY + file.chmod(0o777) + cmd = Gem.win_platform? ? "#{Gem.ruby} bin/bundle_version.rb" : "bin/bundle_version.rb" + sys_exec cmd, artifice: nil + expect(out).to eq(previous_minor) + end + # Subsequent installs use the locked version without reinstalling bundle "install --verbose" expect(out).to include("Using bundler #{previous_minor}") @@ -67,7 +103,7 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do lockfile_bundled_with(previous_minor) bundle "config set --local deployment true" - bundle "install", artifice: "vcr" + bundle "install", preserve_ruby_flags: true expect(out).to include("Bundler #{Bundler::VERSION} is running, but your lockfile was generated with #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.") expect(vendored_gems("gems/bundler-#{previous_minor}")).to exist @@ -95,12 +131,23 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION) end + it "does not try to install when --local is passed" do + lockfile_bundled_with(previous_minor) + system_gems "myrack-1.0.0", path: default_bundle_path + + bundle "install --local" + expect(out).not_to match(/Installing Bundler/) + + bundle "-v" + expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION) + end + it "shows a discrete message if locked bundler does not exist" do missing_minor = "#{Bundler::VERSION[0]}.999.999" lockfile_bundled_with(missing_minor) - bundle "install", artifice: "vcr" + bundle "install" expect(err).to eq("Your lockfile is locked to a version of bundler (#{missing_minor}) that doesn't exist at https://rubygems.org/. Going on using #{Bundler::VERSION}") bundle "-v" @@ -111,7 +158,7 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do lockfile_bundled_with(current_version) bundle "config set --local version #{previous_minor}" - bundle "install", artifice: "vcr" + bundle "install", preserve_ruby_flags: true expect(out).to include("Bundler #{Bundler::VERSION} is running, but your configuration was #{previous_minor}. Installing Bundler #{previous_minor} and restarting using that version.") bundle "-v" @@ -122,7 +169,18 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do lockfile_bundled_with(previous_minor) bundle "config set version system" - bundle "install", artifice: "vcr" + bundle "install" + expect(out).not_to match(/restarting using that version/) + + bundle "-v" + expect(out).to eq(Bundler::VERSION[0] == "2" ? "Bundler version #{Bundler::VERSION}" : Bundler::VERSION) + end + + it "does not try to install when using bundle config version <dev-version>" do + lockfile_bundled_with(previous_minor) + + bundle "config set version #{previous_minor}.dev" + bundle "install" expect(out).not_to match(/restarting using that version/) bundle "-v" @@ -141,15 +199,15 @@ RSpec.describe "Self management", rubygems: ">= 3.3.0.dev", realworld: true do def lockfile_bundled_with(version) lockfile <<~L GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo4/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack BUNDLED WITH #{version} diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb index 2d78825de4..175e2551f1 100644 --- a/spec/bundler/runtime/setup_spec.rb +++ b/spec/bundler/runtime/setup_spec.rb @@ -6,16 +6,16 @@ RSpec.describe "Bundler.setup" do describe "with no arguments" do it "makes all groups available" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :group => :test + source "https://gem.repo1" + gem "myrack", :group => :test G ruby <<-RUBY require 'bundler' Bundler.setup - require 'rack' - puts RACK + require 'myrack' + puts MYRACK RUBY expect(err).to be_empty expect(out).to eq("1.0.0") @@ -25,9 +25,9 @@ RSpec.describe "Bundler.setup" do describe "when called with groups" do before(:each) do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack", :group => :test + gem "myrack", :group => :test G end @@ -37,7 +37,7 @@ RSpec.describe "Bundler.setup" do Bundler.setup(:default) begin - require 'rack' + require 'myrack' rescue LoadError puts "WIN" end @@ -51,8 +51,8 @@ RSpec.describe "Bundler.setup" do require 'bundler' Bundler.setup(:default, 'test') - require 'rack' - puts RACK + require 'myrack' + puts MYRACK RUBY expect(err).to be_empty expect(out).to eq("1.0.0") @@ -64,8 +64,8 @@ RSpec.describe "Bundler.setup" do Bundler.setup Bundler.setup(:default) - require 'rack' - puts RACK + require 'myrack' + puts MYRACK RUBY expect(err).to be_empty expect(out).to eq("1.0.0") @@ -93,12 +93,12 @@ RSpec.describe "Bundler.setup" do require 'bundler' Bundler.setup(:default, :test) Bundler.setup(:default) - require 'rack' + require 'myrack' puts "FAIL" RUBY - expect(err).to match("rack") + expect(err).to match("myrack") expect(err).to match("LoadError") expect(out).not_to match("FAIL") end @@ -113,8 +113,8 @@ RSpec.describe "Bundler.setup" do it "puts loaded gems after -I and RUBYLIB", :ruby_repo do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ENV["RUBYOPT"] = "#{ENV["RUBYOPT"]} -Idash_i_dir" @@ -127,18 +127,18 @@ RSpec.describe "Bundler.setup" do RUBY load_path = out.split("\n") - rack_load_order = load_path.index {|path| path.include?("rack") } + myrack_load_order = load_path.index {|path| path.include?("myrack") } expect(err).to be_empty expect(load_path).to include(a_string_ending_with("dash_i_dir"), "rubylib_dir") - expect(rack_load_order).to be > 0 + expect(myrack_load_order).to be > 0 end it "orders the load path correctly when there are dependencies" do bundle "config set path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "rails" G @@ -166,7 +166,7 @@ RSpec.describe "Bundler.setup" do bundle "config set path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "weakling" gem "duradura" gem "terranova" @@ -189,8 +189,8 @@ RSpec.describe "Bundler.setup" do it "raises if the Gemfile was not yet installed" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ruby <<-R @@ -209,8 +209,8 @@ RSpec.describe "Bundler.setup" do it "doesn't create a Gemfile.lock if the setup fails" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ruby <<-R, raise_on_error: false @@ -224,15 +224,15 @@ RSpec.describe "Bundler.setup" do it "doesn't change the Gemfile.lock if the setup fails" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G lockfile = File.read(bundled_app_lock) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "nosuchgem", "10.0" G @@ -247,8 +247,8 @@ RSpec.describe "Bundler.setup" do it "makes a Gemfile.lock if setup succeeds" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G File.read(bundled_app_lock) @@ -263,12 +263,12 @@ RSpec.describe "Bundler.setup" do context "user provides an absolute path" do it "uses BUNDLE_GEMFILE to locate the gemfile if present" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G gemfile bundled_app("4realz"), <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", "2.3.5" G @@ -282,7 +282,7 @@ RSpec.describe "Bundler.setup" do context "an absolute path is not provided" do it "uses BUNDLE_GEMFILE to locate the gemfile if present and doesn't fail in deployment mode" do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G bundle "install" @@ -308,23 +308,23 @@ RSpec.describe "Bundler.setup" do it "prioritizes gems in BUNDLE_PATH over gems in GEM_HOME" do ENV["BUNDLE_PATH"] = bundled_app(".bundle").to_s install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" G - build_gem "rack", "1.0", to_system: true do |s| - s.write "lib/rack.rb", "RACK = 'FAIL'" + build_gem "myrack", "1.0", to_system: true do |s| + s.write "lib/myrack.rb", "MYRACK = 'FAIL'" end - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end describe "integrate with rubygems" do describe "by replacing #gem" do before :each do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "0.9.1" + source "https://gem.repo1" + gem "myrack", "0.9.1" G end @@ -344,7 +344,7 @@ RSpec.describe "Bundler.setup" do it "replaces #gem but raises when the version is wrong" do run <<-R begin - gem "rack", "1.0.0" + gem "myrack", "1.0.0" puts "FAIL" rescue LoadError puts "WIN" @@ -359,7 +359,7 @@ RSpec.describe "Bundler.setup" do before :each do system_gems "activesupport-2.3.5" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" G end @@ -381,37 +381,37 @@ RSpec.describe "Bundler.setup" do describe "with paths" do it "activates the gems in the path source" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" - build_lib "rack", "1.0.0" do |s| - s.write "lib/rack.rb", "puts 'WIN'" + build_lib "myrack", "1.0.0" do |s| + s.write "lib/myrack.rb", "puts 'WIN'" end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - path "#{lib_path("rack-1.0.0")}" do - gem "rack" + source "https://gem.repo1" + path "#{lib_path("myrack-1.0.0")}" do + gem "myrack" end G - run "require 'rack'" + run "require 'myrack'" expect(out).to eq("WIN") end end describe "with git" do before do - build_git "rack", "1.0.0" + build_git "myrack", "1.0.0" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-1.0.0")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-1.0.0")}" G end it "provides a useful exception when the git repo is not checked out yet" do run "1", raise_on_error: false - expect(err).to match(/the git source #{lib_path("rack-1.0.0")} is not yet checked out. Please run `bundle install`/i) + expect(err).to match(/the git source #{lib_path("myrack-1.0.0")} is not yet checked out. Please run `bundle install`/i) end it "does not hit the git binary if the lockfile is available and up to date" do @@ -460,7 +460,7 @@ RSpec.describe "Bundler.setup" do bundle "config set --local path vendor/bundle" bundle :install FileUtils.rm_rf vendored_gems("cache") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end it "does not randomly change the path when specifying --path and the bundle directory becomes read only" do @@ -468,7 +468,7 @@ RSpec.describe "Bundler.setup" do bundle :install with_read_only("#{bundled_app}/**/*") do - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end @@ -477,91 +477,91 @@ RSpec.describe "Bundler.setup" do bundle "install" with_read_only("#{bundled_app(".bundle")}/**/*") do - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end end describe "when specifying local override" do it "explodes if given path does not exist on runtime" do - build_git "rack", "0.8" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle :install - FileUtils.rm_rf(lib_path("local-rack")) - run "require 'rack'", 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/) + FileUtils.rm_rf(lib_path("local-myrack")) + run "require 'myrack'", raise_on_error: false + expect(err).to match(/Cannot use local override for myrack-0.8 because #{Regexp.escape(lib_path("local-myrack").to_s)} does not exist/) end it "explodes if branch is not given on runtime" do - build_git "rack", "0.8" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle :install gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}" G - run "require 'rack'", raise_on_error: false + run "require 'myrack'", raise_on_error: false expect(err).to match(/because :branch is not specified in Gemfile/) end it "explodes on different branches on runtime" do - build_git "rack", "0.8" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) + bundle %(config set local.myrack #{lib_path("local-myrack")}) bundle :install gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :branch => "changed" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "changed" G - run "require 'rack'", raise_on_error: false + run "require 'myrack'", raise_on_error: false expect(err).to match(/is using branch main but Gemfile specifies changed/) end it "explodes on refs with different branches on runtime" do - build_git "rack", "0.8" + build_git "myrack", "0.8" - FileUtils.cp_r("#{lib_path("rack-0.8")}/.", lib_path("local-rack")) + FileUtils.cp_r("#{lib_path("myrack-0.8")}/.", lib_path("local-myrack")) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :ref => "main", :branch => "main" G gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{lib_path("rack-0.8")}", :ref => "main", :branch => "nonexistent" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :ref => "main", :branch => "nonexistent" G - bundle %(config set local.rack #{lib_path("local-rack")}) - run "require 'rack'", raise_on_error: false + bundle %(config set local.myrack #{lib_path("local-myrack")}) + run "require 'myrack'", raise_on_error: false expect(err).to match(/is using branch main but Gemfile specifies nonexistent/) end end @@ -570,7 +570,7 @@ RSpec.describe "Bundler.setup" do it "doesn't change the resolve if --without is used" do bundle "config set --local without rails" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" group :rails do @@ -586,7 +586,7 @@ RSpec.describe "Bundler.setup" do it "remembers --without and does not bail on bare Bundler.setup" do bundle "config set --local without rails" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" group :rails do @@ -606,7 +606,7 @@ RSpec.describe "Bundler.setup" do build_lib "foo", path: path install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", "2.3.2" gem 'foo', :path => 'vendor/foo', :group => :development G @@ -629,7 +629,7 @@ RSpec.describe "Bundler.setup" do end install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "depends_on_bundler" G @@ -641,7 +641,7 @@ RSpec.describe "Bundler.setup" do it "doesn't fail in frozen mode when bundler is a Gemfile dependency" do install_gemfile <<~G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "bundler" G @@ -651,14 +651,14 @@ RSpec.describe "Bundler.setup" do it "doesn't re-resolve when deleting dependencies" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "actionpack" G install_gemfile <<-G, verbose: true - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G expect(out).to include("Some dependencies were deleted, using a subset of the resolution from the lockfile") @@ -668,11 +668,11 @@ RSpec.describe "Bundler.setup" do it "remembers --without and does not include groups passed to Bundler.setup" do bundle "config set --local without rails" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" - group :rack do - gem "rack" + group :myrack do + gem "myrack" end group :rails do @@ -680,8 +680,8 @@ RSpec.describe "Bundler.setup" do end G - expect(the_bundle).not_to include_gems "activesupport 2.3.2", groups: :rack - expect(the_bundle).to include_gems "rack 1.0.0", groups: :rack + expect(the_bundle).not_to include_gems "activesupport 2.3.2", groups: :myrack + expect(the_bundle).to include_gems "myrack 1.0.0", groups: :myrack end end @@ -691,8 +691,8 @@ RSpec.describe "Bundler.setup" do build_git "no-gemspec", gemspec: false install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" gem "foo", :git => "#{lib_path("foo-1.0")}" gem "no-gemspec", "1.0", :git => "#{lib_path("no-gemspec-1.0")}" G @@ -708,8 +708,8 @@ RSpec.describe "Bundler.setup" do it "does not load all gemspecs" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G run <<-R @@ -757,8 +757,8 @@ end it "ignores empty gem paths" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ENV["GEM_HOME"] = "" @@ -767,10 +767,10 @@ end expect(err).to be_empty end - it "can require rubygems without warnings, when using a local cache", rubygems: ">= 3.5.10" do + it "can require rubygems without warnings, when using a local cache", :truffleruby do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G bundle "package" @@ -790,7 +790,7 @@ end end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "with_man" G @@ -814,7 +814,7 @@ end end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "with_man" G @@ -827,7 +827,7 @@ end expect(out).to eq("#{default_bundle_path("gems/with_man-1.0/man")}#{File::PATH_SEPARATOR}\ntrue") install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "with_man_overriding_system_man" G @@ -854,7 +854,7 @@ end end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem "requirepaths", :require => nil G @@ -870,7 +870,7 @@ end system_gems full_gem_name install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" G ruby <<-R @@ -917,7 +917,7 @@ end end it "should not remove itself from the LOAD_PATH and require a different copy of 'bundler/setup'" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" ruby <<-R, env: { "GEM_PATH" => symlinked_gem_home } TracePoint.trace(:class) do |tp| @@ -934,17 +934,17 @@ end end it "does not reveal system gems even when Gem.refresh is called" do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport" G run <<-R - puts Bundler.rubygems.all_specs.map(&:name) + puts Bundler.rubygems.installed_specs.map(&:name) Gem.refresh - puts Bundler.rubygems.all_specs.map(&:name) + puts Bundler.rubygems.installed_specs.map(&:name) R expect(out).to eq("activesupport\nbundler\nactivesupport\nbundler") @@ -966,7 +966,7 @@ end FileUtils.rm(File.join(path, "foo.gemspec")) install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', '1.2.3', :path => 'vendor/foo' G @@ -987,7 +987,7 @@ end FileUtils.rm(File.join(absolute_path, "foo.gemspec")) gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', '1.2.3', :path => '#{relative_path}' G @@ -1006,7 +1006,7 @@ end build_git "no_gemspec", gemspec: false install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "no_gemspec", "1.0", :git => "#{lib_path("no_gemspec-1.0")}" G end @@ -1023,10 +1023,10 @@ end describe "with bundled and system gems" do before :each do - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", "2.3.5" G @@ -1035,7 +1035,7 @@ end it "does not pull in system gems" do run <<-R begin; - require 'rack' + require 'myrack' rescue LoadError puts 'WIN' end @@ -1057,13 +1057,13 @@ end it "raises an exception if gem is used to invoke a system gem not in the bundle" do run <<-R begin - gem 'rack' + gem 'myrack' rescue LoadError => e puts e.message end R - expect(out).to eq("rack is not part of the bundle. Add it to your Gemfile.") + expect(out).to eq("myrack is not part of the bundle. Add it to your Gemfile.") end it "sets GEM_HOME appropriately" do @@ -1075,11 +1075,11 @@ end describe "with system gems in the bundle" do before :each do bundle "config set path.system true" - system_gems "rack-1.0.0" + system_gems "myrack-1.0.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", "1.0.0" + source "https://gem.repo1" + gem "myrack", "1.0.0" gem "activesupport", "2.3.5" G end @@ -1109,7 +1109,7 @@ end end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :git => "#{lib_path("bar-1.0")}" G end @@ -1156,7 +1156,7 @@ end describe "when Bundler is bundled" do it "doesn't blow up" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bundler", :path => "#{root}" G @@ -1169,15 +1169,15 @@ end def lock_with(bundler_version = nil) lock = <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack L if bundler_version @@ -1191,8 +1191,8 @@ end bundle "config set --local path.system true" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end @@ -1229,20 +1229,20 @@ end def lock_with(ruby_version = nil) checksums = checksums_section do |c| - c.checksum gem_repo1, "rack", "1.0.0" + c.checksum gem_repo1, "myrack", "1.0.0" end lock = <<~L GEM - remote: #{file_uri_for(gem_repo1)}/ + remote: https://gem.repo1/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES - rack + myrack #{checksums} L @@ -1262,8 +1262,8 @@ end before do install_gemfile <<-G ruby ">= 0" - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G lockfile lock_with(ruby_version) end @@ -1305,19 +1305,19 @@ end s.files = Dir["lib/**/*.rb"] s.author = 'no one' - s.add_runtime_dependency 'digest' + s.add_dependency 'digest' end G end gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "bar", :git => "#{lib_path("bar-1.0")}" G bundle :install - ruby <<-RUBY + ruby <<-RUBY, artifice: nil require 'bundler/setup' puts defined?(::Digest) ? "Digest defined" : "Digest undefined" require 'digest' @@ -1326,7 +1326,7 @@ end end it "does not load Psych" do - gemfile "source \"#{file_uri_for(gem_repo1)}\"" + gemfile "source 'https://gem.repo1'" ruby <<-RUBY require 'bundler/setup' puts defined?(Psych::VERSION) ? Psych::VERSION : "undefined" @@ -1339,8 +1339,8 @@ end end it "does not load openssl" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" - ruby <<-RUBY + install_gemfile "source 'https://gem.repo1'" + ruby <<-RUBY, artifice: nil require "bundler/setup" puts defined?(OpenSSL) || "undefined" require "openssl" @@ -1363,11 +1363,11 @@ end G install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "test", path: "#{bundled_app("test")}" G - ruby <<-RUBY + ruby <<-RUBY, artifice: nil require "bundler/setup" puts defined?(URI) || "undefined" require "uri" @@ -1376,10 +1376,29 @@ end expect(out).to eq("undefined\nconstant") end + it "activates default gems when they are part of the bundle, but not installed explicitly", :ruby_repo do + default_delegate_version = ruby "gem 'delegate'; require 'delegate'; puts Delegator::VERSION" + + build_repo2 do + build_gem "delegate", default_delegate_version + end + + gemfile "source \"https://gem.repo2\"; gem 'delegate'" + + ruby <<-RUBY + require "bundler/setup" + require "delegate" + puts defined?(::Delegator) ? "Delegator defined" : "Delegator undefined" + RUBY + + expect(out).to eq("Delegator defined") + expect(err).to be_empty + end + describe "default gem activation" do let(:exemptions) do exempts = %w[did_you_mean bundler uri pathname] - exempts << "etc" if Gem.ruby_version < Gem::Version.new("3.2") && Gem.win_platform? + exempts << "etc" if (Gem.ruby_version < Gem::Version.new("3.2") || Gem.ruby_version >= Gem::Version.new("3.3.2")) && Gem.win_platform? exempts << "set" unless Gem.rubygems_version >= Gem::Version.new("3.2.6") exempts << "tsort" unless Gem.rubygems_version >= Gem::Version.new("3.2.31") exempts << "error_highlight" # added in Ruby 3.1 as a default gem @@ -1422,13 +1441,13 @@ end RUBY it "activates no gems with -rbundler/setup" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" - ruby code, env: { "RUBYOPT" => activation_warning_hack_rubyopt + " -rbundler/setup" } + install_gemfile "source 'https://gem.repo1'" + ruby code, env: { "RUBYOPT" => activation_warning_hack_rubyopt + " -rbundler/setup" }, artifice: nil expect(out).to eq("{}") end it "activates no gems with bundle exec" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" create_file("script.rb", code) bundle "exec ruby ./script.rb", env: { "RUBYOPT" => activation_warning_hack_rubyopt } expect(out).to eq("{}") @@ -1437,7 +1456,7 @@ end it "activates no gems with bundle exec that is loaded" do skip "not executable" if Gem.win_platform? - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" create_file("script.rb", "#!/usr/bin/env ruby\n\n#{code}") FileUtils.chmod(0o777, bundled_app("script.rb")) bundle "exec ./script.rb", artifice: nil, env: { "RUBYOPT" => activation_warning_hack_rubyopt } @@ -1452,7 +1471,7 @@ end system_gems "net-http-pipeline-1.0.1", gem_repo: gem_repo4 gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "net-http-pipeline", "1.0.1" G @@ -1474,11 +1493,11 @@ end end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "#{g}", "999999" G - expect(the_bundle).to include_gem("#{g} 999999", env: { "RUBYOPT" => activation_warning_hack_rubyopt }) + expect(the_bundle).to include_gem("#{g} 999999", env: { "RUBYOPT" => activation_warning_hack_rubyopt }, artifice: nil) end it "activates older versions of #{g}", :ruby_repo do @@ -1489,11 +1508,11 @@ end end install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" gem "#{g}", "0.0.0.a" G - expect(the_bundle).to include_gem("#{g} 0.0.0.a", env: { "RUBYOPT" => activation_warning_hack_rubyopt }) + expect(the_bundle).to include_gem("#{g} 0.0.0.a", env: { "RUBYOPT" => activation_warning_hack_rubyopt }, artifice: nil) end end end @@ -1502,28 +1521,28 @@ end describe "after setup" do it "allows calling #gem on random objects", bundler: "< 3" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ruby <<-RUBY require "bundler/setup" - Object.new.gem "rack" - puts Gem.loaded_specs["rack"].full_name + Object.new.gem "myrack" + puts Gem.loaded_specs["myrack"].full_name RUBY - expect(out).to eq("rack-1.0.0") + expect(out).to eq("myrack-1.0.0") end it "keeps Kernel#gem private", bundler: "3" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ruby <<-RUBY, raise_on_error: false require "bundler/setup" - Object.new.gem "rack" + Object.new.gem "myrack" puts "FAIL" RUBY @@ -1533,13 +1552,13 @@ end it "keeps Kernel#require private" do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G ruby <<-RUBY, raise_on_error: false require "bundler/setup" - Object.new.require "rack" + Object.new.require "myrack" puts "FAIL" RUBY @@ -1549,9 +1568,9 @@ end it "memoizes initial set of specs when requiring bundler/setup, so that even if further code mutates dependencies, Bundler.definition.specs is not affected" do install_gemfile <<~G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "yard" - gem "rack", :group => :test + gem "myrack", :group => :test G ruby <<-RUBY, raise_on_error: false @@ -1560,7 +1579,7 @@ end puts Bundler.definition.specs.map(&:name).join(", ") RUBY - expect(out).to include("rack, yard") + expect(out).to include("myrack, yard") end it "does not cause double loads when higher versions of default gems are activated before bundler" do @@ -1576,7 +1595,7 @@ end system_gems "json-999.999.999", gem_repo: gem_repo2 - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" ruby <<-RUBY require "json" require "bundler/setup" @@ -1588,7 +1607,7 @@ end end it "does not undo the Kernel.require decorations", rubygems: ">= 3.4.6" do - install_gemfile "source \"#{file_uri_for(gem_repo1)}\"" + install_gemfile "source 'https://gem.repo1'" script = bundled_app("bin/script") create_file(script, <<~RUBY) module Kernel @@ -1613,17 +1632,21 @@ end end it "performs an automatic bundle install" do + build_repo4 do + build_gem "myrack", "1.0.0" + end + gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :group => :test + source "https://gem.repo1" + gem "myrack", :group => :test G bundle "config set auto_install 1" - ruby <<-RUBY + ruby <<-RUBY, artifice: "compact_index" require 'bundler/setup' RUBY expect(err).to be_empty - expect(out).to include("Installing rack 1.0.0") + expect(out).to include("Installing myrack 1.0.0") end end diff --git a/spec/bundler/runtime/with_unbundled_env_spec.rb b/spec/bundler/runtime/with_unbundled_env_spec.rb index 135c71b0af..8c3582f7ac 100644 --- a/spec/bundler/runtime/with_unbundled_env_spec.rb +++ b/spec/bundler/runtime/with_unbundled_env_spec.rb @@ -2,13 +2,13 @@ RSpec.describe "Bundler.with_env helpers" do def bundle_exec_ruby(args, options = {}) - build_bundler_context options + build_bundler_context options.dup bundle "exec '#{Gem.ruby}' #{args}", options end def build_bundler_context(options = {}) - bundle "config set path vendor/bundle" - gemfile "source \"#{file_uri_for(gem_repo1)}\"" + bundle "config set path vendor/bundle", options.dup + gemfile "source 'https://gem.repo1'" bundle "install", options end @@ -65,11 +65,11 @@ RSpec.describe "Bundler.with_env helpers" do # Simulate bundler has not yet been loaded ENV.replace(ENV.to_hash.delete_if {|k, _v| k.start_with?(Bundler::EnvironmentPreserver::BUNDLER_PREFIX) }) - original = ruby('puts ENV.to_a.map {|e| e.join("=") }.sort.join("\n")') + original = ruby('puts ENV.to_a.map {|e| e.join("=") }.sort.join("\n")', artifice: "fail") create_file("source.rb", <<-RUBY) puts Bundler.original_env.to_a.map {|e| e.join("=") }.sort.join("\n") RUBY - bundle_exec_ruby bundled_app("source.rb") + bundle_exec_ruby bundled_app("source.rb"), artifice: "fail" expect(out).to eq original end end diff --git a/spec/bundler/spec_helper.rb b/spec/bundler/spec_helper.rb index 66bdcfa028..c6bd786347 100644 --- a/spec/bundler/spec_helper.rb +++ b/spec/bundler/spec_helper.rb @@ -87,11 +87,10 @@ RSpec.configure do |config| # Don't wrap output in tests ENV["THOR_COLUMNS"] = "10000" - extend(Spec::Helpers) - system_gems :bundler, path: pristine_system_gem_path - end + Spec::Helpers.install_dev_bundler unless ENV["CI"] + + extend(Spec::Builders) - config.before :all do check_test_gems! build_repo1 diff --git a/spec/bundler/support/artifice/fail.rb b/spec/bundler/support/artifice/fail.rb index 8822e5b8e2..5ddbc4e590 100644 --- a/spec/bundler/support/artifice/fail.rb +++ b/spec/bundler/support/artifice/fail.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "bundler/vendored_net_http" +require_relative "../vendored_net_http" class Fail < Gem::Net::HTTP # Gem::Net::HTTP uses a @newimpl instance variable to decide whether diff --git a/spec/bundler/support/artifice/helpers/compact_index.rb b/spec/bundler/support/artifice/helpers/compact_index.rb index a803a2d30a..f045b71bcf 100644 --- a/spec/bundler/support/artifice/helpers/compact_index.rb +++ b/spec/bundler/support/artifice/helpers/compact_index.rb @@ -40,7 +40,7 @@ class CompactIndexAPI < Endpoint end def requested_range_for(response_body) - ranges = Rack::Utils.byte_ranges(env, response_body.bytesize) + ranges = Rack::Utils.get_byte_ranges(env["HTTP_RANGE"], response_body.bytesize) if ranges status 206 @@ -68,7 +68,10 @@ class CompactIndexAPI < Endpoint @gems[gem_repo] ||= begin specs = Bundler::Deprecate.skip_during do %w[specs.4.8 prerelease_specs.4.8].map do |filename| - Marshal.load(File.open(gem_repo.join(filename)).read).map do |name, version, platform| + spec_index = gem_repo.join(filename) + next [] unless File.exist?(spec_index) + + Marshal.load(File.binread(spec_index)).map do |name, version, platform| load_spec(name, version, platform, gem_repo) end end.flatten diff --git a/spec/bundler/support/artifice/helpers/endpoint.rb b/spec/bundler/support/artifice/helpers/endpoint.rb index 83ba1be0fc..329d2d807a 100644 --- a/spec/bundler/support/artifice/helpers/endpoint.rb +++ b/spec/bundler/support/artifice/helpers/endpoint.rb @@ -62,7 +62,7 @@ class Endpoint < Sinatra::Base return [] if gem_names.nil? || gem_names.empty? all_specs = %w[specs.4.8 prerelease_specs.4.8].map do |filename| - Marshal.load(File.open(gem_repo.join(filename)).read) + Marshal.load(File.binread(gem_repo.join(filename))) end.inject(:+) all_specs.map do |name, version, platform| diff --git a/spec/bundler/support/artifice/helpers/rack_request.rb b/spec/bundler/support/artifice/helpers/rack_request.rb index f419bacb8c..05ff034463 100644 --- a/spec/bundler/support/artifice/helpers/rack_request.rb +++ b/spec/bundler/support/artifice/helpers/rack_request.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require "rack/test" -require "bundler/vendored_net_http" +require_relative "../../vendored_net_http" module Artifice module Net diff --git a/spec/bundler/support/artifice/vcr.rb b/spec/bundler/support/artifice/vcr.rb index 7b9a8bdeaf..2386a4c6b7 100644 --- a/spec/bundler/support/artifice/vcr.rb +++ b/spec/bundler/support/artifice/vcr.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "bundler/vendored_net_http" +require_relative "../vendored_net_http" require_relative "../path" CASSETTE_PATH = "#{Spec::Path.spec_dir}/support/artifice/vcr_cassettes".freeze diff --git a/spec/bundler/support/build_metadata.rb b/spec/bundler/support/build_metadata.rb index 5898e7f3bd..189100edb7 100644 --- a/spec/bundler/support/build_metadata.rb +++ b/spec/bundler/support/build_metadata.rb @@ -41,7 +41,7 @@ module Spec end def git_commit_sha - ruby_core_tarball? ? "unknown" : sys_exec("git rev-parse --short HEAD", dir: source_root).strip + ruby_core_tarball? ? "unknown" : git("rev-parse --short HEAD", source_root).strip end extend self diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb index 8f646b9358..a187d2ae48 100644 --- a/spec/bundler/support/builders.rb +++ b/spec/bundler/support/builders.rb @@ -5,6 +5,11 @@ require "shellwords" module Spec module Builders + def self.extended(mod) + mod.extend Path + mod.extend Helpers + end + def self.constantize(name) name.delete("-").upcase end @@ -22,8 +27,6 @@ module Spec end def build_repo1 - rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first - build_repo gem_repo1 do FileUtils.cp rake_path, "#{gem_repo1}/gems/" @@ -32,23 +35,23 @@ module Spec build_gem "puma" build_gem "minitest" - build_gem "rack", %w[0.9.1 1.0.0] do |s| - s.executables = "rackup" - s.post_install_message = "Rack's post install message" + build_gem "myrack", %w[0.9.1 1.0.0] do |s| + s.executables = "myrackup" + s.post_install_message = "Myrack's post install message" end build_gem "thin" do |s| - s.add_dependency "rack" + s.add_dependency "myrack" s.post_install_message = "Thin's post install message" end - build_gem "rack-obama" do |s| - s.add_dependency "rack" - s.post_install_message = "Rack-obama's post install message" + build_gem "myrack-obama" do |s| + s.add_dependency "myrack" + s.post_install_message = "Myrack-obama's post install message" end - build_gem "rack_middleware", "1.0" do |s| - s.add_dependency "rack", "0.9.1" + build_gem "myrack_middleware", "1.0" do |s| + s.add_dependency "myrack", "0.9.1" end build_gem "rails", "2.3.2" do |s| @@ -81,80 +84,62 @@ module Spec s.write "lib/spec.rb", "SPEC = '1.2.7'" end - build_gem "rack-test", no_default: true do |s| - s.write "lib/rack/test.rb", "RACK_TEST = '1.0'" - end - - build_gem "platform_specific" do |s| - s.platform = Gem::Platform.local - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 #{Gem::Platform.local}'" + build_gem "myrack-test", no_default: true do |s| + s.write "lib/myrack/test.rb", "MYRACK_TEST = '1.0'" end build_gem "platform_specific" do |s| s.platform = "java" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 JAVA'" end build_gem "platform_specific" do |s| s.platform = "ruby" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 RUBY'" end build_gem "platform_specific" do |s| s.platform = "x86-mswin32" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0 x86-mswin32'" end build_gem "platform_specific" do |s| s.platform = "x64-mswin64" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0 x64-mswin64'" end build_gem "platform_specific" do |s| s.platform = "x86-mingw32" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0 x86-mingw32'" end build_gem "platform_specific" do |s| s.platform = "x64-mingw32" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0 x64-mingw32'" end build_gem "platform_specific" do |s| s.platform = "x64-mingw-ucrt" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0 x64-mingw-ucrt'" end build_gem "platform_specific" do |s| s.platform = "x86-darwin-100" - s.write "lib/platform_specific.rb", "PLATFORM_SPECIFIC = '1.0.0 x86-darwin-100'" end build_gem "only_java", "1.0" do |s| s.platform = "java" - s.write "lib/only_java.rb", "ONLY_JAVA = '1.0.0 JAVA'" end build_gem "only_java", "1.1" do |s| s.platform = "java" - s.write "lib/only_java.rb", "ONLY_JAVA = '1.1.0 JAVA'" end build_gem "nokogiri", "1.4.2" build_gem "nokogiri", "1.4.2" do |s| s.platform = "java" - s.write "lib/nokogiri.rb", "NOKOGIRI = '1.4.2 JAVA'" s.add_dependency "weakling", ">= 0.0.3" end build_gem "laduradura", "5.15.2" build_gem "laduradura", "5.15.2" do |s| s.platform = "java" - s.write "lib/laduradura.rb", "LADURADURA = '5.15.2 JAVA'" end build_gem "laduradura", "5.15.3" do |s| s.platform = "java" - s.write "lib/laduradura.rb", "LADURADURA = '5.15.2 JAVA'" end build_gem "weakling", "0.0.3" @@ -168,7 +153,7 @@ module Spec build_gem "bundler", "0.9" do |s| s.executables = "bundle" - s.write "bin/bundle", "puts 'FAIL'" + s.write "bin/bundle", "#!/usr/bin/env ruby\nputs 'FAIL'" end # The bundler 0.8 gem has a rubygems plugin that always loads :( @@ -203,9 +188,15 @@ module Spec # A repo that has no pre-installed gems included. (The caller completely # determines the contents with the block.) + def build_repo3(**kwargs, &blk) + build_empty_repo gem_repo3, **kwargs, &blk + end + + # Like build_repo3, this is a repo that has no pre-installed gems included. + # We have two different methods for situations where two different empty + # sources are needed. def build_repo4(**kwargs, &blk) - FileUtils.rm_rf gem_repo4 - build_repo(gem_repo4, **kwargs, &blk) + build_empty_repo gem_repo4, **kwargs, &blk end def update_repo4(&blk) @@ -218,7 +209,7 @@ module Spec def build_security_repo build_repo security_repo do - build_gem "rack" + build_gem "myrack" build_gem "signed_gem" do |s| cert = "signing-cert.pem" @@ -240,12 +231,9 @@ module Spec end def check_test_gems! - rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first - if rake_path.nil? - FileUtils.rm_rf(Path.base_system_gems) + FileUtils.rm_rf(base_system_gems) Spec::Rubygems.install_test_deps - rake_path = Dir["#{Path.base_system_gems}/**/rake*.gem"].first end if rake_path.nil? @@ -254,16 +242,17 @@ module Spec end def update_repo(path, build_compact_index: true) - if path == gem_repo1 && caller.first.split(" ").last == "`build_repo`" + exempted_caller = Gem.ruby_version >= Gem::Version.new("3.4.0.dev") ? "#{Module.nesting.first}#build_repo" : "build_repo" + if path == gem_repo1 && caller_locations(1, 1).first.label != exempted_caller raise "Updating gem_repo1 is unsupported -- use gem_repo2 instead" end return unless block_given? @_build_path = "#{path}/gems" @_build_repo = File.basename(path) yield - with_gem_path_as Path.base_system_gem_path do - Dir[Spec::Path.base_system_gem_path.join("gems/rubygems-generate_index*/lib")].first || - raise("Could not find rubygems-generate_index lib directory in #{Spec::Path.base_system_gem_path}") + with_gem_path_as base_system_gem_path do + Dir[base_system_gem_path.join("gems/rubygems-generate_index*/lib")].first || + raise("Could not find rubygems-generate_index lib directory in #{base_system_gem_path}") command = "generate_index" command += " --no-compact" if !build_compact_index && gem_command(command + " --help").include?("--[no-]compact") @@ -324,6 +313,11 @@ module Spec private + def build_empty_repo(gem_repo, **kwargs, &blk) + FileUtils.rm_rf gem_repo + build_repo(gem_repo, **kwargs, &blk) + end + def build_with(builder, name, args, &blk) @_build_path ||= nil @_build_repo ||= nil @@ -462,6 +456,7 @@ module Spec s.email = "foo@bar.baz" s.homepage = "http://example.com" s.license = "MIT" + s.required_ruby_version = ">= 3.0" end @files = {} end @@ -478,18 +473,13 @@ module Spec @spec.executables = Array(val) @spec.executables.each do |file| executable = "#{@spec.bindir}/#{file}" - shebang = if Bundler.current_ruby.jruby? - "#!/usr/bin/env jruby\n" - else - "#!/usr/bin/env ruby\n" - end + shebang = "#!/usr/bin/env ruby\n" @spec.files << executable write executable, "#{shebang}require_relative '../lib/#{@name}' ; puts #{Builders.constantize(@name)}" end end def add_c_extension - require_paths << "ext" extensions << "ext/extconf.rb" write "ext/extconf.rb", <<-RUBY require "mkmf" @@ -544,10 +534,10 @@ module Spec end @files.each do |file, source| - file = Pathname.new(path).join(file) - FileUtils.mkdir_p(file.dirname) - File.open(file, "w") {|f| f.puts source } - File.chmod("+x", file) if @spec.executables.map {|exe| "#{@spec.bindir}/#{exe}" }.include?(file) + full_path = Pathname.new(path).join(file) + FileUtils.mkdir_p(full_path.dirname) + File.open(full_path, "w") {|f| f.puts source } + FileUtils.chmod("+x", full_path) if @spec.executables.map {|exe| "#{@spec.bindir}/#{exe}" }.include?(file) end path end diff --git a/spec/bundler/support/checksums.rb b/spec/bundler/support/checksums.rb index f758559b3b..f3aa13ca9f 100644 --- a/spec/bundler/support/checksums.rb +++ b/spec/bundler/support/checksums.rb @@ -54,11 +54,11 @@ module Spec ChecksumsBuilder.new(enabled, &block) end - def checksums_section_when_existing(&block) + def checksums_section_when_enabled(target_lockfile = nil, &block) begin - enabled = lockfile.match?(/^CHECKSUMS$/) + enabled = (target_lockfile || lockfile).match?(/^CHECKSUMS$/) rescue Errno::ENOENT - enabled = false + enabled = Bundler.feature_flag.bundler_3_mode? end checksums_section(enabled, &block) end @@ -110,5 +110,17 @@ module Spec _checksums, tail = remaining.split("\n\n", 2) head.concat(tail) end + + def checksum_from_package(gem_file, name, version) + name_tuple = Gem::NameTuple.new(name, version) + + checksum = nil + + File.open(gem_file, "rb") do |f| + checksum = Bundler::Checksum.from_gem(f, gemfile) + end + + "#{name_tuple.lock_name} #{checksum.to_lock}" + end end end diff --git a/spec/bundler/support/command_execution.rb b/spec/bundler/support/command_execution.rb index 5639fda3b6..02726744d3 100644 --- a/spec/bundler/support/command_execution.rb +++ b/spec/bundler/support/command_execution.rb @@ -1,7 +1,37 @@ # frozen_string_literal: true module Spec - CommandExecution = Struct.new(:command, :working_directory, :exitstatus, :original_stdout, :original_stderr) do + class CommandExecution + def initialize(command, working_directory:, timeout:) + @command = command + @working_directory = working_directory + @timeout = timeout + @original_stdout = String.new + @original_stderr = String.new + end + + attr_accessor :exitstatus, :command, :original_stdout, :original_stderr + attr_reader :timeout + attr_writer :failure_reason + + def raise_error! + return unless failure? + + error_header = if failure_reason == :timeout + "Invoking `#{command}` was aborted after #{timeout} seconds with output:" + else + "Invoking `#{command}` failed with output:" + end + + raise <<~ERROR + #{error_header} + + ---------------------------------------------------------------------- + #{stdboth} + ---------------------------------------------------------------------- + ERROR + end + def to_s "$ #{command}" end @@ -12,16 +42,11 @@ module Spec end def stdout - original_stdout + normalize(original_stdout) end - # Can be removed once/if https://github.com/oneclick/rubyinstaller2/pull/369 is resolved def stderr - return original_stderr unless Gem.win_platform? - - original_stderr.split("\n").reject do |l| - l.include?("operating_system_defaults") - end.join("\n") + normalize(original_stderr) end def to_s_verbose @@ -42,5 +67,13 @@ module Spec return true unless exitstatus exitstatus > 0 end + + private + + attr_reader :failure_reason + + def normalize(string) + string.force_encoding(Encoding::UTF_8).strip.gsub("\r\n", "\n") + end end end diff --git a/spec/bundler/support/env.rb b/spec/bundler/support/env.rb new file mode 100644 index 0000000000..2d13c449fe --- /dev/null +++ b/spec/bundler/support/env.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Spec + module Env + def ruby_core? + File.exist?(File.expand_path("../../../lib/bundler/bundler.gemspec", __dir__)) + end + end +end diff --git a/spec/bundler/support/filters.rb b/spec/bundler/support/filters.rb index 8e164af756..e1683ae75b 100644 --- a/spec/bundler/support/filters.rb +++ b/spec/bundler/support/filters.rb @@ -14,7 +14,7 @@ class RequirementChecker < Proc attr_accessor :provided def inspect - "\"!= #{provided}\"" + "\"#{provided}\"" end end diff --git a/spec/bundler/support/hax.rb b/spec/bundler/support/hax.rb index c7fe3637cc..492c6ca8ed 100644 --- a/spec/bundler/support/hax.rb +++ b/spec/bundler/support/hax.rb @@ -36,18 +36,4 @@ module Gem if ENV["BUNDLER_SPEC_GEM_SOURCES"] self.sources = [ENV["BUNDLER_SPEC_GEM_SOURCES"]] end - - if ENV["BUNDLER_IGNORE_DEFAULT_GEM"] - module RemoveDefaultBundlerStub - def default_stubs(pattern = "*") - super.delete_if {|stub| stub.name == "bundler" } - end - end - - class Specification - class << self - prepend RemoveDefaultBundlerStub - end - end - end end diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb index 1ad9cc78ca..145008ab42 100644 --- a/spec/bundler/support/helpers.rb +++ b/spec/bundler/support/helpers.rb @@ -1,12 +1,21 @@ # frozen_string_literal: true -require_relative "command_execution" require_relative "the_bundle" require_relative "path" +require_relative "options" +require_relative "subprocess" module Spec module Helpers include Spec::Path + include Spec::Options + include Spec::Subprocess + + def self.extended(mod) + mod.extend Spec::Path + mod.extend Spec::Options + mod.extend Spec::Subprocess + end def reset! Dir.glob("#{tmp}/{gems/*,*}", File::FNM_DOTMATCH).each do |dir| @@ -27,22 +36,6 @@ module Spec TheBundle.new(*args) end - def command_executions - @command_executions ||= [] - end - - def last_command - command_executions.last || raise("There is no last command") - end - - def out - last_command.stdout - end - - def err - last_command.stderr - end - MAJOR_DEPRECATION = /^\[DEPRECATED\]\s*/ def err_without_deprecations @@ -53,10 +46,6 @@ module Spec err.split("\n").select {|l| l =~ MAJOR_DEPRECATION }.join("\n").split(MAJOR_DEPRECATION) end - def exitstatus - last_command.exitstatus - end - def run(cmd, *args) opts = args.last.is_a?(Hash) ? args.pop : {} groups = args.map(&:inspect).join(", ") @@ -82,31 +71,26 @@ module Spec bundle_bin ||= installed_bindir.join("bundle") env = options.delete(:env) || {} + preserve_ruby_flags = options.delete(:preserve_ruby_flags) requires = options.delete(:requires) || [] - realworld = RSpec.current_example.metadata[:realworld] - artifice = options.delete(:artifice) do - if realworld - "vcr" - else - "fail" - end - end - if artifice - requires << "#{Path.spec_dir}/support/artifice/#{artifice}.rb" - end + dir = options.delete(:dir) || bundled_app load_path = [] load_path << spec_dir - dir = options.delete(:dir) || bundled_app + build_ruby_options = { load_path: load_path, requires: requires, env: env } + build_ruby_options.merge!(artifice: options.delete(:artifice)) if options.key?(:artifice) + + match_source(cmd) + + env, ruby_cmd = build_ruby_cmd(build_ruby_options) + raise_on_error = options.delete(:raise_on_error) args = options.map do |k, v| case v - when nil - next when true " --#{k}" when false @@ -116,19 +100,30 @@ module Spec end end.join - ruby_cmd = build_ruby_cmd({ load_path: load_path, requires: requires, env: env }) cmd = "#{ruby_cmd} #{bundle_bin} #{cmd}#{args}" + env["BUNDLER_SPEC_ORIGINAL_CMD"] = "#{ruby_cmd} #{bundle_bin}" if preserve_ruby_flags sys_exec(cmd, { env: env, dir: dir, raise_on_error: raise_on_error }, &block) end + def main_source(dir) + gemfile = File.expand_path("Gemfile", dir) + return unless File.exist?(gemfile) + + match = File.readlines(gemfile).first.match(/source ["'](?<source>[^"']+)["']/) + return unless match + + match[:source] + end + def bundler(cmd, options = {}) - options[:bundle_bin] = system_gem_path.join("bin/bundler") + options[:bundle_bin] = system_gem_path("bin/bundler") bundle(cmd, options) end def ruby(ruby, options = {}) - ruby_cmd = build_ruby_cmd + env, ruby_cmd = build_ruby_cmd({ artifice: nil }.merge(options)) escaped_ruby = ruby.shellescape + options[:env] = env if env sys_exec(%(#{ruby_cmd} -w -e #{escaped_ruby}), options) end @@ -146,17 +141,40 @@ module Spec libs = options.delete(:load_path) lib_option = libs ? "-I#{libs.join(File::PATH_SEPARATOR)}" : [] + env = options.delete(:env) || {} + current_example = RSpec.current_example + + main_source = @gemfile_source if defined?(@gemfile_source) + compact_index_main_source = main_source&.start_with?("https://gem.repo", "https://gems.security") + requires = options.delete(:requires) || [] + artifice = options.delete(:artifice) do + if current_example && current_example.metadata[:realworld] + "vcr" + elsif compact_index_main_source + env["BUNDLER_SPEC_GEM_REPO"] ||= + case main_source + when "https://gem.repo1" then gem_repo1.to_s + when "https://gem.repo2" then gem_repo2.to_s + when "https://gem.repo3" then gem_repo3.to_s + when "https://gem.repo4" then gem_repo4.to_s + when "https://gems.security" then security_repo.to_s + end + + "compact_index" + else + "fail" + end + end + if artifice + requires << "#{Path.spec_dir}/support/artifice/#{artifice}.rb" + end - hax_path = "#{Path.spec_dir}/support/hax.rb" + requires << "#{Path.spec_dir}/support/hax.rb" - # For specs that need to ignore the default Bundler gem, load hax before - # anything else since other stuff may actually load bundler and not skip - # the default version - options[:env]&.include?("BUNDLER_IGNORE_DEFAULT_GEM") ? requires.prepend(hax_path) : requires.append(hax_path) require_option = requires.map {|r| "-r#{r}" } - [Gem.ruby, *lib_option, *require_option].compact.join(" ") + [env, [Gem.ruby, *lib_option, *require_option].compact.join(" ")] end def gembin(cmd, options = {}) @@ -168,70 +186,40 @@ module Spec env = options[:env] || {} env["RUBYOPT"] = opt_add(opt_add("-r#{spec_dir}/support/hax.rb", env["RUBYOPT"]), ENV["RUBYOPT"]) options[:env] = env - sys_exec("#{Path.gem_bin} #{command}", options) + output = sys_exec("#{Path.gem_bin} #{command}", options) + stderr = last_command.stderr + raise stderr if stderr.include?("WARNING") && !allowed_rubygems_warning?(stderr) + output end def rake "#{Gem.ruby} -S #{ENV["GEM_PATH"]}/bin/rake" end - def git(cmd, path, options = {}) - sys_exec("git #{cmd}", options.merge(dir: path)) - end - - def sys_exec(cmd, options = {}) + def sys_exec(cmd, options = {}, &block) env = options[:env] || {} env["RUBYOPT"] = opt_add(opt_add("-r#{spec_dir}/support/switch_rubygems.rb", env["RUBYOPT"]), ENV["RUBYOPT"]) - dir = options[:dir] || bundled_app - command_execution = CommandExecution.new(cmd.to_s, dir) - - require "open3" - require "shellwords" - Open3.popen3(env, *cmd.shellsplit, chdir: dir) do |stdin, stdout, stderr, wait_thr| - yield stdin, stdout, wait_thr if block_given? - stdin.close - - stdout_read_thread = Thread.new { stdout.read } - stderr_read_thread = Thread.new { stderr.read } - command_execution.original_stdout = stdout_read_thread.value.strip - command_execution.original_stderr = stderr_read_thread.value.strip - - status = wait_thr.value - command_execution.exitstatus = if status.exited? - status.exitstatus - elsif status.signaled? - exit_status_for_signal(status.termsig) - end - end - - unless options[:raise_on_error] == false || command_execution.success? - raise <<~ERROR - - Invoking `#{cmd}` failed with output: - ---------------------------------------------------------------------- - #{command_execution.stdboth} - ---------------------------------------------------------------------- - ERROR - end - - command_executions << command_execution + options[:env] = env + options[:dir] ||= bundled_app - command_execution.stdout + sh(cmd, options, &block) end - def all_commands_output - return "" if command_executions.empty? + def config(config = nil, path = bundled_app(".bundle/config")) + current = File.exist?(path) ? Psych.load_file(path) : {} + return current unless config - "\n\nCommands:\n#{command_executions.map(&:to_s_verbose).join("\n\n")}" - end + current = {} if current.empty? - def config(config = nil, path = bundled_app(".bundle/config")) - return Psych.load_file(path) unless config FileUtils.mkdir_p(File.dirname(path)) - File.open(path, "w") do |f| - f.puts config.to_yaml + + new_config = current.merge(config).compact + + File.open(path, "w+") do |f| + f.puts new_config.to_yaml end - config + + new_config end def global_config(config = nil) @@ -252,6 +240,7 @@ module Spec if contents.nil? read_gemfile else + match_source(contents) create_file(args.pop || "Gemfile", contents) end end @@ -317,6 +306,12 @@ module Spec end end + def self.install_dev_bundler + extend self + + system_gems :bundler, path: pristine_system_gem_path + end + def install_gem(path, install_dir, default = false) raise "OMG `#{path}` does not exist!" unless File.exist?(path) @@ -327,6 +322,8 @@ module Spec end def with_built_bundler(version = nil, &block) + require_relative "builders" + Builders::BundlerBuilder.new(self, "bundler", version)._build(&block) end @@ -361,16 +358,6 @@ module Spec end end - def opt_add(option, options) - [option.strip, options].compact.reject(&:empty?).join(" ") - end - - def opt_remove(option, options) - return unless options - - options.split(" ").reject {|opt| opt.strip == option.strip }.join(" ") - end - def break_git! FileUtils.mkdir_p(tmp("broken_path")) File.open(tmp("broken_path/git"), "w", 0o755) do |f| @@ -437,7 +424,7 @@ module Spec def simulate_platform(platform) old = ENV["BUNDLER_SPEC_PLATFORM"] ENV["BUNDLER_SPEC_PLATFORM"] = platform.to_s - yield if block_given? + yield ensure ENV["BUNDLER_SPEC_PLATFORM"] = old if block_given? end @@ -471,7 +458,7 @@ module Spec end def revision_for(path) - sys_exec("git rev-parse HEAD", dir: path).strip + git("rev-parse HEAD", path).strip end def with_read_only(pattern) @@ -558,6 +545,17 @@ module Spec private + def allowed_rubygems_warning?(text) + text.include?("open-ended") || text.include?("is a symlink") || text.include?("rake based") || text.include?("expected RubyGems version") + end + + def match_source(contents) + match = /source ["']?(?<source>http[^"']+)["']?/.match(contents) + return unless match + + @gemfile_source = match[:source] + end + def git_root_dir? root.to_s == `git rev-parse --show-toplevel`.chomp end diff --git a/spec/bundler/support/indexes.rb b/spec/bundler/support/indexes.rb index 086a311551..7960bae59f 100644 --- a/spec/bundler/support/indexes.rb +++ b/spec/bundler/support/indexes.rb @@ -77,8 +77,8 @@ module Spec def an_awesome_index build_index do - gem "rack", %w[0.8 0.9 0.9.1 0.9.2 1.0 1.1] - gem "rack-mount", %w[0.4 0.5 0.5.1 0.5.2 0.6] + gem "myrack", %w[0.8 0.9 0.9.1 0.9.2 1.0 1.1] + gem "myrack-mount", %w[0.4 0.5 0.5.1 0.5.2 0.6] # --- Pre-release support gem "RubyGems\0", ["1.3.2"] @@ -89,10 +89,10 @@ module Spec gem "actionpack", version do dep "activesupport", version if version >= v("3.0.0.beta") - dep "rack", "~> 1.1" - dep "rack-mount", ">= 0.5" - elsif version > v("2.3") then dep "rack", "~> 1.0.0" - elsif version > v("2.0.0") then dep "rack", "~> 0.9.0" + dep "myrack", "~> 1.1" + dep "myrack-mount", ">= 0.5" + elsif version > v("2.3") then dep "myrack", "~> 1.0.0" + elsif version > v("2.0.0") then dep "myrack", "~> 0.9.0" end end gem "activerecord", version do @@ -367,7 +367,7 @@ module Spec def a_circular_index build_index do - gem "rack", "1.0.1" + gem "myrack", "1.0.1" gem("foo", "0.2.6") do dep "bar", ">= 0" end diff --git a/spec/bundler/support/matchers.rb b/spec/bundler/support/matchers.rb index 0f027dcf04..ed11e3ba52 100644 --- a/spec/bundler/support/matchers.rb +++ b/spec/bundler/support/matchers.rb @@ -118,6 +118,7 @@ module Spec opts[:raise_on_error] = false @errors = names.map do |full_name| name, version, platform = full_name.split(/\s+/) + platform ||= "ruby" require_path = name.tr("-", "/") version_const = name == "bundler" ? "Bundler::VERSION" : Spec::Builders.constantize(name) source_const = "#{Spec::Builders.constantize(name)}_SOURCE" @@ -127,6 +128,7 @@ module Spec require '#{require_path}' actual_version, actual_platform = #{version_const}.split(/\s+/, 2) + actual_platform ||= "ruby" unless Gem::Version.new(actual_version) == Gem::Version.new('#{version}') puts actual_version exit 64 @@ -150,7 +152,7 @@ module Spec end if exitstatus == 65 actual_platform = out.split("\n").last - next "#{name} was expected to be of platform #{platform || "ruby"} but was #{actual_platform || "ruby"}" + next "#{name} was expected to be of platform #{platform} but was #{actual_platform}" end if exitstatus == 66 actual_source = out.split("\n").last diff --git a/spec/bundler/support/options.rb b/spec/bundler/support/options.rb new file mode 100644 index 0000000000..551fa1acd8 --- /dev/null +++ b/spec/bundler/support/options.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Spec + module Options + def opt_add(option, options) + [option.strip, options].compact.reject(&:empty?).join(" ") + end + + def opt_remove(option, options) + return unless options + + options.split(" ").reject {|opt| opt.strip == option.strip }.join(" ") + end + end +end diff --git a/spec/bundler/support/path.rb b/spec/bundler/support/path.rb index 7352d5a353..b26e77d376 100644 --- a/spec/bundler/support/path.rb +++ b/spec/bundler/support/path.rb @@ -3,8 +3,12 @@ require "pathname" require "rbconfig" +require_relative "env" + module Spec module Path + include Spec::Env + def source_root @source_root ||= Pathname.new(ruby_core? ? "../../.." : "../..").expand_path(__dir__) end @@ -58,7 +62,7 @@ module Spec end def gem_bin - @gem_bin ||= ruby_core? ? ENV["GEM_COMMAND"] : "gem" + @gem_bin ||= ENV["GEM_COMMAND"] || "gem" end def path @@ -98,7 +102,18 @@ module Spec end def tmp(*path) - source_root.join("tmp", scope, *path) + tmp_root(scope).join(*path) + end + + def tmp_root(scope) + source_root.join("tmp", "#{test_env_version}.#{scope}") + end + + # Bump this version whenever you make a breaking change to the spec setup + # that requires regenerating tmp/. + + def test_env_version + 1 end def scope @@ -109,7 +124,7 @@ module Spec end def home(*path) - tmp.join("home", *path) + tmp("home", *path) end def default_bundle_path(*path) @@ -129,13 +144,13 @@ module Spec end def bundled_app(*path) - root = tmp.join("bundled_app") + root = tmp("bundled_app") FileUtils.mkdir_p(root) root.join(*path) end def bundled_app2(*path) - root = tmp.join("bundled_app2") + root = tmp("bundled_app2") FileUtils.mkdir_p(root) root.join(*path) end @@ -161,15 +176,15 @@ module Spec end def base_system_gems - tmp.join("gems/base") + tmp("gems/base") end def rubocop_gems - tmp.join("gems/rubocop") + tmp("gems/rubocop") end def standard_gems - tmp.join("gems/standard") + tmp("gems/standard") end def file_uri_for(path) @@ -257,27 +272,20 @@ module Spec File.open(gemspec_file, "w") {|f| f << contents } end - def ruby_core? - # avoid to warnings - @ruby_core ||= nil - - if @ruby_core.nil? - @ruby_core = true & ENV["GEM_COMMAND"] - else - @ruby_core - end - end - def git_root ruby_core? ? source_root : source_root.parent end + def rake_path + Dir["#{base_system_gems}/#{Bundler.ruby_scope}/**/rake*.gem"].first + end + private def git_ls_files(glob) skip "Not running on a git context, since running tests from a tarball" if ruby_core_tarball? - sys_exec("git ls-files -z -- #{glob}", dir: source_root).split("\x0") + git("ls-files -z -- #{glob}", source_root).split("\x0") end def tracked_files_glob diff --git a/spec/bundler/support/rubygems_ext.rb b/spec/bundler/support/rubygems_ext.rb index 889ebc90c3..1fc5aa16c0 100644 --- a/spec/bundler/support/rubygems_ext.rb +++ b/spec/bundler/support/rubygems_ext.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +abort "RubyGems only supports Ruby 3.0 or higher" if RUBY_VERSION < "3.0.0" + require_relative "path" $LOAD_PATH.unshift(Spec::Path.source_lib_dir.to_s) @@ -57,8 +59,8 @@ module Spec install_test_deps (2..Parallel.processor_count).each do |n| - source = Path.source_root.join("tmp", "1") - destination = Path.source_root.join("tmp", n.to_s) + source = Path.tmp_root("1") + destination = Path.tmp_root(n.to_s) FileUtils.rm_rf destination FileUtils.cp_r source, destination @@ -70,14 +72,20 @@ module Spec ENV["BUNDLE_PATH"] = nil ENV["GEM_HOME"] = ENV["GEM_PATH"] = Path.base_system_gem_path.to_s - ENV["PATH"] = [Path.system_gem_path.join("bin"), ENV["PATH"]].join(File::PATH_SEPARATOR) + ENV["PATH"] = [Path.system_gem_path("bin"), ENV["PATH"]].join(File::PATH_SEPARATOR) ENV["PATH"] = [Path.bindir, ENV["PATH"]].join(File::PATH_SEPARATOR) if Path.ruby_core? end def install_test_deps + Gem.clear_paths + install_gems(test_gemfile, Path.base_system_gems.to_s) install_gems(rubocop_gemfile, Path.rubocop_gems.to_s) install_gems(standard_gemfile, Path.standard_gems.to_s) + + # For some reason, doing this here crashes on JRuby + Windows. So defer to + # when the test suite is running in that case. + Helpers.install_dev_bundler unless Gem.win_platform? && RUBY_ENGINE == "jruby" end def check_source_control_changes(success_message:, error_message:) @@ -117,7 +125,14 @@ module Spec def gem_activate_and_possibly_install(gem_name) gem_activate(gem_name) rescue Gem::LoadError => e - Gem.install(gem_name, e.requirement) + # Windows 3.0 puts a Windows stub script as `rake` while it should be + # named `rake.bat`. RubyGems does not like that and avoids overwriting it + # unless explicitly instructed to do so with `force`. + if RUBY_VERSION.start_with?("3.0") && Gem.win_platform? + Gem.install(gem_name, e.requirement, force: true) + else + Gem.install(gem_name, e.requirement) + end retry end diff --git a/spec/bundler/support/rubygems_version_manager.rb b/spec/bundler/support/rubygems_version_manager.rb index 88da14b67e..c174c461f0 100644 --- a/spec/bundler/support/rubygems_version_manager.rb +++ b/spec/bundler/support/rubygems_version_manager.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -require "pathname" -require_relative "helpers" -require_relative "path" +require_relative "options" +require_relative "env" +require_relative "subprocess" class RubygemsVersionManager - include Spec::Helpers - include Spec::Path + include Spec::Options + include Spec::Env + include Spec::Subprocess def initialize(source) @source = source @@ -57,7 +58,7 @@ class RubygemsVersionManager cmd = [RbConfig.ruby, $0, *ARGV].compact - ENV["RUBYOPT"] = opt_add("-I#{local_copy_path.join("lib")}", opt_remove("--disable-gems", ENV["RUBYOPT"])) + ENV["RUBYOPT"] = opt_add("-I#{File.join(local_copy_path, "lib")}", opt_remove("--disable-gems", ENV["RUBYOPT"])) exec(ENV, *cmd) end @@ -65,14 +66,14 @@ class RubygemsVersionManager def switch_local_copy_if_needed return unless local_copy_switch_needed? - sys_exec("git checkout #{target_tag}", dir: local_copy_path) + git("checkout #{target_tag}", local_copy_path) - ENV["RGV"] = local_copy_path.to_s + ENV["RGV"] = local_copy_path end def rubygems_unrequire_needed? require "rubygems" - !$LOADED_FEATURES.include?(local_copy_path.join("lib/rubygems.rb").to_s) + !$LOADED_FEATURES.include?(File.join(local_copy_path, "lib/rubygems.rb")) end def local_copy_switch_needed? @@ -84,7 +85,7 @@ class RubygemsVersionManager end def local_copy_tag - sys_exec("git rev-parse --abbrev-ref HEAD", dir: local_copy_path) + git("rev-parse --abbrev-ref HEAD", local_copy_path) end def local_copy_path @@ -94,21 +95,25 @@ class RubygemsVersionManager def resolve_local_copy_path return expanded_source if source_is_path? - rubygems_path = source_root.join("tmp/rubygems") + rubygems_path = File.join(source_root, "tmp/rubygems") - unless rubygems_path.directory? - sys_exec("git clone .. #{rubygems_path}", dir: source_root) + unless File.directory?(rubygems_path) + git("clone .. #{rubygems_path}", source_root) end rubygems_path end def source_is_path? - expanded_source.directory? + File.directory?(expanded_source) end def expanded_source - @expanded_source ||= Pathname.new(@source).expand_path(source_root) + @expanded_source ||= File.expand_path(@source, source_root) + end + + def source_root + @source_root ||= File.expand_path(ruby_core? ? "../../.." : "../..", __dir__) end def resolve_target_tag diff --git a/spec/bundler/support/subprocess.rb b/spec/bundler/support/subprocess.rb new file mode 100644 index 0000000000..ade18e7805 --- /dev/null +++ b/spec/bundler/support/subprocess.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +require_relative "command_execution" + +module Spec + module Subprocess + class TimeoutExceeded < StandardError; end + + def command_executions + @command_executions ||= [] + end + + def last_command + command_executions.last || raise("There is no last command") + end + + def out + last_command.stdout + end + + def err + last_command.stderr + end + + def exitstatus + last_command.exitstatus + end + + def git(cmd, path = Dir.pwd, options = {}) + sh("git #{cmd}", options.merge(dir: path)) + end + + def sh(cmd, options = {}) + dir = options[:dir] + env = options[:env] || {} + + command_execution = CommandExecution.new(cmd.to_s, working_directory: dir, timeout: 60) + + require "open3" + require "shellwords" + Open3.popen3(env, *cmd.shellsplit, chdir: dir) do |stdin, stdout, stderr, wait_thr| + yield stdin, stdout, wait_thr if block_given? + stdin.close + + stdout_handler = ->(data) { command_execution.original_stdout << data } + stderr_handler = ->(data) { command_execution.original_stderr << data } + + stdout_thread = read_stream(stdout, stdout_handler, timeout: command_execution.timeout) + stderr_thread = read_stream(stderr, stderr_handler, timeout: command_execution.timeout) + + stdout_thread.join + stderr_thread.join + + status = wait_thr.value + command_execution.exitstatus = if status.exited? + status.exitstatus + elsif status.signaled? + exit_status_for_signal(status.termsig) + end + rescue TimeoutExceeded + command_execution.failure_reason = :timeout + command_execution.exitstatus = exit_status_for_signal(Signal.list["INT"]) + end + + unless options[:raise_on_error] == false || command_execution.success? + command_execution.raise_error! + end + + command_executions << command_execution + + command_execution.stdout + end + + # Mostly copied from https://github.com/piotrmurach/tty-command/blob/49c37a895ccea107e8b78d20e4cb29de6a1a53c8/lib/tty/command/process_runner.rb#L165-L193 + def read_stream(stream, handler, timeout:) + Thread.new do + Thread.current.report_on_exception = false + cmd_start = Time.now + readers = [stream] + + while readers.any? + ready = IO.select(readers, nil, readers, timeout) + raise TimeoutExceeded if ready.nil? + + ready[0].each do |reader| + chunk = reader.readpartial(16 * 1024) + handler.call(chunk) + + # control total time spent reading + runtime = Time.now - cmd_start + time_left = timeout - runtime + raise TimeoutExceeded if time_left < 0.0 + rescue Errno::EAGAIN, Errno::EINTR + rescue EOFError, Errno::EPIPE, Errno::EIO + readers.delete(reader) + reader.close + end + end + end + end + + def all_commands_output + return "" if command_executions.empty? + + "\n\nCommands:\n#{command_executions.map(&:to_s_verbose).join("\n\n")}" + end + end +end diff --git a/spec/bundler/support/vendored_net_http.rb b/spec/bundler/support/vendored_net_http.rb new file mode 100644 index 0000000000..8ff2ccd1fe --- /dev/null +++ b/spec/bundler/support/vendored_net_http.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# This defined? guard can be removed once RubyGems 3.4 support is dropped. +# +# Bundler specs load this code from `spec/support/vendored_net_http.rb` to avoid +# activating the Bundler gem too early. Without this guard, we get redefinition +# warnings once Bundler is actually activated and +# `lib/bundler/vendored_net_http.rb` is required. This is not an issue in +# RubyGems versions including `rubygems/vendored_net_http` since `require` takes +# care of avoiding the double load. +# +unless defined?(Gem::Net) + begin + require "rubygems/vendored_net_http" + rescue LoadError + begin + require "rubygems/net/http" + rescue LoadError + require "net/http" + Gem::Net = Net + end + end +end diff --git a/spec/bundler/update/gemfile_spec.rb b/spec/bundler/update/gemfile_spec.rb index d32a7945b0..cb94799061 100644 --- a/spec/bundler/update/gemfile_spec.rb +++ b/spec/bundler/update/gemfile_spec.rb @@ -4,8 +4,8 @@ RSpec.describe "bundle update" do context "with --gemfile" do it "finds the gemfile" do gemfile bundled_app("NotGemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle :install, gemfile: bundled_app("NotGemfile") @@ -14,15 +14,15 @@ RSpec.describe "bundle update" do # Specify BUNDLE_GEMFILE for `the_bundle` # to retrieve the proper Gemfile ENV["BUNDLE_GEMFILE"] = "NotGemfile" - expect(the_bundle).to include_gems "rack 1.0.0" + expect(the_bundle).to include_gems "myrack 1.0.0" end end context "with gemfile set via config" do before do gemfile bundled_app("NotGemfile"), <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' G bundle "config set --local gemfile #{bundled_app("NotGemfile")}" @@ -33,7 +33,7 @@ RSpec.describe "bundle update" do bundle "update", all: true bundle "list" - expect(out).to include("rack (1.0.0)") + expect(out).to include("myrack (1.0.0)") end it "uses the gemfile while in a subdirectory" do @@ -41,7 +41,7 @@ RSpec.describe "bundle update" do bundle "update", all: true, dir: bundled_app("subdir") bundle "list", dir: bundled_app("subdir") - expect(out).to include("rack (1.0.0)") + expect(out).to include("myrack (1.0.0)") end end end diff --git a/spec/bundler/update/gems/fund_spec.rb b/spec/bundler/update/gems/fund_spec.rb index 4a87c16bf7..a5624d3e0a 100644 --- a/spec/bundler/update/gems/fund_spec.rb +++ b/spec/bundler/update/gems/fund_spec.rb @@ -24,7 +24,7 @@ RSpec.describe "bundle update" do end gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding_and_other_metadata' gem 'has_funding', '< 2.0' G @@ -35,7 +35,7 @@ RSpec.describe "bundle update" do context "when listed gems are updated" do before do gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" gem 'has_funding_and_other_metadata' gem 'has_funding' G diff --git a/spec/bundler/update/gems/post_install_spec.rb b/spec/bundler/update/gems/post_install_spec.rb index e3593387d4..9c71f6e0e3 100644 --- a/spec/bundler/update/gems/post_install_spec.rb +++ b/spec/bundler/update/gems/post_install_spec.rb @@ -5,8 +5,8 @@ RSpec.describe "bundle update" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack', "< 1.0" + source "https://gem.repo1" + gem 'myrack', "< 1.0" gem 'thin' G @@ -17,10 +17,10 @@ RSpec.describe "bundle update" do shared_examples "a config observer" do context "when ignore post-install messages for gem is set" do - let(:config) { "ignore_messages.rack true" } + let(:config) { "ignore_messages.myrack true" } it "doesn't display gem's post-install message" do - expect(out).not_to include("Rack's post install message") + expect(out).not_to include("Myrack's post install message") end end @@ -35,8 +35,8 @@ RSpec.describe "bundle update" do shared_examples "a post-install message outputter" do it "should display post-install messages for updated gems" do - expect(out).to include("Post-install message from rack:") - expect(out).to include("Rack's post install message") + expect(out).to include("Post-install message from myrack:") + expect(out).to include("Myrack's post install message") end it "should not display the post-install message for non-updated gems" do @@ -47,8 +47,8 @@ RSpec.describe "bundle update" do context "when listed gem is updated" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack' + source "https://gem.repo1" + gem 'myrack' gem 'thin' G @@ -62,8 +62,8 @@ RSpec.describe "bundle update" do context "when dependency triggers update" do before do gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem 'rack-obama' + source "https://gem.repo1" + gem 'myrack-obama' gem 'thin' G diff --git a/spec/bundler/update/git_spec.rb b/spec/bundler/update/git_spec.rb index 3b7bbfd979..64124e0920 100644 --- a/spec/bundler/update/git_spec.rb +++ b/spec/bundler/update/git_spec.rb @@ -7,7 +7,7 @@ RSpec.describe "bundle update" do update_git "foo", branch: "omg" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo-1.0")}", :branch => "omg" do gem 'foo' end @@ -29,8 +29,8 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rails", :git => "#{file_uri_for(lib_path("rails"))}" + source "https://gem.repo1" + gem "rails", :git => "#{lib_path("rails")}" G bundle "update rails" @@ -42,7 +42,7 @@ RSpec.describe "bundle update" do update_git "foo", branch: "omg", path: lib_path("foo") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" git "#{lib_path("foo")}", :branch => "omg" do gem 'foo' end @@ -64,8 +64,8 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo"))}" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo")}" gem "bar" G @@ -83,30 +83,30 @@ RSpec.describe "bundle update" do build_git "foo", path: lib_path("foo_two") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", "1.0", :git => "#{file_uri_for(lib_path("foo_one"))}" + source "https://gem.repo1" + gem "foo", "1.0", :git => "#{lib_path("foo_one")}" G FileUtils.rm_rf lib_path("foo_one") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", "1.0", :git => "#{file_uri_for(lib_path("foo_two"))}" + source "https://gem.repo1" + gem "foo", "1.0", :git => "#{lib_path("foo_two")}" G expect(err).to be_empty - expect(out).to include("Fetching #{file_uri_for(lib_path)}/foo_two") + expect(out).to include("Fetching #{lib_path}/foo_two") expect(out).to include("Bundle complete!") end it "fetches tags from the remote" do build_git "foo" @remote = build_git("bar", bare: true) - update_git "foo", remote: file_uri_for(@remote.path) + update_git "foo", remote: @remote.path update_git "foo", push: "main" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{@remote.path}" G @@ -115,7 +115,7 @@ RSpec.describe "bundle update" do update_git "foo", push: "fubar" gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem 'foo', :git => "#{@remote.path}", :tag => "fubar" G @@ -142,13 +142,13 @@ RSpec.describe "bundle update" do 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") + git "submodule add #{lib_path("submodule-1.0")} submodule-1.0", lib_path("has_submodule-1.0") + git "commit -m \"submodulator\"", lib_path("has_submodule-1.0") end it "it unlocks the source when submodules are added to a git source" do install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" git "#{lib_path("has_submodule-1.0")}" do gem "has_submodule" end @@ -158,7 +158,7 @@ RSpec.describe "bundle update" do expect(out).to eq("GEM") install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" git "#{lib_path("has_submodule-1.0")}", :submodules => true do gem "has_submodule" end @@ -170,7 +170,7 @@ RSpec.describe "bundle update" do it "unlocks the source when submodules are removed from git source", git: ">= 2.9.0" do install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" git "#{lib_path("has_submodule-1.0")}", :submodules => true do gem "has_submodule" end @@ -180,7 +180,7 @@ RSpec.describe "bundle update" do expect(out).to eq("GIT") install_gemfile <<-G - source "#{file_uri_for(gem_repo4)}" + source "https://gem.repo4" git "#{lib_path("has_submodule-1.0")}" do gem "has_submodule" end @@ -195,8 +195,8 @@ RSpec.describe "bundle update" do build_git "foo", "1.0" install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "foo", :git => "#{file_uri_for(lib_path("foo-1.0"))}" + source "https://gem.repo1" + gem "foo", :git => "#{lib_path("foo-1.0")}" G lib_path("foo-1.0").join(".git").rmtree @@ -207,19 +207,19 @@ RSpec.describe "bundle update" do end it "should not explode on invalid revision on update of gem by name" do - build_git "rack", "0.8" + build_git "myrack", "0.8" - build_git "rack", "0.8", path: lib_path("local-rack") do |s| - s.write "lib/rack.rb", "puts :LOCAL" + build_git "myrack", "0.8", path: lib_path("local-myrack") do |s| + s.write "lib/myrack.rb", "puts :LOCAL" end install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack", :git => "#{file_uri_for(lib_path("rack-0.8"))}", :branch => "main" + source "https://gem.repo1" + gem "myrack", :git => "#{lib_path("myrack-0.8")}", :branch => "main" G - bundle %(config set local.rack #{lib_path("local-rack")}) - bundle "update rack" + bundle %(config set local.myrack #{lib_path("local-myrack")}) + bundle "update myrack" expect(out).to include("Bundle updated!") end @@ -227,14 +227,14 @@ RSpec.describe "bundle update" do build_git "rails", "2.3.2", path: lib_path("rails") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rails", :git => "#{file_uri_for(lib_path("rails"))}" + source "https://gem.repo1" + gem "rails", :git => "#{lib_path("rails")}" G update_git "rails", "3.0", path: lib_path("rails"), gemspec: true bundle "update", all: true - expect(out).to include("Using rails 3.0 (was 2.3.2) from #{file_uri_for(lib_path("rails"))} (at main@#{revision_for(lib_path("rails"))[0..6]})") + expect(out).to include("Using rails 3.0 (was 2.3.2) from #{lib_path("rails")} (at main@#{revision_for(lib_path("rails"))[0..6]})") end end @@ -246,11 +246,11 @@ RSpec.describe "bundle update" do end install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" git "#{lib_path("foo")}" do gem 'foo' end - gem 'rack' + gem 'myrack' G end @@ -279,7 +279,7 @@ RSpec.describe "bundle update" do update_git "foo", path: @git.path bundle "update --source foo" - expect(the_bundle).to include_gems "rack 1.0" + expect(the_bundle).to include_gems "myrack 1.0" end end @@ -289,11 +289,11 @@ RSpec.describe "bundle update" do @git = build_git "foo", path: lib_path("bar") install_gemfile <<-G - source "#{file_uri_for(gem_repo2)}" + source "https://gem.repo2" git "#{lib_path("bar")}" do gem 'foo' end - gem 'rack' + gem 'myrack' G end @@ -309,9 +309,9 @@ RSpec.describe "bundle update" do bundle "update --source bar" - checksums = checksums_section_when_existing do |c| + checksums = checksums_section_when_enabled do |c| c.no_checksum "foo", "2.0" - c.checksum gem_repo2, "rack", "1.0.0" + c.checksum gem_repo2, "myrack", "1.0.0" end expect(lockfile).to eq <<~G @@ -322,16 +322,16 @@ RSpec.describe "bundle update" do foo (2.0) GEM - remote: #{file_uri_for(gem_repo2)}/ + remote: https://gem.repo2/ specs: - rack (1.0.0) + myrack (1.0.0) PLATFORMS #{lockfile_platforms} DEPENDENCIES foo! - rack + myrack #{checksums} BUNDLED WITH #{Bundler::VERSION} diff --git a/spec/bundler/update/path_spec.rb b/spec/bundler/update/path_spec.rb index 1f8992b33f..8c76c94e1a 100644 --- a/spec/bundler/update/path_spec.rb +++ b/spec/bundler/update/path_spec.rb @@ -6,7 +6,7 @@ RSpec.describe "path sources" do build_lib "activesupport", "2.3.5", path: lib_path("rails/activesupport") install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" + source "https://gem.repo1" gem "activesupport", :path => "#{lib_path("rails/activesupport")}" G diff --git a/spec/bundler/update/redownload_spec.rb b/spec/bundler/update/redownload_spec.rb index 4a8c711bfa..66437fb938 100644 --- a/spec/bundler/update/redownload_spec.rb +++ b/spec/bundler/update/redownload_spec.rb @@ -3,42 +3,42 @@ RSpec.describe "bundle update" do before :each do install_gemfile <<-G - source "#{file_uri_for(gem_repo1)}" - gem "rack" + source "https://gem.repo1" + gem "myrack" G end describe "with --force" do it "shows a deprecation when single flag passed", bundler: 2 do - bundle "update rack --force" + bundle "update myrack --force" expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`" end it "shows a deprecation when multiple flags passed", bundler: 2 do - bundle "update rack --no-color --force" + bundle "update myrack --no-color --force" expect(err).to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`" end end describe "with --redownload" do it "does not show a deprecation when single flag passed" do - bundle "update rack --redownload" + bundle "update myrack --redownload" expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`" end it "does not show a deprecation when single multiple flags passed" do - bundle "update rack --no-color --redownload" + bundle "update myrack --no-color --redownload" expect(err).not_to include "[DEPRECATED] The `--force` option has been renamed to `--redownload`" end it "re-installs installed gems" do - rack_lib = default_bundle_path("gems/rack-1.0.0/lib/rack.rb") - rack_lib.open("w") {|f| f.write("blah blah blah") } + myrack_lib = default_bundle_path("gems/myrack-1.0.0/lib/myrack.rb") + myrack_lib.open("w") {|f| f.write("blah blah blah") } bundle :update, redownload: true - expect(out).to include "Installing rack 1.0.0" - expect(rack_lib.open(&:read)).to eq("RACK = '1.0.0'\n") - expect(the_bundle).to include_gems "rack 1.0.0" + expect(out).to include "Installing myrack 1.0.0" + expect(myrack_lib.open(&:read)).to eq("MYRACK = '1.0.0'\n") + expect(the_bundle).to include_gems "myrack 1.0.0" end end end diff --git a/spec/default.mspec b/spec/default.mspec index cae5fa374f..ecd3f3afe9 100644 --- a/spec/default.mspec +++ b/spec/default.mspec @@ -90,6 +90,7 @@ require 'mspec/runner/formatters/dotted' class DottedFormatter prepend Module.new { BASE = __dir__ + "/ruby/" unless defined?(BASE) + COUNT_WIDTH = 6 unless defined?(COUNT_WIDTH) def initialize(out = nil) super @@ -97,7 +98,10 @@ class DottedFormatter @columns = nil else columns = ENV["COLUMNS"]&.to_i - @columns = columns&.nonzero? || 80 + columns = 80 unless columns&.nonzero? + w = COUNT_WIDTH + 1 + round = 20 + @columns = (columns - w) / round * round + w end @dotted = 0 @loaded = false @@ -113,7 +117,7 @@ class DottedFormatter def after(*) if @columns if @dotted == 0 - s = sprintf("%6d ", @count) + s = sprintf("%*d ", COUNT_WIDTH, @count) print(s) @dotted += s.size end diff --git a/spec/mspec/lib/mspec/guards/platform.rb b/spec/mspec/lib/mspec/guards/platform.rb index e87b08a4c1..03c0fca8f5 100644 --- a/spec/mspec/lib/mspec/guards/platform.rb +++ b/spec/mspec/lib/mspec/guards/platform.rb @@ -53,23 +53,27 @@ class PlatformGuard < SpecGuard end end - WORD_SIZE = 1.size * 8 - POINTER_SIZE = begin require 'rbconfig/sizeof' RbConfig::SIZEOF["void*"] * 8 rescue LoadError - WORD_SIZE + [0].pack('j').size end - def self.wordsize?(size) - size == WORD_SIZE + C_LONG_SIZE = if defined?(RbConfig::SIZEOF[]) + RbConfig::SIZEOF["long"] * 8 + else + [0].pack('l!').size end def self.pointer_size?(size) size == POINTER_SIZE end + def self.c_long_size?(size) + size == C_LONG_SIZE + end + def initialize(*args) if args.last.is_a?(Hash) @options, @platforms = args.last, args[0..-2] @@ -85,10 +89,10 @@ class PlatformGuard < SpecGuard case key when :os match &&= PlatformGuard.os?(*value) - when :wordsize - match &&= PlatformGuard.wordsize? value when :pointer_size match &&= PlatformGuard.pointer_size? value + when :c_long_size + match &&= PlatformGuard::c_long_size? value end end match diff --git a/spec/mspec/lib/mspec/helpers/numeric.rb b/spec/mspec/lib/mspec/helpers/numeric.rb index c1ed81a233..d877fc9296 100644 --- a/spec/mspec/lib/mspec/helpers/numeric.rb +++ b/spec/mspec/lib/mspec/helpers/numeric.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'mspec/guards/platform' def nan_value @@ -15,11 +16,13 @@ def bignum_value(plus = 0) end def max_long - 2**(0.size * 8 - 1) - 1 + long_byte_size = [0].pack('l!').size + 2**(long_byte_size * 8 - 1) - 1 end def min_long - -(2**(0.size * 8 - 1)) + long_byte_size = [0].pack('l!').size + -(2**(long_byte_size * 8 - 1)) end # This is a bit hairy, but we need to be able to write specs that cover the @@ -28,7 +31,24 @@ end # specs based on the relationship between values rather than specific # values. if PlatformGuard.standard? or PlatformGuard.implementation? :topaz - if PlatformGuard.wordsize? 32 + limits_available = begin + require 'rbconfig/sizeof' + defined?(RbConfig::LIMITS.[]) && ['FIXNUM_MAX', 'FIXNUM_MIN'].all? do |key| + Integer === RbConfig::LIMITS[key] + end + rescue LoadError + false + end + + if limits_available + def fixnum_max + RbConfig::LIMITS['FIXNUM_MAX'] + end + + def fixnum_min + RbConfig::LIMITS['FIXNUM_MIN'] + end + elsif PlatformGuard.c_long_size? 32 def fixnum_max (2**30) - 1 end @@ -36,7 +56,7 @@ if PlatformGuard.standard? or PlatformGuard.implementation? :topaz def fixnum_min -(2**30) end - elsif PlatformGuard.wordsize? 64 + elsif PlatformGuard.c_long_size? 64 def fixnum_max (2**62) - 1 end diff --git a/spec/mspec/lib/mspec/helpers/tmp.rb b/spec/mspec/lib/mspec/helpers/tmp.rb index 4c0eddab75..e903dd9f50 100644 --- a/spec/mspec/lib/mspec/helpers/tmp.rb +++ b/spec/mspec/lib/mspec/helpers/tmp.rb @@ -36,7 +36,20 @@ all specs are cleaning up temporary files: end def tmp(name, uniquify = true) - mkdir_p SPEC_TEMP_DIR unless Dir.exist? SPEC_TEMP_DIR + if Dir.exist? SPEC_TEMP_DIR + stat = File.stat(SPEC_TEMP_DIR) + if stat.world_writable? and !stat.sticky? + raise ArgumentError, "SPEC_TEMP_DIR (#{SPEC_TEMP_DIR}) is world writable but not sticky" + end + else + platform_is_not :windows do + umask = File.umask + if (umask & 0002) == 0 # o+w + raise ArgumentError, "File.umask #=> #{umask.to_s(8)} (world-writable)" + end + end + mkdir_p SPEC_TEMP_DIR + end if uniquify and !name.empty? slash = name.rindex "/" diff --git a/spec/mspec/lib/mspec/runner/actions/leakchecker.rb b/spec/mspec/lib/mspec/runner/actions/leakchecker.rb index 71797b9815..0a8c9c3252 100644 --- a/spec/mspec/lib/mspec/runner/actions/leakchecker.rb +++ b/spec/mspec/lib/mspec/runner/actions/leakchecker.rb @@ -132,14 +132,14 @@ class LeakChecker attr_accessor :count end - def new(data) + def new(...) LeakChecker::TempfileCounter.count += 1 - super(data) + super end } LeakChecker.const_set(:TempfileCounter, m) - class << Tempfile::Remover + class << Tempfile prepend LeakChecker::TempfileCounter end end diff --git a/spec/mspec/lib/mspec/runner/formatters/multi.rb b/spec/mspec/lib/mspec/runner/formatters/multi.rb index a723ae8eb9..fa1da3766b 100644 --- a/spec/mspec/lib/mspec/runner/formatters/multi.rb +++ b/spec/mspec/lib/mspec/runner/formatters/multi.rb @@ -42,6 +42,6 @@ module MultiFormatter end def print_exception(exc, count) - print "\n#{count})\n#{exc}\n" + @err.print "\n#{count})\n#{exc}\n" end end diff --git a/spec/mspec/spec/guards/platform_spec.rb b/spec/mspec/spec/guards/platform_spec.rb index 88a7ad86f2..bd37432800 100644 --- a/spec/mspec/spec/guards/platform_spec.rb +++ b/spec/mspec/spec/guards/platform_spec.rb @@ -81,44 +81,44 @@ RSpec.describe Object, "#platform_is_not" do end end -RSpec.describe Object, "#platform_is :wordsize => SIZE_SPEC" do +RSpec.describe Object, "#platform_is :c_long_size => SIZE_SPEC" do before :each do - @guard = PlatformGuard.new :darwin, :wordsize => 32 + @guard = PlatformGuard.new :darwin, :c_long_size => 32 allow(PlatformGuard).to receive(:os?).and_return(true) allow(PlatformGuard).to receive(:new).and_return(@guard) ScratchPad.clear end - it "yields when #wordsize? returns true" do - allow(PlatformGuard).to receive(:wordsize?).and_return(true) - platform_is(:wordsize => 32) { ScratchPad.record :yield } + it "yields when #c_long_size? returns true" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(true) + platform_is(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).to eq(:yield) end - it "doesn not yield when #wordsize? returns false" do - allow(PlatformGuard).to receive(:wordsize?).and_return(false) - platform_is(:wordsize => 32) { ScratchPad.record :yield } + it "doesn not yield when #c_long_size? returns false" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(false) + platform_is(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).not_to eq(:yield) end end -RSpec.describe Object, "#platform_is_not :wordsize => SIZE_SPEC" do +RSpec.describe Object, "#platform_is_not :c_long_size => SIZE_SPEC" do before :each do - @guard = PlatformGuard.new :darwin, :wordsize => 32 + @guard = PlatformGuard.new :darwin, :c_long_size => 32 allow(PlatformGuard).to receive(:os?).and_return(true) allow(PlatformGuard).to receive(:new).and_return(@guard) ScratchPad.clear end - it "yields when #wordsize? returns false" do - allow(PlatformGuard).to receive(:wordsize?).and_return(false) - platform_is_not(:wordsize => 32) { ScratchPad.record :yield } + it "yields when #c_long_size? returns false" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(false) + platform_is_not(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).to eq(:yield) end - it "doesn not yield when #wordsize? returns true" do - allow(PlatformGuard).to receive(:wordsize?).and_return(true) - platform_is_not(:wordsize => 32) { ScratchPad.record :yield } + it "doesn not yield when #c_long_size? returns true" do + allow(PlatformGuard).to receive(:c_long_size?).and_return(true) + platform_is_not(:c_long_size => 32) { ScratchPad.record :yield } expect(ScratchPad.recorded).not_to eq(:yield) end end @@ -184,13 +184,13 @@ RSpec.describe PlatformGuard, ".standard?" do end end -RSpec.describe PlatformGuard, ".wordsize?" do +RSpec.describe PlatformGuard, ".c_long_size?" do it "returns true when arg is 32 and 1.size is 4" do - expect(PlatformGuard.wordsize?(32)).to eq(1.size == 4) + expect(PlatformGuard.c_long_size?(32)).to eq(1.size == 4) end it "returns true when arg is 64 and 1.size is 8" do - expect(PlatformGuard.wordsize?(64)).to eq(1.size == 8) + expect(PlatformGuard.c_long_size?(64)).to eq(1.size == 8) end end diff --git a/spec/prism.mspec b/spec/prism.mspec deleted file mode 100644 index 3014b9788f..0000000000 --- a/spec/prism.mspec +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -# We are missing emitting some :end event inside eval; we need more -# investigation here. -MSpec.register(:exclude, "TracePoint#path equals \"(eval at __FILE__:__LINE__)\" inside an eval for :end event") - -# We need to respect the eval coverage setting. -MSpec.register(:exclude, "Coverage.result returns the correct results when eval coverage is disabled") diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml index be32ce8900..5a902e0f01 100644 --- a/spec/ruby/.rubocop.yml +++ b/spec/ruby/.rubocop.yml @@ -1,7 +1,7 @@ inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 3.0 + TargetRubyVersion: 3.1 DisplayCopNames: true Exclude: - command_line/fixtures/bad_syntax.rb diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md index c82eb5ea4f..e9314208d1 100644 --- a/spec/ruby/CONTRIBUTING.md +++ b/spec/ruby/CONTRIBUTING.md @@ -164,7 +164,7 @@ end platform_is_not :linux, :darwin do # Not Linux and not Darwin end -platform_is wordsize: 64 do +platform_is pointer_size: 64 do # 64-bit platform end @@ -277,13 +277,13 @@ describe :kernel_sprintf, shared: true do end describe "Kernel#sprintf" do - it_behaves_like :kernel_sprintf, -> (format, *args) { + it_behaves_like :kernel_sprintf, -> format, *args { sprintf(format, *args) } end describe "Kernel.sprintf" do - it_behaves_like :kernel_sprintf, -> (format, *args) { + it_behaves_like :kernel_sprintf, -> format, *args { Kernel.sprintf(format, *args) } end diff --git a/spec/ruby/README.md b/spec/ruby/README.md index 115392835f..964efbec48 100644 --- a/spec/ruby/README.md +++ b/spec/ruby/README.md @@ -35,7 +35,7 @@ More precisely, every latest stable MRI release should [pass](https://github.com ### Synchronization with Ruby Implementations -The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby, +The specs are synchronized both ways around once a month by @andrykonchin between ruby/spec, MRI, JRuby and TruffleRuby, using [this script](https://github.com/ruby/mspec/blob/master/tool/sync/sync-rubyspec.rb). Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs. Any of these repositories can be used to add or edit specs, use what is most convenient for you. diff --git a/spec/ruby/command_line/frozen_strings_spec.rb b/spec/ruby/command_line/frozen_strings_spec.rb index 334b98273b..06889755d2 100644 --- a/spec/ruby/command_line/frozen_strings_spec.rb +++ b/spec/ruby/command_line/frozen_strings_spec.rb @@ -42,16 +42,8 @@ describe "With neither --enable-frozen-string-literal nor --disable-frozen-strin ruby_exe(fixture(__FILE__, "freeze_flag_one_literal.rb")).chomp.should == "false" end - ruby_version_is "3.4" do - it "if file has no frozen_string_literal comment produce different frozen strings each time" do - ruby_exe(fixture(__FILE__, "string_literal_raw.rb")).chomp.should == "frozen:true interned:false" - end - end - - ruby_version_is ""..."3.4" do - it "if file has no frozen_string_literal comment produce different mutable strings each time" do - ruby_exe(fixture(__FILE__, "string_literal_raw.rb")).chomp.should == "frozen:false interned:false" - end + it "if file has no frozen_string_literal comment produce different mutable strings each time" do + ruby_exe(fixture(__FILE__, "string_literal_raw.rb")).chomp.should == "frozen:false interned:false" end it "if file has frozen_string_literal:true comment produce same frozen strings each time" do diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb index 57d6082f01..f4b5b758d0 100644 --- a/spec/ruby/core/array/each_spec.rb +++ b/spec/ruby/core/array/each_spec.rb @@ -7,7 +7,7 @@ require_relative '../enumerable/shared/enumeratorized' # Mutating the array while it is being iterated is discouraged as it can result in confusing behavior. # Yet a Ruby implementation must not crash in such a case, and following the simple CRuby behavior makes sense. # CRuby simply reads the array storage and checks the size for every iteration; -# like `i = 0; while i < size; yield self[i]; end` +# like `i = 0; while i < size; yield self[i]; i += 1; end` describe "Array#each" do it "yields each element to the block" do diff --git a/spec/ruby/core/array/fetch_values_spec.rb b/spec/ruby/core/array/fetch_values_spec.rb new file mode 100644 index 0000000000..559b6c2b2f --- /dev/null +++ b/spec/ruby/core/array/fetch_values_spec.rb @@ -0,0 +1,48 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Array#fetch_values" do + before :each do + @array = [:a, :b, :c] + end + + ruby_version_is "3.4" do + describe "with matched indexes" do + it "returns the values for indexes" do + @array.fetch_values(0).should == [:a] + @array.fetch_values(0, 2).should == [:a, :c] + end + + it "returns the values for indexes ordered in the order of the requested indexes" do + @array.fetch_values(2, 0).should == [:c, :a] + end + end + + describe "with unmatched indexes" do + it "raises a index error if no block is provided" do + -> { @array.fetch_values(0, 1, 44) }.should raise_error(IndexError) + end + + it "returns the default value from block" do + @array.fetch_values(44) { |index| "`#{index}' is not found" }.should == ["`44' is not found"] + @array.fetch_values(0, 44) { |index| "`#{index}' is not found" }.should == [:a, "`44' is not found"] + end + end + + describe "without keys" do + it "returns an empty Array" do + @array.fetch_values.should == [] + end + end + + it "tries to convert the passed argument to an Integer using #to_int" do + obj = mock('to_int') + obj.should_receive(:to_int).and_return(2) + @array.fetch_values(obj).should == [:c] + end + + it "raises a TypeError when the passed argument can't be coerced to Integer" do + -> { [].fetch_values("cat") }.should raise_error(TypeError) + end + end +end diff --git a/spec/ruby/core/array/fixtures/classes.rb b/spec/ruby/core/array/fixtures/classes.rb index 8596245fb8..05283c0f74 100644 --- a/spec/ruby/core/array/fixtures/classes.rb +++ b/spec/ruby/core/array/fixtures/classes.rb @@ -56,23 +56,20 @@ module ArraySpecs 101.621, 102.816, 104.010, 105.202, 106.393, 107.583, 108.771, 109.958, 111.144, 112.329, 113.512, 114.695, 115.876, 117.057, 118.236, 119.414, 120.591, 121.767, 122.942, 124.116, 125.289, 126.462, 127.633, 128.803, 129.973, 131.141, 132.309, 133.476, 134.642, 135.807, - ] + ] def self.measure_sample_fairness(size, samples, iters) ary = Array.new(size) { |x| x } + expected = iters.fdiv size (samples).times do |i| chi_results = [] 3.times do - counts = Array.new(size) { 0 } - expected = iters / size + counts = Array.new(size, 0) iters.times do x = ary.sample(samples)[i] counts[x] += 1 end - chi_squared = 0.0 - counts.each do |count| - chi_squared += (((count - expected) ** 2) * 1.0 / expected) - end + chi_squared = counts.sum {|count| (count - expected) ** 2} / expected chi_results << chi_squared break if chi_squared <= CHI_SQUARED_CRITICAL_VALUES[size] end @@ -83,17 +80,14 @@ module ArraySpecs def self.measure_sample_fairness_large_sample_size(size, samples, iters) ary = Array.new(size) { |x| x } - counts = Array.new(size) { 0 } - expected = iters * samples / size + counts = Array.new(size, 0) + expected = (iters * samples).fdiv size iters.times do ary.sample(samples).each do |sample| counts[sample] += 1 end end - chi_squared = 0.0 - counts.each do |count| - chi_squared += (((count - expected) ** 2) * 1.0 / expected) - end + chi_squared = counts.sum {|count| (count - expected) ** 2} / expected # Chi squared critical values for tests with 4 degrees of freedom # Values obtained from NIST Engineering Statistic Handbook at @@ -223,366 +217,370 @@ module ArraySpecs obj end - LargeArray = ["test_create_table_with_force_true_does_not_drop_nonexisting_table", - "test_add_table", - "assert_difference", - "assert_operator", - "instance_variables", - "class", - "instance_variable_get", - "__class__", - "expects", - "assert_no_difference", - "name", - "assert_blank", - "assert_not_same", - "is_a?", - "test_add_table_with_decimals", - "test_create_table_with_timestamps_should_create_datetime_columns", - "assert_present", - "assert_no_match", - "__instance_of__", - "assert_deprecated", - "assert", - "assert_throws", - "kind_of?", - "try", - "__instance_variable_get__", - "object_id", - "timeout", - "instance_variable_set", - "assert_nothing_thrown", - "__instance_variable_set__", - "copy_object", - "test_create_table_with_timestamps_should_create_datetime_columns_with_options", - "assert_not_deprecated", - "assert_in_delta", - "id", - "copy_metaclass", - "test_create_table_without_a_block", - "dup", - "assert_not_nil", - "send", - "__instance_variables__", - "to_sql", - "mock", - "assert_send", - "instance_variable_defined?", - "clone", - "require", - "test_migrator", - "__instance_variable_defined_eh__", - "frozen?", - "test_add_column_not_null_with_default", - "freeze", - "test_migrator_one_up", - "test_migrator_one_down", - "singleton_methods", - "method_exists?", - "create_fixtures", - "test_migrator_one_up_one_down", - "test_native_decimal_insert_manual_vs_automatic", - "instance_exec", - "__is_a__", - "test_migrator_double_up", - "stub", - "private_methods", - "stubs", - "test_migrator_double_down", - "fixture_path", - "private_singleton_methods", - "stub_everything", - "test_migrator_one_up_with_exception_and_rollback", - "sequence", - "protected_methods", - "enum_for", - "test_finds_migrations", - "run_before_mocha", - "states", - "protected_singleton_methods", - "to_json", - "instance_values", - "==", - "mocha_setup", - "public_methods", - "test_finds_pending_migrations", - "mocha_verify", - "assert_kind_of", - "===", - "=~", - "test_relative_migrations", - "mocha_teardown", - "gem", - "mocha", - "test_only_loads_pending_migrations", - "test_add_column_with_precision_and_scale", - "require_or_load", - "eql?", - "require_dependency", - "test_native_types", - "test_target_version_zero_should_run_only_once", - "extend", - "to_matcher", - "unloadable", - "require_association", - "hash", - "__id__", - "load_dependency", - "equals", - "test_migrator_db_has_no_schema_migrations_table", - "test_migrator_verbosity", - "kind_of", - "to_yaml", - "to_bool", - "test_migrator_verbosity_off", - "taint", - "test_migrator_going_down_due_to_version_target", - "tainted?", - "mocha_inspect", - "test_migrator_rollback", - "vim", - "untaint", - "taguri=", - "test_migrator_forward", - "test_schema_migrations_table_name", - "test_proper_table_name", - "all_of", - "test_add_drop_table_with_prefix_and_suffix", - "_setup_callbacks", - "setup", - "Not", - "test_create_table_with_binary_column", - "assert_not_equal", - "enable_warnings", - "acts_like?", - "Rational", - "_removed_setup_callbacks", - "Table", - "bind", - "any_of", - "__method__", - "test_migrator_with_duplicates", - "_teardown_callbacks", - "method", - "test_migrator_with_duplicate_names", - "_removed_teardown_callbacks", - "any_parameters", - "test_migrator_with_missing_version_numbers", - "test_add_remove_single_field_using_string_arguments", - "test_create_table_with_custom_sequence_name", - "test_add_remove_single_field_using_symbol_arguments", - "_one_time_conditions_valid_14?", - "_one_time_conditions_valid_16?", - "run_callbacks", - "anything", - "silence_warnings", - "instance_variable_names", - "_fixture_path", - "copy_instance_variables_from", - "fixture_path?", - "has_entry", - "__marshal__", - "_fixture_table_names", - "__kind_of__", - "fixture_table_names?", - "test_add_rename", - "assert_equal", - "_fixture_class_names", - "fixture_class_names?", - "has_entries", - "_use_transactional_fixtures", - "people", - "test_rename_column_using_symbol_arguments", - "use_transactional_fixtures?", - "instance_eval", - "blank?", - "with_warnings", - "__nil__", - "load", - "metaclass", - "_use_instantiated_fixtures", - "has_key", - "class_eval", - "present?", - "test_rename_column", - "teardown", - "use_instantiated_fixtures?", - "method_name", - "silence_stderr", - "presence", - "test_rename_column_preserves_default_value_not_null", - "silence_stream", - "_pre_loaded_fixtures", - "__metaclass__", - "__fixnum__", - "pre_loaded_fixtures?", - "has_value", - "suppress", - "to_yaml_properties", - "test_rename_nonexistent_column", - "test_add_index", - "includes", - "find_correlate_in", - "equality_predicate_sql", - "assert_nothing_raised", - "let", - "not_predicate_sql", - "test_rename_column_with_sql_reserved_word", - "singleton_class", - "test_rename_column_with_an_index", - "display", - "taguri", - "to_yaml_style", - "test_remove_column_with_index", - "size", - "current_adapter?", - "test_remove_column_with_multi_column_index", - "respond_to?", - "test_change_type_of_not_null_column", - "is_a", - "to_a", - "test_rename_table_for_sqlite_should_work_with_reserved_words", - "require_library_or_gem", - "setup_fixtures", - "equal?", - "teardown_fixtures", - "nil?", - "fixture_table_names", - "fixture_class_names", - "test_create_table_without_id", - "use_transactional_fixtures", - "test_add_column_with_primary_key_attribute", - "repair_validations", - "use_instantiated_fixtures", - "instance_of?", - "test_create_table_adds_id", - "test_rename_table", - "pre_loaded_fixtures", - "to_enum", - "test_create_table_with_not_null_column", - "instance_of", - "test_change_column_nullability", - "optionally", - "test_rename_table_with_an_index", - "run", - "test_change_column", - "default_test", - "assert_raise", - "test_create_table_with_defaults", - "assert_nil", - "flunk", - "regexp_matches", - "duplicable?", - "reset_mocha", - "stubba_method", - "filter_backtrace", - "test_create_table_with_limits", - "responds_with", - "stubba_object", - "test_change_column_with_nil_default", - "assert_block", - "__show__", - "assert_date_from_db", - "__respond_to_eh__", - "run_in_transaction?", - "inspect", - "assert_sql", - "test_change_column_with_new_default", - "yaml_equivalent", - "build_message", - "to_s", - "test_change_column_default", - "assert_queries", - "pending", - "as_json", - "assert_no_queries", - "test_change_column_quotes_column_names", - "assert_match", - "test_keeping_default_and_notnull_constraint_on_change", - "methods", - "connection_allow_concurrency_setup", - "connection_allow_concurrency_teardown", - "test_create_table_with_primary_key_prefix_as_table_name_with_underscore", - "__send__", - "make_connection", - "assert_raises", - "tap", - "with_kcode", - "assert_instance_of", - "test_create_table_with_primary_key_prefix_as_table_name", - "assert_respond_to", - "test_change_column_default_to_null", - "assert_same", - "__extend__"] - - LargeTestArraySorted = ["test_add_column_not_null_with_default", - "test_add_column_with_precision_and_scale", - "test_add_column_with_primary_key_attribute", - "test_add_drop_table_with_prefix_and_suffix", - "test_add_index", - "test_add_remove_single_field_using_string_arguments", - "test_add_remove_single_field_using_symbol_arguments", - "test_add_rename", - "test_add_table", - "test_add_table_with_decimals", - "test_change_column", - "test_change_column_default", - "test_change_column_default_to_null", - "test_change_column_nullability", - "test_change_column_quotes_column_names", - "test_change_column_with_new_default", - "test_change_column_with_nil_default", - "test_change_type_of_not_null_column", - "test_create_table_adds_id", - "test_create_table_with_binary_column", - "test_create_table_with_custom_sequence_name", - "test_create_table_with_defaults", - "test_create_table_with_force_true_does_not_drop_nonexisting_table", - "test_create_table_with_limits", - "test_create_table_with_not_null_column", - "test_create_table_with_primary_key_prefix_as_table_name", - "test_create_table_with_primary_key_prefix_as_table_name_with_underscore", - "test_create_table_with_timestamps_should_create_datetime_columns", - "test_create_table_with_timestamps_should_create_datetime_columns_with_options", - "test_create_table_without_a_block", - "test_create_table_without_id", - "test_finds_migrations", - "test_finds_pending_migrations", - "test_keeping_default_and_notnull_constraint_on_change", - "test_migrator", - "test_migrator_db_has_no_schema_migrations_table", - "test_migrator_double_down", - "test_migrator_double_up", - "test_migrator_forward", - "test_migrator_going_down_due_to_version_target", - "test_migrator_one_down", - "test_migrator_one_up", - "test_migrator_one_up_one_down", - "test_migrator_one_up_with_exception_and_rollback", - "test_migrator_rollback", - "test_migrator_verbosity", - "test_migrator_verbosity_off", - "test_migrator_with_duplicate_names", - "test_migrator_with_duplicates", - "test_migrator_with_missing_version_numbers", - "test_native_decimal_insert_manual_vs_automatic", - "test_native_types", - "test_only_loads_pending_migrations", - "test_proper_table_name", - "test_relative_migrations", - "test_remove_column_with_index", - "test_remove_column_with_multi_column_index", - "test_rename_column", - "test_rename_column_preserves_default_value_not_null", - "test_rename_column_using_symbol_arguments", - "test_rename_column_with_an_index", - "test_rename_column_with_sql_reserved_word", - "test_rename_nonexistent_column", - "test_rename_table", - "test_rename_table_for_sqlite_should_work_with_reserved_words", - "test_rename_table_with_an_index", - "test_schema_migrations_table_name", - "test_target_version_zero_should_run_only_once"] + LargeArray = [ + "test_create_table_with_force_true_does_not_drop_nonexisting_table", + "test_add_table", + "assert_difference", + "assert_operator", + "instance_variables", + "class", + "instance_variable_get", + "__class__", + "expects", + "assert_no_difference", + "name", + "assert_blank", + "assert_not_same", + "is_a?", + "test_add_table_with_decimals", + "test_create_table_with_timestamps_should_create_datetime_columns", + "assert_present", + "assert_no_match", + "__instance_of__", + "assert_deprecated", + "assert", + "assert_throws", + "kind_of?", + "try", + "__instance_variable_get__", + "object_id", + "timeout", + "instance_variable_set", + "assert_nothing_thrown", + "__instance_variable_set__", + "copy_object", + "test_create_table_with_timestamps_should_create_datetime_columns_with_options", + "assert_not_deprecated", + "assert_in_delta", + "id", + "copy_metaclass", + "test_create_table_without_a_block", + "dup", + "assert_not_nil", + "send", + "__instance_variables__", + "to_sql", + "mock", + "assert_send", + "instance_variable_defined?", + "clone", + "require", + "test_migrator", + "__instance_variable_defined_eh__", + "frozen?", + "test_add_column_not_null_with_default", + "freeze", + "test_migrator_one_up", + "test_migrator_one_down", + "singleton_methods", + "method_exists?", + "create_fixtures", + "test_migrator_one_up_one_down", + "test_native_decimal_insert_manual_vs_automatic", + "instance_exec", + "__is_a__", + "test_migrator_double_up", + "stub", + "private_methods", + "stubs", + "test_migrator_double_down", + "fixture_path", + "private_singleton_methods", + "stub_everything", + "test_migrator_one_up_with_exception_and_rollback", + "sequence", + "protected_methods", + "enum_for", + "test_finds_migrations", + "run_before_mocha", + "states", + "protected_singleton_methods", + "to_json", + "instance_values", + "==", + "mocha_setup", + "public_methods", + "test_finds_pending_migrations", + "mocha_verify", + "assert_kind_of", + "===", + "=~", + "test_relative_migrations", + "mocha_teardown", + "gem", + "mocha", + "test_only_loads_pending_migrations", + "test_add_column_with_precision_and_scale", + "require_or_load", + "eql?", + "require_dependency", + "test_native_types", + "test_target_version_zero_should_run_only_once", + "extend", + "to_matcher", + "unloadable", + "require_association", + "hash", + "__id__", + "load_dependency", + "equals", + "test_migrator_db_has_no_schema_migrations_table", + "test_migrator_verbosity", + "kind_of", + "to_yaml", + "to_bool", + "test_migrator_verbosity_off", + "taint", + "test_migrator_going_down_due_to_version_target", + "tainted?", + "mocha_inspect", + "test_migrator_rollback", + "vim", + "untaint", + "taguri=", + "test_migrator_forward", + "test_schema_migrations_table_name", + "test_proper_table_name", + "all_of", + "test_add_drop_table_with_prefix_and_suffix", + "_setup_callbacks", + "setup", + "Not", + "test_create_table_with_binary_column", + "assert_not_equal", + "enable_warnings", + "acts_like?", + "Rational", + "_removed_setup_callbacks", + "Table", + "bind", + "any_of", + "__method__", + "test_migrator_with_duplicates", + "_teardown_callbacks", + "method", + "test_migrator_with_duplicate_names", + "_removed_teardown_callbacks", + "any_parameters", + "test_migrator_with_missing_version_numbers", + "test_add_remove_single_field_using_string_arguments", + "test_create_table_with_custom_sequence_name", + "test_add_remove_single_field_using_symbol_arguments", + "_one_time_conditions_valid_14?", + "_one_time_conditions_valid_16?", + "run_callbacks", + "anything", + "silence_warnings", + "instance_variable_names", + "_fixture_path", + "copy_instance_variables_from", + "fixture_path?", + "has_entry", + "__marshal__", + "_fixture_table_names", + "__kind_of__", + "fixture_table_names?", + "test_add_rename", + "assert_equal", + "_fixture_class_names", + "fixture_class_names?", + "has_entries", + "_use_transactional_fixtures", + "people", + "test_rename_column_using_symbol_arguments", + "use_transactional_fixtures?", + "instance_eval", + "blank?", + "with_warnings", + "__nil__", + "load", + "metaclass", + "_use_instantiated_fixtures", + "has_key", + "class_eval", + "present?", + "test_rename_column", + "teardown", + "use_instantiated_fixtures?", + "method_name", + "silence_stderr", + "presence", + "test_rename_column_preserves_default_value_not_null", + "silence_stream", + "_pre_loaded_fixtures", + "__metaclass__", + "__fixnum__", + "pre_loaded_fixtures?", + "has_value", + "suppress", + "to_yaml_properties", + "test_rename_nonexistent_column", + "test_add_index", + "includes", + "find_correlate_in", + "equality_predicate_sql", + "assert_nothing_raised", + "let", + "not_predicate_sql", + "test_rename_column_with_sql_reserved_word", + "singleton_class", + "test_rename_column_with_an_index", + "display", + "taguri", + "to_yaml_style", + "test_remove_column_with_index", + "size", + "current_adapter?", + "test_remove_column_with_multi_column_index", + "respond_to?", + "test_change_type_of_not_null_column", + "is_a", + "to_a", + "test_rename_table_for_sqlite_should_work_with_reserved_words", + "require_library_or_gem", + "setup_fixtures", + "equal?", + "teardown_fixtures", + "nil?", + "fixture_table_names", + "fixture_class_names", + "test_create_table_without_id", + "use_transactional_fixtures", + "test_add_column_with_primary_key_attribute", + "repair_validations", + "use_instantiated_fixtures", + "instance_of?", + "test_create_table_adds_id", + "test_rename_table", + "pre_loaded_fixtures", + "to_enum", + "test_create_table_with_not_null_column", + "instance_of", + "test_change_column_nullability", + "optionally", + "test_rename_table_with_an_index", + "run", + "test_change_column", + "default_test", + "assert_raise", + "test_create_table_with_defaults", + "assert_nil", + "flunk", + "regexp_matches", + "duplicable?", + "reset_mocha", + "stubba_method", + "filter_backtrace", + "test_create_table_with_limits", + "responds_with", + "stubba_object", + "test_change_column_with_nil_default", + "assert_block", + "__show__", + "assert_date_from_db", + "__respond_to_eh__", + "run_in_transaction?", + "inspect", + "assert_sql", + "test_change_column_with_new_default", + "yaml_equivalent", + "build_message", + "to_s", + "test_change_column_default", + "assert_queries", + "pending", + "as_json", + "assert_no_queries", + "test_change_column_quotes_column_names", + "assert_match", + "test_keeping_default_and_notnull_constraint_on_change", + "methods", + "connection_allow_concurrency_setup", + "connection_allow_concurrency_teardown", + "test_create_table_with_primary_key_prefix_as_table_name_with_underscore", + "__send__", + "make_connection", + "assert_raises", + "tap", + "with_kcode", + "assert_instance_of", + "test_create_table_with_primary_key_prefix_as_table_name", + "assert_respond_to", + "test_change_column_default_to_null", + "assert_same", + "__extend__", + ] + + LargeTestArraySorted = [ + "test_add_column_not_null_with_default", + "test_add_column_with_precision_and_scale", + "test_add_column_with_primary_key_attribute", + "test_add_drop_table_with_prefix_and_suffix", + "test_add_index", + "test_add_remove_single_field_using_string_arguments", + "test_add_remove_single_field_using_symbol_arguments", + "test_add_rename", + "test_add_table", + "test_add_table_with_decimals", + "test_change_column", + "test_change_column_default", + "test_change_column_default_to_null", + "test_change_column_nullability", + "test_change_column_quotes_column_names", + "test_change_column_with_new_default", + "test_change_column_with_nil_default", + "test_change_type_of_not_null_column", + "test_create_table_adds_id", + "test_create_table_with_binary_column", + "test_create_table_with_custom_sequence_name", + "test_create_table_with_defaults", + "test_create_table_with_force_true_does_not_drop_nonexisting_table", + "test_create_table_with_limits", + "test_create_table_with_not_null_column", + "test_create_table_with_primary_key_prefix_as_table_name", + "test_create_table_with_primary_key_prefix_as_table_name_with_underscore", + "test_create_table_with_timestamps_should_create_datetime_columns", + "test_create_table_with_timestamps_should_create_datetime_columns_with_options", + "test_create_table_without_a_block", + "test_create_table_without_id", + "test_finds_migrations", + "test_finds_pending_migrations", + "test_keeping_default_and_notnull_constraint_on_change", + "test_migrator", + "test_migrator_db_has_no_schema_migrations_table", + "test_migrator_double_down", + "test_migrator_double_up", + "test_migrator_forward", + "test_migrator_going_down_due_to_version_target", + "test_migrator_one_down", + "test_migrator_one_up", + "test_migrator_one_up_one_down", + "test_migrator_one_up_with_exception_and_rollback", + "test_migrator_rollback", + "test_migrator_verbosity", + "test_migrator_verbosity_off", + "test_migrator_with_duplicate_names", + "test_migrator_with_duplicates", + "test_migrator_with_missing_version_numbers", + "test_native_decimal_insert_manual_vs_automatic", + "test_native_types", + "test_only_loads_pending_migrations", + "test_proper_table_name", + "test_relative_migrations", + "test_remove_column_with_index", + "test_remove_column_with_multi_column_index", + "test_rename_column", + "test_rename_column_preserves_default_value_not_null", + "test_rename_column_using_symbol_arguments", + "test_rename_column_with_an_index", + "test_rename_column_with_sql_reserved_word", + "test_rename_nonexistent_column", + "test_rename_table", + "test_rename_table_for_sqlite_should_work_with_reserved_words", + "test_rename_table_with_an_index", + "test_schema_migrations_table_name", + "test_target_version_zero_should_run_only_once", + ] class PrivateToAry private diff --git a/spec/ruby/core/array/pack/buffer_spec.rb b/spec/ruby/core/array/pack/buffer_spec.rb index f1206efb3e..b77b2d1efa 100644 --- a/spec/ruby/core/array/pack/buffer_spec.rb +++ b/spec/ruby/core/array/pack/buffer_spec.rb @@ -28,6 +28,16 @@ describe "Array#pack with :buffer option" do TypeError, "buffer must be String, not Array") end + it "raise FrozenError if buffer is frozen" do + -> { [65].pack("c", buffer: "frozen-string".freeze) }.should raise_error(FrozenError) + end + + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + [65, 66, 67].pack("ccc", buffer: buffer) + buffer.encoding.should == Encoding::ISO_8859_1 + end + context "offset (@) is specified" do it 'keeps buffer content if it is longer than offset' do n = [ 65, 66, 67 ] diff --git a/spec/ruby/core/array/pack/l_spec.rb b/spec/ruby/core/array/pack/l_spec.rb index b446a7a36a..f6dfb1da83 100644 --- a/spec/ruby/core/array/pack/l_spec.rb +++ b/spec/ruby/core/array/pack/l_spec.rb @@ -29,7 +29,7 @@ describe "Array#pack with format 'L'" do it_behaves_like :array_pack_32bit_be, 'L>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_32bit_le, 'L<_' it_behaves_like :array_pack_32bit_le, 'L_<' @@ -51,7 +51,7 @@ describe "Array#pack with format 'L'" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_64bit_le, 'L<_' it_behaves_like :array_pack_64bit_le, 'L_<' @@ -83,7 +83,7 @@ describe "Array#pack with format 'l'" do it_behaves_like :array_pack_32bit_be, 'l>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_32bit_le, 'l<_' it_behaves_like :array_pack_32bit_le, 'l_<' @@ -105,7 +105,7 @@ describe "Array#pack with format 'l'" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :array_pack_64bit_le, 'l<_' it_behaves_like :array_pack_64bit_le, 'l_<' @@ -137,7 +137,7 @@ little_endian do it_behaves_like :array_pack_32bit_le, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_32bit_le, 'L_' end @@ -155,7 +155,7 @@ little_endian do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_64bit_le, 'L_' end @@ -183,7 +183,7 @@ big_endian do it_behaves_like :array_pack_32bit_be, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_32bit_be, 'L_' end @@ -201,7 +201,7 @@ big_endian do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "Array#pack with format 'L' with modifier '_'" do it_behaves_like :array_pack_64bit_be, 'L_' end diff --git a/spec/ruby/core/array/pack/shared/integer.rb b/spec/ruby/core/array/pack/shared/integer.rb index fd21b25b19..a89b5b733b 100644 --- a/spec/ruby/core/array/pack/shared/integer.rb +++ b/spec/ruby/core/array/pack/shared/integer.rb @@ -273,7 +273,7 @@ describe :array_pack_32bit_le_platform, shared: true do str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78" end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "encodes the least significant 32 bits of a number that is greater than 32 bits" do [ [[0xff_7865_4321], "\x21\x43\x65\x78"], [[-0xff_7865_4321], "\xdf\xbc\x9a\x87"] @@ -299,7 +299,7 @@ describe :array_pack_32bit_be_platform, shared: true do str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21" end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "encodes the least significant 32 bits of a number that is greater than 32 bits" do [ [[0xff_7865_4321], "\x78\x65\x43\x21"], [[-0xff_7865_4321], "\x87\x9a\xbc\xdf"] diff --git a/spec/ruby/core/array/plus_spec.rb b/spec/ruby/core/array/plus_spec.rb index 635bd131c9..b7153fd3ef 100644 --- a/spec/ruby/core/array/plus_spec.rb +++ b/spec/ruby/core/array/plus_spec.rb @@ -21,7 +21,7 @@ describe "Array#+" do ([1, 2, 3] + obj).should == [1, 2, 3, "x", "y"] end - it "raises a Typeerror if the given argument can't be converted to an array" do + it "raises a TypeError if the given argument can't be converted to an array" do -> { [1, 2, 3] + nil }.should raise_error(TypeError) -> { [1, 2, 3] + "abc" }.should raise_error(TypeError) end diff --git a/spec/ruby/core/array/to_h_spec.rb b/spec/ruby/core/array/to_h_spec.rb index f4578211a1..1c814f3d01 100644 --- a/spec/ruby/core/array/to_h_spec.rb +++ b/spec/ruby/core/array/to_h_spec.rb @@ -45,6 +45,12 @@ describe "Array#to_h" do [:a, :b].to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' } end + it "passes to a block each element as a single argument" do + ScratchPad.record [] + [[:a, 1], [:b, 2]].to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [[[:a, 1]], [[:b, 2]]] + end + it "raises ArgumentError if block returns longer or shorter array" do -> do [:a, :b].to_h { |k| [k, k.to_s, 1] } diff --git a/spec/ruby/core/binding/dup_spec.rb b/spec/ruby/core/binding/dup_spec.rb index 55fac6e333..4eff66bd9a 100644 --- a/spec/ruby/core/binding/dup_spec.rb +++ b/spec/ruby/core/binding/dup_spec.rb @@ -10,4 +10,21 @@ describe "Binding#dup" do bind.frozen?.should == true bind.dup.frozen?.should == false end + + it "retains original binding variables but the list is distinct" do + bind1 = binding + eval "a = 1", bind1 + + bind2 = bind1.dup + eval("a = 2", bind2) + eval("a", bind1).should == 2 + eval("a", bind2).should == 2 + + eval("b = 2", bind2) + -> { eval("b", bind1) }.should raise_error(NameError) + eval("b", bind2).should == 2 + + bind1.local_variables.sort.should == [:a, :bind1, :bind2] + bind2.local_variables.sort.should == [:a, :b, :bind1, :bind2] + end end diff --git a/spec/ruby/core/dir/chdir_spec.rb b/spec/ruby/core/dir/chdir_spec.rb index 729ac403e3..7ced2a7057 100644 --- a/spec/ruby/core/dir/chdir_spec.rb +++ b/spec/ruby/core/dir/chdir_spec.rb @@ -19,14 +19,14 @@ describe "Dir.chdir" do end it "defaults to $HOME with no arguments" do - if ENV['HOME'] - Dir.chdir - current_dir = Dir.pwd + skip "$HOME not valid directory" unless ENV['HOME'] && File.directory?(ENV['HOME']) - Dir.chdir(ENV['HOME']) - home = Dir.pwd - current_dir.should == home - end + Dir.chdir + current_dir = Dir.pwd + + Dir.chdir(ENV['HOME']) + home = Dir.pwd + current_dir.should == home end it "changes to the specified directory" do @@ -70,6 +70,8 @@ describe "Dir.chdir" do end it "defaults to the home directory when given a block but no argument" do + skip "$HOME not valid directory" unless ENV['HOME'] && File.directory?(ENV['HOME']) + # Windows will return a path with forward slashes for ENV["HOME"] so we have # to compare the route representations returned by Dir.chdir. current_dir = "" diff --git a/spec/ruby/core/dir/shared/exist.rb b/spec/ruby/core/dir/shared/exist.rb index 2ea4f88a80..3097f57715 100644 --- a/spec/ruby/core/dir/shared/exist.rb +++ b/spec/ruby/core/dir/shared/exist.rb @@ -34,6 +34,7 @@ describe :dir_exist, shared: true do end it "doesn't expand paths" do + skip "$HOME not valid directory" unless ENV['HOME'] && File.directory?(ENV['HOME']) Dir.send(@method, File.expand_path('~')).should be_true Dir.send(@method, '~').should be_false end diff --git a/spec/ruby/core/enumerable/shared/inject.rb b/spec/ruby/core/enumerable/shared/inject.rb index 693d34d675..92f220efa4 100644 --- a/spec/ruby/core/enumerable/shared/inject.rb +++ b/spec/ruby/core/enumerable/shared/inject.rb @@ -16,6 +16,23 @@ describe :enumerable_inject, shared: true do it "can take two argument" do EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, :-).should == 4 + EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, "-").should == 4 + + [1, 2, 3].send(@method, 10, :-).should == 4 + [1, 2, 3].send(@method, 10, "-").should == 4 + end + + it "converts non-Symbol method name argument to String with #to_str if two arguments" do + name = Object.new + def name.to_str; "-"; end + + EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, name).should == 4 + [1, 2, 3].send(@method, 10, name).should == 4 + end + + it "raises TypeError when the second argument is not Symbol or String and it cannot be converted to String if two arguments" do + -> { EnumerableSpecs::Numerous.new(1, 2, 3).send(@method, 10, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/) + -> { [1, 2, 3].send(@method, 10, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/) end it "ignores the block if two arguments" do @@ -39,6 +56,25 @@ describe :enumerable_inject, shared: true do it "can take a symbol argument" do EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, :-).should == 4 + [10, 1, 2, 3].send(@method, :-).should == 4 + end + + it "can take a String argument" do + EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, "-").should == 4 + [10, 1, 2, 3].send(@method, "-").should == 4 + end + + it "converts non-Symbol method name argument to String with #to_str" do + name = Object.new + def name.to_str; "-"; end + + EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, name).should == 4 + [10, 1, 2, 3].send(@method, name).should == 4 + end + + it "raises TypeError when passed not Symbol or String method name argument and it cannot be converted to String" do + -> { EnumerableSpecs::Numerous.new(10, 1, 2, 3).send(@method, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/) + -> { [10, 1, 2, 3].send(@method, Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/) end it "without argument takes a block with an accumulator (with first element as initial value) and the current element. Value of block becomes new accumulator" do @@ -77,7 +113,6 @@ describe :enumerable_inject, shared: true do EnumerableSpecs::EachDefiner.new('a','b','c').send(@method) {|result, i| i+result}.should == "cba" EnumerableSpecs::EachDefiner.new(3, 4, 5).send(@method) {|result, i| result*i}.should == 60 EnumerableSpecs::EachDefiner.new([1], 2, 'a','b').send(@method){|r,i| r<<i}.should == [1, 2, 'a', 'b'] - end it "returns nil when fails(legacy rubycon)" do diff --git a/spec/ruby/core/enumerable/to_h_spec.rb b/spec/ruby/core/enumerable/to_h_spec.rb index 0489134552..11a4933c10 100644 --- a/spec/ruby/core/enumerable/to_h_spec.rb +++ b/spec/ruby/core/enumerable/to_h_spec.rb @@ -53,6 +53,14 @@ describe "Enumerable#to_h" do @enum.to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' } end + it "passes to a block each element as a single argument" do + enum_of_arrays = EnumerableSpecs::EachDefiner.new([:a, 1], [:b, 2]) + + ScratchPad.record [] + enum_of_arrays.to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [[[:a, 1]], [[:b, 2]]] + end + it "raises ArgumentError if block returns longer or shorter array" do -> do @enum.to_h { |k| [k, k.to_s, 1] } diff --git a/spec/ruby/core/enumerator/next_values_spec.rb b/spec/ruby/core/enumerator/next_values_spec.rb index 201b5d323f..2202700c58 100644 --- a/spec/ruby/core/enumerator/next_values_spec.rb +++ b/spec/ruby/core/enumerator/next_values_spec.rb @@ -11,6 +11,7 @@ describe "Enumerator#next_values" do yield :e1, :e2, :e3 yield nil yield + yield [:f1, :f2] end @e = o.to_enum @@ -48,8 +49,13 @@ describe "Enumerator#next_values" do @e.next_values.should == [] end - it "raises StopIteration if called on a finished enumerator" do + it "returns an array of array if yield is called with an array" do 7.times { @e.next } + @e.next_values.should == [[:f1, :f2]] + end + + it "raises StopIteration if called on a finished enumerator" do + 8.times { @e.next } -> { @e.next_values }.should raise_error(StopIteration) end end diff --git a/spec/ruby/core/enumerator/peek_values_spec.rb b/spec/ruby/core/enumerator/peek_values_spec.rb index 7865546515..8b84fc8afc 100644 --- a/spec/ruby/core/enumerator/peek_values_spec.rb +++ b/spec/ruby/core/enumerator/peek_values_spec.rb @@ -11,6 +11,7 @@ describe "Enumerator#peek_values" do yield :e1, :e2, :e3 yield nil yield + yield [:f1, :f2] end @e = o.to_enum @@ -50,8 +51,13 @@ describe "Enumerator#peek_values" do @e.peek_values.should == [] end - it "raises StopIteration if called on a finished enumerator" do + it "returns an array of array if yield is called with an array" do 7.times { @e.next } + @e.peek_values.should == [[:f1, :f2]] + end + + it "raises StopIteration if called on a finished enumerator" do + 8.times { @e.next } -> { @e.peek_values }.should raise_error(StopIteration) end end diff --git a/spec/ruby/core/env/to_h_spec.rb b/spec/ruby/core/env/to_h_spec.rb index 3c4a92aa57..58ea2d2030 100644 --- a/spec/ruby/core/env/to_h_spec.rb +++ b/spec/ruby/core/env/to_h_spec.rb @@ -18,6 +18,18 @@ describe "ENV.to_h" do ENV.to_h { |k, v| [k, v.upcase] }.should == { 'a' => "B", 'c' => "D" } end + it "passes to a block each pair's key and value as separate arguments" do + ENV.replace("a" => "b", "c" => "d") + + ScratchPad.record [] + ENV.to_h { |k, v| ScratchPad << [k, v]; [k, v] } + ScratchPad.recorded.sort.should == [["a", "b"], ["c", "d"]] + + ScratchPad.record [] + ENV.to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [["a", "b"], ["c", "d"]] + end + it "does not require the array elements to be strings" do ENV.replace("a" => "b", "c" => "d") ENV.to_h { |k, v| [k.to_sym, v.to_sym] }.should == { :a => :b, :c => :d } diff --git a/spec/ruby/core/exception/detailed_message_spec.rb b/spec/ruby/core/exception/detailed_message_spec.rb index fbe4443daa..8178278b2b 100644 --- a/spec/ruby/core/exception/detailed_message_spec.rb +++ b/spec/ruby/core/exception/detailed_message_spec.rb @@ -15,14 +15,6 @@ describe "Exception#detailed_message" do exception.full_message(highlight: false).should.include? "<prefix>new error<suffix>" end - it "accepts highlight keyword argument and adds escape control sequences" do - RuntimeError.new("new error").detailed_message(highlight: true).should == "\e[1mnew error (\e[1;4mRuntimeError\e[m\e[1m)\e[m" - end - - it "allows and ignores other keyword arguments" do - RuntimeError.new("new error").detailed_message(foo: true).should == "new error (RuntimeError)" - end - it "returns just a message if exception class is anonymous" do Class.new(RuntimeError).new("message").detailed_message.should == "message" end @@ -31,13 +23,30 @@ describe "Exception#detailed_message" do RuntimeError.new("").detailed_message.should == "unhandled exception" end - it "returns just class name for an instance of RuntimeError subclass with empty message" do + it "returns just class name for an instance other than RuntimeError with empty message" do DetailedMessageSpec::C.new("").detailed_message.should == "DetailedMessageSpec::C" + StandardError.new("").detailed_message.should == "StandardError" end it "returns a generated class name for an instance of RuntimeError anonymous subclass with empty message" do klass = Class.new(RuntimeError) klass.new("").detailed_message.should =~ /\A#<Class:0x\h+>\z/ end + + it "accepts highlight keyword argument and adds escape control sequences" do + RuntimeError.new("new error").detailed_message(highlight: true).should == "\e[1mnew error (\e[1;4mRuntimeError\e[m\e[1m)\e[m" + end + + it "accepts highlight keyword argument and adds escape control sequences for an instance of RuntimeError with empty message" do + RuntimeError.new("").detailed_message(highlight: true).should == "\e[1;4munhandled exception\e[m" + end + + it "accepts highlight keyword argument and adds escape control sequences for an instance other than RuntimeError with empty message" do + StandardError.new("").detailed_message(highlight: true).should == "\e[1;4mStandardError\e[m" + end + + it "allows and ignores other keyword arguments" do + RuntimeError.new("new error").detailed_message(foo: true).should == "new error (RuntimeError)" + end end end diff --git a/spec/ruby/core/file/shared/update_time.rb b/spec/ruby/core/file/shared/update_time.rb index 9c063a8e93..3fe7266a00 100644 --- a/spec/ruby/core/file/shared/update_time.rb +++ b/spec/ruby/core/file/shared/update_time.rb @@ -84,7 +84,7 @@ describe :update_time, shared: true do end platform_is :linux do - platform_is wordsize: 64 do + platform_is pointer_size: 64 do it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19 or 2486-07-02)" do # https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Timestamps # "Therefore, timestamps should not overflow until May 2446." diff --git a/spec/ruby/core/hash/new_spec.rb b/spec/ruby/core/hash/new_spec.rb index 6279815fd6..5ae3e1f98d 100644 --- a/spec/ruby/core/hash/new_spec.rb +++ b/spec/ruby/core/hash/new_spec.rb @@ -34,7 +34,7 @@ describe "Hash.new" do -> { Hash.new(nil) { 0 } }.should raise_error(ArgumentError) end - ruby_version_is "3.3" do + ruby_version_is "3.3"..."3.4" do it "emits a deprecation warning if keyword arguments are passed" do -> { Hash.new(unknown: true) }.should complain( Regexp.new(Regexp.escape("Calling Hash.new with keyword arguments is deprecated and will be removed in Ruby 3.4; use Hash.new({ key: value }) instead")) @@ -46,4 +46,22 @@ describe "Hash.new" do Hash.new({ unknown: true }).default.should == { unknown: true } end end + + ruby_version_is "3.4" do + it "accepts a capacity: argument" do + Hash.new(5, capacity: 42).default.should == 5 + Hash.new(capacity: 42).default.should == nil + (Hash.new(capacity: 42) { 1 }).default_proc.should_not == nil + end + + it "ignores negative capacity" do + -> { Hash.new(capacity: -42) }.should_not raise_error + end + + it "raises an error if unknown keyword arguments are passed" do + -> { Hash.new(unknown: true) }.should raise_error(ArgumentError) + -> { Hash.new(1, unknown: true) }.should raise_error(ArgumentError) + -> { Hash.new(unknown: true) { 0 } }.should raise_error(ArgumentError) + end + end end diff --git a/spec/ruby/core/hash/replace_spec.rb b/spec/ruby/core/hash/replace_spec.rb index 92b2118fd3..a26a31f5f9 100644 --- a/spec/ruby/core/hash/replace_spec.rb +++ b/spec/ruby/core/hash/replace_spec.rb @@ -1,7 +1,70 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -require_relative 'shared/replace' describe "Hash#replace" do - it_behaves_like :hash_replace, :replace + it "replaces the contents of self with other" do + h = { a: 1, b: 2 } + h.replace(c: -1, d: -2).should equal(h) + h.should == { c: -1, d: -2 } + end + + it "tries to convert the passed argument to a hash using #to_hash" do + obj = mock('{1=>2,3=>4}') + obj.should_receive(:to_hash).and_return({ 1 => 2, 3 => 4 }) + + h = {} + h.replace(obj) + h.should == { 1 => 2, 3 => 4 } + end + + it "calls to_hash on hash subclasses" do + h = {} + h.replace(HashSpecs::ToHashHash[1 => 2]) + h.should == { 1 => 2 } + end + + it "transfers the compare_by_identity flag" do + hash_a = { a: 1 } + hash_b = { b: 2 } + hash_b.compare_by_identity + hash_a.should_not.compare_by_identity? + hash_a.replace(hash_b) + hash_a.should.compare_by_identity? + + hash_a = { a: 1 } + hash_b = { b: 2 } + hash_a.compare_by_identity + hash_a.should.compare_by_identity? + hash_a.replace(hash_b) + hash_a.should_not.compare_by_identity? + end + + it "does not transfer default values" do + hash_a = {} + hash_b = Hash.new(5) + hash_a.replace(hash_b) + hash_a.default.should == 5 + + hash_a = {} + hash_b = Hash.new { |h, k| k * 2 } + hash_a.replace(hash_b) + hash_a.default(5).should == 10 + + hash_a = Hash.new { |h, k| k * 5 } + hash_b = Hash.new(-> { raise "Should not invoke lambda" }) + hash_a.replace(hash_b) + hash_a.default.should == hash_b.default + end + + it "raises a FrozenError if called on a frozen instance that would not be modified" do + -> do + HashSpecs.frozen_hash.replace(HashSpecs.frozen_hash) + end.should raise_error(FrozenError) + end + + it "raises a FrozenError if called on a frozen instance that is modified" do + -> do + HashSpecs.frozen_hash.replace(HashSpecs.empty_frozen_hash) + end.should raise_error(FrozenError) + end end diff --git a/spec/ruby/core/hash/shared/replace.rb b/spec/ruby/core/hash/shared/replace.rb deleted file mode 100644 index bea64384bb..0000000000 --- a/spec/ruby/core/hash/shared/replace.rb +++ /dev/null @@ -1,51 +0,0 @@ -describe :hash_replace, shared: true do - it "replaces the contents of self with other" do - h = { a: 1, b: 2 } - h.send(@method, c: -1, d: -2).should equal(h) - h.should == { c: -1, d: -2 } - end - - it "tries to convert the passed argument to a hash using #to_hash" do - obj = mock('{1=>2,3=>4}') - obj.should_receive(:to_hash).and_return({ 1 => 2, 3 => 4 }) - - h = {} - h.send(@method, obj) - h.should == { 1 => 2, 3 => 4 } - end - - it "calls to_hash on hash subclasses" do - h = {} - h.send(@method, HashSpecs::ToHashHash[1 => 2]) - h.should == { 1 => 2 } - end - - it "does not transfer default values" do - hash_a = {} - hash_b = Hash.new(5) - hash_a.send(@method, hash_b) - hash_a.default.should == 5 - - hash_a = {} - hash_b = Hash.new { |h, k| k * 2 } - hash_a.send(@method, hash_b) - hash_a.default(5).should == 10 - - hash_a = Hash.new { |h, k| k * 5 } - hash_b = Hash.new(-> { raise "Should not invoke lambda" }) - hash_a.send(@method, hash_b) - hash_a.default.should == hash_b.default - end - - it "raises a FrozenError if called on a frozen instance that would not be modified" do - -> do - HashSpecs.frozen_hash.send(@method, HashSpecs.frozen_hash) - end.should raise_error(FrozenError) - end - - it "raises a FrozenError if called on a frozen instance that is modified" do - -> do - HashSpecs.frozen_hash.send(@method, HashSpecs.empty_frozen_hash) - end.should raise_error(FrozenError) - end -end diff --git a/spec/ruby/core/hash/to_h_spec.rb b/spec/ruby/core/hash/to_h_spec.rb index 75ebce68b1..e17ca7e671 100644 --- a/spec/ruby/core/hash/to_h_spec.rb +++ b/spec/ruby/core/hash/to_h_spec.rb @@ -37,6 +37,16 @@ describe "Hash#to_h" do { a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v]}.should == { "a" => 1, "b" => 4 } end + it "passes to a block each pair's key and value as separate arguments" do + ScratchPad.record [] + { a: 1, b: 2 }.to_h { |k, v| ScratchPad << [k, v]; [k, v] } + ScratchPad.recorded.sort.should == [[:a, 1], [:b, 2]] + + ScratchPad.record [] + { a: 1, b: 2 }.to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [[:a, 1], [:b, 2]] + end + it "raises ArgumentError if block returns longer or shorter array" do -> do { a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v, 1] } diff --git a/spec/ruby/core/integer/chr_spec.rb b/spec/ruby/core/integer/chr_spec.rb index 8fe20ff812..39cafe2874 100644 --- a/spec/ruby/core/integer/chr_spec.rb +++ b/spec/ruby/core/integer/chr_spec.rb @@ -10,12 +10,12 @@ describe "Integer#chr without argument" do end it "raises a RangeError is self is less than 0" do - -> { -1.chr }.should raise_error(RangeError) - -> { (-bignum_value).chr }.should raise_error(RangeError) + -> { -1.chr }.should raise_error(RangeError, /-1 out of char range/) + -> { (-bignum_value).chr }.should raise_error(RangeError, /bignum out of char range/) end it "raises a RangeError if self is too large" do - -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError) + -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError, /2206368128 out of char range/) end describe "when Encoding.default_internal is nil" do @@ -48,8 +48,8 @@ describe "Integer#chr without argument" do end it "raises a RangeError is self is greater than 255" do - -> { 256.chr }.should raise_error(RangeError) - -> { bignum_value.chr }.should raise_error(RangeError) + -> { 256.chr }.should raise_error(RangeError, /256 out of char range/) + -> { bignum_value.chr }.should raise_error(RangeError, /bignum out of char range/) end end @@ -137,7 +137,7 @@ describe "Integer#chr without argument" do [620, "TIS-620"] ].each do |integer, encoding_name| Encoding.default_internal = Encoding.find(encoding_name) - -> { integer.chr }.should raise_error(RangeError) + -> { integer.chr }.should raise_error(RangeError, /(invalid codepoint|out of char range)/) end end end @@ -165,12 +165,12 @@ describe "Integer#chr with an encoding argument" do # http://redmine.ruby-lang.org/issues/4869 it "raises a RangeError is self is less than 0" do - -> { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError) - -> { (-bignum_value).chr(Encoding::EUC_JP) }.should raise_error(RangeError) + -> { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError, /-1 out of char range/) + -> { (-bignum_value).chr(Encoding::EUC_JP) }.should raise_error(RangeError, /bignum out of char range/) end it "raises a RangeError if self is too large" do - -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError) + -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError, /2206368128 out of char range/) end it "returns a String with the specified encoding" do diff --git a/spec/ruby/core/integer/round_spec.rb b/spec/ruby/core/integer/round_spec.rb index 45ac126fd3..189384f11a 100644 --- a/spec/ruby/core/integer/round_spec.rb +++ b/spec/ruby/core/integer/round_spec.rb @@ -21,10 +21,8 @@ describe "Integer#round" do (-25 * 10**70).round(-71).should eql(-30 * 10**70) end - platform_is_not wordsize: 32 do - it "raises a RangeError when passed a big negative value" do - -> { 42.round(fixnum_min) }.should raise_error(RangeError) - end + it "raises a RangeError when passed a big negative value" do + -> { 42.round(min_long - 1) }.should raise_error(RangeError) end it "raises a RangeError when passed Float::INFINITY" do diff --git a/spec/ruby/core/integer/size_spec.rb b/spec/ruby/core/integer/size_spec.rb index a134e82384..725e9eb062 100644 --- a/spec/ruby/core/integer/size_spec.rb +++ b/spec/ruby/core/integer/size_spec.rb @@ -1,7 +1,7 @@ require_relative '../../spec_helper' describe "Integer#size" do - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "returns the number of bytes in the machine representation of self" do -1.size.should == 4 0.size.should == 4 @@ -9,7 +9,7 @@ describe "Integer#size" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "returns the number of bytes in the machine representation of self" do -1.size.should == 8 0.size.should == 8 diff --git a/spec/ruby/core/io/autoclose_spec.rb b/spec/ruby/core/io/autoclose_spec.rb new file mode 100644 index 0000000000..715ada7c93 --- /dev/null +++ b/spec/ruby/core/io/autoclose_spec.rb @@ -0,0 +1,77 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "IO#autoclose?" do + before :each do + @io = IOSpecs.io_fixture "lines.txt" + end + + after :each do + @io.autoclose = true unless @io.closed? + @io.close unless @io.closed? + end + + it "is set to true by default" do + @io.should.autoclose? + end + + it "cannot be queried on a closed IO object" do + @io.close + -> { @io.autoclose? }.should raise_error(IOError, /closed stream/) + end +end + +describe "IO#autoclose=" do + before :each do + @io = IOSpecs.io_fixture "lines.txt" + end + + after :each do + @io.autoclose = true unless @io.closed? + @io.close unless @io.closed? + end + + it "can be set to true" do + @io.autoclose = false + @io.autoclose = true + @io.should.autoclose? + end + + it "can be set to false" do + @io.autoclose = true + @io.autoclose = false + @io.should_not.autoclose? + end + + it "can be set to any truthy value" do + @io.autoclose = false + @io.autoclose = 42 + @io.should.autoclose? + + @io.autoclose = false + @io.autoclose = Object.new + @io.should.autoclose? + end + + it "can be set to any falsy value" do + @io.autoclose = true + @io.autoclose = nil + @io.should_not.autoclose? + end + + it "can be set multiple times" do + @io.autoclose = true + @io.should.autoclose? + + @io.autoclose = false + @io.should_not.autoclose? + + @io.autoclose = true + @io.should.autoclose? + end + + it "cannot be set on a closed IO object" do + @io.close + -> { @io.autoclose = false }.should raise_error(IOError, /closed stream/) + end +end diff --git a/spec/ruby/core/io/pread_spec.rb b/spec/ruby/core/io/pread_spec.rb index 28afc80e5c..6d93b432c2 100644 --- a/spec/ruby/core/io/pread_spec.rb +++ b/spec/ruby/core/io/pread_spec.rb @@ -22,7 +22,7 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do it "accepts a length, an offset, and an output buffer" do buffer = +"foo" - @file.pread(3, 4, buffer) + @file.pread(3, 4, buffer).should.equal?(buffer) buffer.should == "567" end @@ -38,6 +38,13 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do buffer.should == "12345" end + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + @file.pread(10, 0, buffer) + + buffer.encoding.should == Encoding::ISO_8859_1 + end + it "does not advance the file pointer" do @file.pread(4, 0).should == "1234" @file.read.should == "1234567890" diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb index eb3652e692..8741d9f017 100644 --- a/spec/ruby/core/io/read_spec.rb +++ b/spec/ruby/core/io/read_spec.rb @@ -376,6 +376,21 @@ describe "IO#read" do buf.should == @contents[0..4] end + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + @io.read(10, buffer) + + buffer.encoding.should == Encoding::ISO_8859_1 + end + + # https://bugs.ruby-lang.org/issues/20416 + it "does not preserve the encoding of the given buffer when max length is not provided" do + buffer = ''.encode(Encoding::ISO_8859_1) + @io.read(nil, buffer) + + buffer.encoding.should_not == Encoding::ISO_8859_1 + end + it "returns the given buffer" do buf = +"" diff --git a/spec/ruby/core/io/readpartial_spec.rb b/spec/ruby/core/io/readpartial_spec.rb index 0060beb545..0852f20b2d 100644 --- a/spec/ruby/core/io/readpartial_spec.rb +++ b/spec/ruby/core/io/readpartial_spec.rb @@ -62,7 +62,7 @@ describe "IO#readpartial" do buffer = +"existing content" @wr.write("hello world") @wr.close - @rd.readpartial(11, buffer) + @rd.readpartial(11, buffer).should.equal?(buffer) buffer.should == "hello world" end @@ -106,6 +106,7 @@ describe "IO#readpartial" do @wr.write("abc") @wr.close @rd.readpartial(10, buffer) + buffer.encoding.should == Encoding::ISO_8859_1 end end diff --git a/spec/ruby/core/io/sysread_spec.rb b/spec/ruby/core/io/sysread_spec.rb index 003bb9eb94..8851214283 100644 --- a/spec/ruby/core/io/sysread_spec.rb +++ b/spec/ruby/core/io/sysread_spec.rb @@ -97,7 +97,7 @@ describe "IO#sysread on a file" do it "discards the existing buffer content upon successful read" do buffer = +"existing content" - @file.sysread(11, buffer) + @file.sysread(11, buffer).should.equal?(buffer) buffer.should == "01234567890" end @@ -107,6 +107,13 @@ describe "IO#sysread on a file" do -> { @file.sysread(1, buffer) }.should raise_error(EOFError) buffer.should be_empty end + + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + string = @file.sysread(10, buffer) + + buffer.encoding.should == Encoding::ISO_8859_1 + end end describe "IO#sysread" do diff --git a/spec/ruby/core/kernel/caller_spec.rb b/spec/ruby/core/kernel/caller_spec.rb index c3d63ccb00..33c7929a31 100644 --- a/spec/ruby/core/kernel/caller_spec.rb +++ b/spec/ruby/core/kernel/caller_spec.rb @@ -43,16 +43,44 @@ describe 'Kernel#caller' do lines[1].should =~ /\A#{path}:2:in [`']block in <main>'\n\z/ end + it "can be called with a range" do + locations1 = caller(0) + locations2 = caller(2..4) + locations1[2..4].should == locations2 + end + it "works with endless ranges" do locations1 = KernelSpecs::CallerTest.locations(0) locations2 = KernelSpecs::CallerTest.locations(eval("(2..)")) - locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) + locations2.should == locations1[2..-1] end it "works with beginless ranges" do locations1 = KernelSpecs::CallerTest.locations(0) locations2 = KernelSpecs::CallerTest.locations((..5)) - locations2.map(&:to_s)[eval("(2..)")].should == locations1[(..5)].map(&:to_s)[eval("(2..)")] + locations2[eval("(2..)")].should == locations1[(..5)][eval("(2..)")] + end + + it "can be called with a range whose end is negative" do + locations1 = caller(0) + locations2 = caller(2..-1) + locations3 = caller(2..-2) + locations1[2..-1].should == locations2 + locations1[2..-2].should == locations3 + end + + it "must return nil if omitting more locations than available" do + caller(100).should == nil + caller(100..-1).should == nil + end + + it "must return [] if omitting exactly the number of locations available" do + omit = caller(0).length + caller(omit).should == [] + end + + it "must return the same locations when called with 1..-1 and when called with no arguments" do + caller.should == caller(1..-1) end guard -> { Kernel.instance_method(:tap).source_location } do diff --git a/spec/ruby/core/kernel/format_spec.rb b/spec/ruby/core/kernel/format_spec.rb index e8b031e480..1d0c000c15 100644 --- a/spec/ruby/core/kernel/format_spec.rb +++ b/spec/ruby/core/kernel/format_spec.rb @@ -12,4 +12,36 @@ describe "Kernel.format" do it "is accessible as a module function" do Kernel.format("%s", "hello").should == "hello" end + + describe "when $VERBOSE is true" do + it "warns if too many arguments are passed" do + code = <<~RUBY + $VERBOSE = true + format("test", 1) + RUBY + + ruby_exe(code, args: "2>&1").should include("warning: too many arguments for format string") + end + + it "does not warns if too many keyword arguments are passed" do + code = <<~RUBY + $VERBOSE = true + format("test %{test}", test: 1, unused: 2) + RUBY + + ruby_exe(code, args: "2>&1").should_not include("warning") + end + + ruby_bug "#20593", ""..."3.4" do + it "doesn't warns if keyword arguments are passed and none are used" do + code = <<~RUBY + $VERBOSE = true + format("test", test: 1) + format("test", {}) + RUBY + + ruby_exe(code, args: "2>&1").should_not include("warning") + end + end + end end diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb index 0570629723..d35e313006 100644 --- a/spec/ruby/core/kernel/sleep_spec.rb +++ b/spec/ruby/core/kernel/sleep_spec.rb @@ -21,7 +21,7 @@ describe "Kernel#sleep" do sleep(Rational(1, 999)).should >= 0 end - it "accepts any Object that reponds to divmod" do + it "accepts any Object that responds to divmod" do o = Object.new def o.divmod(*); [0, 0.001]; end sleep(o).should >= 0 diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb index 0f77279a4f..adabfdf025 100644 --- a/spec/ruby/core/marshal/dump_spec.rb +++ b/spec/ruby/core/marshal/dump_spec.rb @@ -38,7 +38,7 @@ describe "Marshal.dump" do ].should be_computed_by(:dump) end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "dumps a positive Fixnum > 31 bits as a Bignum" do Marshal.dump(2**31 + 1).should == "\x04\bl+\a\x01\x00\x00\x80" end diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index f599042529..4eac21a952 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -1049,7 +1049,7 @@ describe :marshal_load, shared: true do end describe "for a Bignum" do - platform_is wordsize: 64 do + platform_is c_long_size: 64 do context "that is Bignum on 32-bit platforms but Fixnum on 64-bit" do it "dumps a Fixnum" do val = Marshal.send(@method, "\004\bl+\ab:wU") diff --git a/spec/ruby/core/matchdata/element_reference_spec.rb b/spec/ruby/core/matchdata/element_reference_spec.rb index 806db2d7b5..0924be0aae 100644 --- a/spec/ruby/core/matchdata/element_reference_spec.rb +++ b/spec/ruby/core/matchdata/element_reference_spec.rb @@ -20,6 +20,11 @@ describe "MatchData#[]" do # negative index is larger than the number of match values /(.)(.)(\d+)(\d)/.match("THX1138.")[-30, 2].should == nil + # positive index larger than number of match values + /(.)(.)(\d+)(\d)/.match("THX1138.")[5, 2].should == [] + /(.)(.)(\d+)(\d)/.match("THX1138.")[6, 2].should == nil + /(.)(.)(\d+)(\d)/.match("THX1138.")[30, 2].should == nil + # length argument larger than number of match values is capped to match value length /(.)(.)(\d+)(\d)/.match("THX1138.")[3, 10].should == %w|113 8| diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb index c073bc31ca..78f6b41031 100644 --- a/spec/ruby/core/module/include_spec.rb +++ b/spec/ruby/core/module/include_spec.rb @@ -47,6 +47,34 @@ describe "Module#include" do -> { ModuleSpecs::SubclassSpec.include(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError) end + ruby_version_is ""..."3.2" do + it "raises ArgumentError when the argument is a refinement" do + refinement = nil + + Module.new do + refine String do + refinement = self + end + end + + -> { ModuleSpecs::Basic.include(refinement) }.should raise_error(ArgumentError, "refinement module is not allowed") + end + end + + ruby_version_is "3.2" do + it "raises a TypeError when the argument is a refinement" do + refinement = nil + + Module.new do + refine String do + refinement = self + end + end + + -> { ModuleSpecs::Basic.include(refinement) }.should raise_error(TypeError, "Cannot include refinement") + end + end + it "imports constants to modules and classes" do ModuleSpecs::A.constants.should include(:CONSTANT_A) ModuleSpecs::B.constants.should include(:CONSTANT_A, :CONSTANT_B) diff --git a/spec/ruby/core/module/new_spec.rb b/spec/ruby/core/module/new_spec.rb index da7f3b8720..ec521360bd 100644 --- a/spec/ruby/core/module/new_spec.rb +++ b/spec/ruby/core/module/new_spec.rb @@ -6,6 +6,10 @@ describe "Module.new" do Module.new.is_a?(Module).should == true end + it "creates a module without a name" do + Module.new.name.should be_nil + end + it "creates a new Module and passes it to the provided block" do test_mod = nil m = Module.new do |mod| diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb index c90fa9700e..b40d12f0de 100644 --- a/spec/ruby/core/module/prepend_spec.rb +++ b/spec/ruby/core/module/prepend_spec.rb @@ -75,6 +75,26 @@ describe "Module#prepend" do foo.call.should == 'm' end + it "updates the optimized method when a prepended module is updated" do + out = ruby_exe(<<~RUBY) + module M; end + class Integer + prepend M + end + l = -> { 1 + 2 } + p l.call + M.module_eval do + def +(o) + $called = true + super(o) + end + end + p l.call + p $called + RUBY + out.should == "3\n3\ntrue\n" + end + it "updates the method when there is a base included method and the prepended module overrides it" do base_module = Module.new do def foo @@ -415,6 +435,34 @@ describe "Module#prepend" do -> { ModuleSpecs::SubclassSpec.prepend(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError) end + ruby_version_is ""..."3.2" do + it "raises ArgumentError when the argument is a refinement" do + refinement = nil + + Module.new do + refine String do + refinement = self + end + end + + -> { ModuleSpecs::Basic.prepend(refinement) }.should raise_error(ArgumentError, "refinement module is not allowed") + end + end + + ruby_version_is "3.2" do + it "raises a TypeError when the argument is a refinement" do + refinement = nil + + Module.new do + refine String do + refinement = self + end + end + + -> { ModuleSpecs::Basic.prepend(refinement) }.should raise_error(TypeError, "Cannot prepend refinement") + end + end + it "imports constants" do m1 = Module.new m1::MY_CONSTANT = 1 diff --git a/spec/ruby/core/process/daemon_spec.rb b/spec/ruby/core/process/daemon_spec.rb index 70ffd1b320..36825771d1 100644 --- a/spec/ruby/core/process/daemon_spec.rb +++ b/spec/ruby/core/process/daemon_spec.rb @@ -2,6 +2,9 @@ require_relative '../../spec_helper' require_relative 'fixtures/common' platform_is_not :windows do + # macOS 15 beta is not working this examples + return if /darwin/ =~ RUBY_PLATFORM && /15/ =~ `sw_vers -productVersion` + describe :process_daemon_keep_stdio_open_false, shared: true do it "redirects stdout to /dev/null" do @daemon.invoke("keep_stdio_open_false_stdout", @object).should == "" diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb index 64ea3de4ed..31cfd400cc 100644 --- a/spec/ruby/core/range/step_spec.rb +++ b/spec/ruby/core/range/step_spec.rb @@ -10,44 +10,50 @@ describe "Range#step" do r.step { }.should equal(r) end - it "raises TypeError if step" do - obj = mock("mock") - -> { (1..10).step(obj) { } }.should raise_error(TypeError) - end + ruby_version_is ""..."3.4" do + it "calls #to_int to coerce step to an Integer" do + obj = mock("Range#step") + obj.should_receive(:to_int).and_return(1) - it "calls #to_int to coerce step to an Integer" do - obj = mock("Range#step") - obj.should_receive(:to_int).and_return(1) + (1..2).step(obj) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([1, 2]) + end - (1..2).step(obj) { |x| ScratchPad << x } - ScratchPad.recorded.should eql([1, 2]) - end + it "raises a TypeError if step does not respond to #to_int" do + obj = mock("Range#step non-integer") - it "raises a TypeError if step does not respond to #to_int" do - obj = mock("Range#step non-integer") + -> { (1..2).step(obj) { } }.should raise_error(TypeError) + end - -> { (1..2).step(obj) { } }.should raise_error(TypeError) - end + it "raises a TypeError if #to_int does not return an Integer" do + obj = mock("Range#step non-integer") + obj.should_receive(:to_int).and_return("1") - it "raises a TypeError if #to_int does not return an Integer" do - obj = mock("Range#step non-integer") - obj.should_receive(:to_int).and_return("1") + -> { (1..2).step(obj) { } }.should raise_error(TypeError) + end - -> { (1..2).step(obj) { } }.should raise_error(TypeError) - end + it "raises a TypeError if the first element does not respond to #succ" do + obj = mock("Range#step non-comparable") + obj.should_receive(:<=>).with(obj).and_return(1) - it "coerces the argument to integer by invoking to_int" do - (obj = mock("2")).should_receive(:to_int).and_return(2) - res = [] - (1..10).step(obj) {|x| res << x} - res.should == [1, 3, 5, 7, 9] + -> { (obj..obj).step { |x| x } }.should raise_error(TypeError) + end end - it "raises a TypeError if the first element does not respond to #succ" do - obj = mock("Range#step non-comparable") - obj.should_receive(:<=>).with(obj).and_return(1) + ruby_version_is "3.4" do + it "calls #coerce to coerce step to an Integer" do + obj = mock("Range#step") + obj.should_receive(:coerce).at_least(:once).and_return([1, 2]) + + (1..3).step(obj) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([1, 3]) + end + + it "raises a TypeError if step does not respond to #coerce" do + obj = mock("Range#step non-coercible") - -> { (obj..obj).step { |x| x } }.should raise_error(TypeError) + -> { (1..2).step(obj) { } }.should raise_error(TypeError) + end end it "raises an ArgumentError if step is 0" do @@ -58,8 +64,17 @@ describe "Range#step" do -> { (-1..1).step(0.0) { |x| x } }.should raise_error(ArgumentError) end - it "raises an ArgumentError if step is negative" do - -> { (-1..1).step(-2) { |x| x } }.should raise_error(ArgumentError) + ruby_version_is "3.4" do + it "does not raise an ArgumentError if step is 0 for non-numeric ranges" do + t = Time.utc(2023, 2, 24) + -> { (t..t+1).step(0) { break } }.should_not raise_error(ArgumentError) + end + end + + ruby_version_is ""..."3.4" do + it "raises an ArgumentError if step is negative" do + -> { (-1..1).step(-2) { |x| x } }.should raise_error(ArgumentError) + end end describe "with inclusive end" do @@ -78,6 +93,18 @@ describe "Range#step" do (-2..2).step(1.5) { |x| ScratchPad << x } ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) end + + ruby_version_is "3.4" do + it "does not iterate if step is negative for forward range" do + (-1..1).step(-1) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([]) + end + + it "iterates backward if step is negative for backward range" do + (1..-1).step(-1) { |x| ScratchPad << x } + ScratchPad.recorded.should eql([1, 0, -1]) + end + end end describe "and Float values" do @@ -162,13 +189,96 @@ describe "Range#step" do -> { ("A".."G").step(2.0) { } }.should raise_error(TypeError) end - it "calls #succ on begin and each element returned by #succ" do - obj = mock("Range#step String start") - obj.should_receive(:<=>).exactly(3).times.and_return(-1, -1, -1, 0) - obj.should_receive(:succ).exactly(2).times.and_return(obj) + ruby_version_is ""..."3.4" do + it "calls #succ on begin and each element returned by #succ" do + obj = mock("Range#step String start") + obj.should_receive(:<=>).exactly(3).times.and_return(-1, -1, -1, 0) + obj.should_receive(:succ).exactly(2).times.and_return(obj) + + (obj..obj).step { |x| ScratchPad << x } + ScratchPad.recorded.should == [obj, obj, obj] + end + end + + ruby_version_is "3.4" do + it "yields String values adjusted by step and less than or equal to end" do + ("A".."AAA").step("A") { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA", "AAA"] + end + + it "raises a TypeError when passed an incompatible type step" do + -> { ("A".."G").step([]) { } }.should raise_error(TypeError) + end + + it "calls #+ on begin and each element returned by #+" do + start = mock("Range#step String start") + stop = mock("Range#step String stop") + + mid1 = mock("Range#step String mid1") + mid2 = mock("Range#step String mid2") + + step = mock("Range#step String step") + + # Deciding on the direction of iteration + start.should_receive(:<=>).with(stop).at_least(:twice).and_return(-1) + # Deciding whether the step moves iteration in the right direction + start.should_receive(:<=>).with(mid1).and_return(-1) + # Iteration 1 + start.should_receive(:+).at_least(:once).with(step).and_return(mid1) + # Iteration 2 + mid1.should_receive(:<=>).with(stop).and_return(-1) + mid1.should_receive(:+).with(step).and_return(mid2) + # Iteration 3 + mid2.should_receive(:<=>).with(stop).and_return(0) + + (start..stop).step(step) { |x| ScratchPad << x } + ScratchPad.recorded.should == [start, mid1, mid2] + end + + it "iterates backward if the step is decreasing values, and the range is backward" do + start = mock("Range#step String start") + stop = mock("Range#step String stop") + + mid1 = mock("Range#step String mid1") + mid2 = mock("Range#step String mid2") + + step = mock("Range#step String step") + + # Deciding on the direction of iteration + start.should_receive(:<=>).with(stop).at_least(:twice).and_return(1) + # Deciding whether the step moves iteration in the right direction + start.should_receive(:<=>).with(mid1).and_return(1) + # Iteration 1 + start.should_receive(:+).at_least(:once).with(step).and_return(mid1) + # Iteration 2 + mid1.should_receive(:<=>).with(stop).and_return(1) + mid1.should_receive(:+).with(step).and_return(mid2) + # Iteration 3 + mid2.should_receive(:<=>).with(stop).and_return(0) + + (start..stop).step(step) { |x| ScratchPad << x } + ScratchPad.recorded.should == [start, mid1, mid2] + end + + it "does no iteration of the direction of the range and of the step don't match" do + start = mock("Range#step String start") + stop = mock("Range#step String stop") + + mid1 = mock("Range#step String mid1") + mid2 = mock("Range#step String mid2") + + step = mock("Range#step String step") + + # Deciding on the direction of iteration: stop > start + start.should_receive(:<=>).with(stop).at_least(:twice).and_return(1) + # Deciding whether the step moves iteration in the right direction + # start + step < start, the direction is opposite to the range's + start.should_receive(:+).with(step).and_return(mid1) + start.should_receive(:<=>).with(mid1).and_return(-1) - (obj..obj).step { |x| ScratchPad << x } - ScratchPad.recorded.should == [obj, obj, obj] + (start..stop).step(step) { |x| ScratchPad << x } + ScratchPad.recorded.should == [] + end end end end @@ -266,18 +376,31 @@ describe "Range#step" do end describe "and String values" do - it "yields String values incremented by #succ and less than or equal to end when not passed a step" do - ("A"..."E").step { |x| ScratchPad << x } - ScratchPad.recorded.should == ["A", "B", "C", "D"] - end + ruby_version_is ""..."3.4" do + it "yields String values incremented by #succ and less than or equal to end when not passed a step" do + ("A"..."E").step { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "B", "C", "D"] + end - it "yields String values incremented by #succ called Integer step times" do - ("A"..."G").step(2) { |x| ScratchPad << x } - ScratchPad.recorded.should == ["A", "C", "E"] + it "yields String values incremented by #succ called Integer step times" do + ("A"..."G").step(2) { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "C", "E"] + end + + it "raises a TypeError when passed a Float step" do + -> { ("A"..."G").step(2.0) { } }.should raise_error(TypeError) + end end - it "raises a TypeError when passed a Float step" do - -> { ("A"..."G").step(2.0) { } }.should raise_error(TypeError) + ruby_version_is "3.4" do + it "yields String values adjusted by step and less than or equal to end" do + ("A"..."AAA").step("A") { |x| ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA"] + end + + it "raises a TypeError when passed an incompatible type step" do + -> { ("A".."G").step([]) { } }.should raise_error(TypeError) + end end end end @@ -373,6 +496,22 @@ describe "Range#step" do -> { eval("('A'..)").step(2.0) { } }.should raise_error(TypeError) -> { eval("('A'...)").step(2.0) { } }.should raise_error(TypeError) end + + ruby_version_is "3.4" do + it "yields String values adjusted by step" do + eval("('A'..)").step("A") { |x| break if x > "AAA"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA", "AAA"] + + ScratchPad.record [] + eval("('A'...)").step("A") { |x| break if x > "AAA"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "AA", "AAA"] + end + + it "raises a TypeError when passed an incompatible type step" do + -> { eval("('A'..)").step([]) { } }.should raise_error(TypeError) + -> { eval("('A'...)").step([]) { } }.should raise_error(TypeError) + end + end end end @@ -383,15 +522,24 @@ describe "Range#step" do describe "returned Enumerator" do describe "size" do - it "raises a TypeError if step does not respond to #to_int" do - obj = mock("Range#step non-integer") - -> { (1..2).step(obj) }.should raise_error(TypeError) + ruby_version_is ""..."3.4" do + it "raises a TypeError if step does not respond to #to_int" do + obj = mock("Range#step non-integer") + -> { (1..2).step(obj) }.should raise_error(TypeError) + end + + it "raises a TypeError if #to_int does not return an Integer" do + obj = mock("Range#step non-integer") + obj.should_receive(:to_int).and_return("1") + -> { (1..2).step(obj) }.should raise_error(TypeError) + end end - it "raises a TypeError if #to_int does not return an Integer" do - obj = mock("Range#step non-integer") - obj.should_receive(:to_int).and_return("1") - -> { (1..2).step(obj) }.should raise_error(TypeError) + ruby_version_is "3.4" do + it "does not raise if step is incompatible" do + obj = mock("Range#step non-integer") + -> { (1..2).step(obj) }.should_not raise_error + end end it "returns the ceil of range size divided by the number of steps" do @@ -431,19 +579,36 @@ describe "Range#step" do (1.0...6.4).step(1.8).size.should == 3 end - it "returns nil with begin and end are String" do - ("A".."E").step(2).size.should == nil - ("A"..."E").step(2).size.should == nil - ("A".."E").step.size.should == nil - ("A"..."E").step.size.should == nil + ruby_version_is ""..."3.4" do + it "returns nil with begin and end are String" do + ("A".."E").step(2).size.should == nil + ("A"..."E").step(2).size.should == nil + ("A".."E").step.size.should == nil + ("A"..."E").step.size.should == nil + end + + it "return nil and not raises a TypeError if the first element does not respond to #succ" do + obj = mock("Range#step non-comparable") + obj.should_receive(:<=>).with(obj).and_return(1) + enum = (obj..obj).step + -> { enum.size }.should_not raise_error + enum.size.should == nil + end end - it "return nil and not raises a TypeError if the first element does not respond to #succ" do - obj = mock("Range#step non-comparable") - obj.should_receive(:<=>).with(obj).and_return(1) - enum = (obj..obj).step - -> { enum.size }.should_not raise_error - enum.size.should == nil + ruby_version_is "3.4" do + it "returns nil with begin and end are String" do + ("A".."E").step("A").size.should == nil + ("A"..."E").step("A").size.should == nil + end + + it "return nil and not raises a TypeError if the first element is not of compatible type" do + obj = mock("Range#step non-comparable") + obj.should_receive(:<=>).with(obj).and_return(1) + enum = (obj..obj).step(obj) + -> { enum.size }.should_not raise_error + enum.size.should == nil + end end end @@ -470,22 +635,48 @@ describe "Range#step" do (1..).step(2).take(3).should == [1, 3, 5] end - it "returns an instance of Enumerator when begin is not numeric" do - ("a"..).step.class.should == Enumerator - ("a"..).step(2).take(3).should == %w[a c e] + ruby_version_is ""..."3.4" do + it "returns an instance of Enumerator when begin is not numeric" do + ("a"..).step.class.should == Enumerator + ("a"..).step(2).take(3).should == %w[a c e] + end + end + + ruby_version_is "3.4" do + it "returns an instance of Enumerator when begin is not numeric" do + ("a"..).step("a").class.should == Enumerator + ("a"..).step("a").take(3).should == %w[a aa aaa] + end end end context "when range is beginless and endless" do - it "returns an instance of Enumerator" do - Range.new(nil, nil).step.class.should == Enumerator + ruby_version_is ""..."3.4" do + it "returns an instance of Enumerator" do + Range.new(nil, nil).step.class.should == Enumerator + end + end + + ruby_version_is "3.4" do + it "raises an ArgumentError" do + -> { Range.new(nil, nil).step(1) }.should raise_error(ArgumentError) + end end end context "when begin and end are not numerics" do - it "returns an instance of Enumerator" do - ("a".."z").step.class.should == Enumerator - ("a".."z").step(3).take(4).should == %w[a d g j] + ruby_version_is ""..."3.4" do + it "returns an instance of Enumerator" do + ("a".."z").step.class.should == Enumerator + ("a".."z").step(3).take(4).should == %w[a d g j] + end + end + + ruby_version_is "3.4" do + it "returns an instance of Enumerator" do + ("a".."z").step("a").class.should == Enumerator + ("a".."z").step("a").take(4).should == %w[a aa aaa aaaa] + end end end end diff --git a/spec/ruby/core/regexp/shared/new.rb b/spec/ruby/core/regexp/shared/new.rb index 7c3fabf612..7052bcab63 100644 --- a/spec/ruby/core/regexp/shared/new.rb +++ b/spec/ruby/core/regexp/shared/new.rb @@ -56,7 +56,7 @@ describe :regexp_new_string, shared: true do end it "raises a RegexpError when passed an incorrect regexp" do - -> { Regexp.send(@method, "^[$", 0) }.should raise_error(RegexpError) + -> { Regexp.send(@method, "^[$", 0) }.should raise_error(RegexpError, Regexp.new(Regexp.escape("premature end of char-class: /^[$/"))) end it "does not set Regexp options if only given one argument" do @@ -261,7 +261,7 @@ describe :regexp_new_string, shared: true do describe "with escaped characters" do it "raises a Regexp error if there is a trailing backslash" do - -> { Regexp.send(@method, "\\") }.should raise_error(RegexpError) + -> { Regexp.send(@method, "\\") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("too short escape sequence: /\\/"))) end it "does not raise a Regexp error if there is an escaped trailing backslash" do @@ -293,7 +293,7 @@ describe :regexp_new_string, shared: true do end it "raises a RegexpError if \\x is not followed by any hexadecimal digits" do - -> { Regexp.send(@method, "\\" + "xn") }.should raise_error(RegexpError) + -> { Regexp.send(@method, "\\" + "xn") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid hex escape: /\\xn/"))) end it "accepts an escaped string interpolation" do @@ -453,15 +453,15 @@ describe :regexp_new_string, shared: true do end it "raises a RegexpError if less than four digits are given for \\uHHHH" do - -> { Regexp.send(@method, "\\" + "u304") }.should raise_error(RegexpError) + -> { Regexp.send(@method, "\\" + "u304") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode escape: /\\u304/"))) end it "raises a RegexpError if the \\u{} escape is empty" do - -> { Regexp.send(@method, "\\" + "u{}") }.should raise_error(RegexpError) + -> { Regexp.send(@method, "\\" + "u{}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode list: /\\u{}/"))) end it "raises a RegexpError if more than six hexadecimal digits are given" do - -> { Regexp.send(@method, "\\" + "u{0ffffff}") }.should raise_error(RegexpError) + -> { Regexp.send(@method, "\\" + "u{0ffffff}") }.should raise_error(RegexpError, Regexp.new(Regexp.escape("invalid Unicode range: /\\u{0ffffff}/"))) end it "returns a Regexp with US-ASCII encoding if only 7-bit ASCII characters are present regardless of the input String's encoding" do diff --git a/spec/ruby/core/string/append_as_bytes_spec.rb b/spec/ruby/core/string/append_as_bytes_spec.rb new file mode 100644 index 0000000000..0e1d09558b --- /dev/null +++ b/spec/ruby/core/string/append_as_bytes_spec.rb @@ -0,0 +1,46 @@ +require_relative '../../spec_helper' + +describe "String#append_bytes" do + ruby_version_is "3.4" do + it "doesn't allow to mutate frozen strings" do + str = "hello".freeze + -> { str.append_as_bytes("\xE2\x82") }.should raise_error(FrozenError) + end + + it "allows creating broken strings" do + str = +"hello" + str.append_as_bytes("\xE2\x82") + str.valid_encoding?.should == false + + str.append_as_bytes("\xAC") + str.valid_encoding?.should == true + + str = "abc".encode(Encoding::UTF_32LE) + str.append_as_bytes("def") + str.encoding.should == Encoding::UTF_32LE + str.valid_encoding?.should == false + end + + it "never changes the receiver encoding" do + str = "".b + str.append_as_bytes("€") + str.encoding.should == Encoding::BINARY + end + + it "accepts variadic String or Integer arguments" do + str = "hello".b + str.append_as_bytes("\xE2\x82", 12, 43, "\xAC") + str.encoding.should == Encoding::BINARY + str.should == "hello\xE2\x82\f+\xAC".b + end + + it "only accepts strings or integers, and doesn't attempt to cast with #to_str or #to_int" do + to_str = mock("to_str") + to_str.should_not_receive(:to_str) + to_str.should_not_receive(:to_int) + + str = +"hello" + -> { str.append_as_bytes(to_str) }.should raise_error(TypeError, "wrong argument type MockObject (expected String or Integer)") + end + end +end diff --git a/spec/ruby/core/string/chilled_string_spec.rb b/spec/ruby/core/string/chilled_string_spec.rb index 8de4fc421b..9f81b1af6d 100644 --- a/spec/ruby/core/string/chilled_string_spec.rb +++ b/spec/ruby/core/string/chilled_string_spec.rb @@ -3,8 +3,8 @@ require_relative '../../spec_helper' describe "chilled String" do guard -> { ruby_version_is "3.4" and !"test".equal?("test") } do describe "#frozen?" do - it "returns true" do - "chilled".frozen?.should == true + it "returns false" do + "chilled".frozen?.should == false end end @@ -45,7 +45,7 @@ describe "chilled String" do input.should == "chilled-mutated" end - it "emits a warning on singleton_class creaation" do + it "emits a warning on singleton_class creation" do -> { "chilled".singleton_class }.should complain(/literal string will be frozen in the future/) @@ -57,12 +57,14 @@ describe "chilled String" do }.should complain(/literal string will be frozen in the future/) end - it "raises FrozenError after the string was explictly frozen" do + it "raises FrozenError after the string was explicitly frozen" do input = "chilled" input.freeze -> { + -> { input << "mutated" - }.should raise_error(FrozenError) + }.should raise_error(FrozenError) + }.should_not complain(/literal string will be frozen in the future/) end end end diff --git a/spec/ruby/core/string/encode_spec.rb b/spec/ruby/core/string/encode_spec.rb index 97dd753b62..cd449498a3 100644 --- a/spec/ruby/core/string/encode_spec.rb +++ b/spec/ruby/core/string/encode_spec.rb @@ -61,10 +61,22 @@ describe "String#encode" do str.encode(invalid: :replace).should_not equal(str) end - it "normalizes newlines" do - "\r\nfoo".encode(universal_newline: true).should == "\nfoo" + it "normalizes newlines with cr_newline option" do + "\r\nfoo".encode(cr_newline: true).should == "\r\rfoo" + "\rfoo".encode(cr_newline: true).should == "\rfoo" + "\nfoo".encode(cr_newline: true).should == "\rfoo" + end + it "normalizes newlines with crlf_newline option" do + "\r\nfoo".encode(crlf_newline: true).should == "\r\r\nfoo" + "\rfoo".encode(crlf_newline: true).should == "\rfoo" + "\nfoo".encode(crlf_newline: true).should == "\r\nfoo" + end + + it "normalizes newlines with universal_newline option" do + "\r\nfoo".encode(universal_newline: true).should == "\nfoo" "\rfoo".encode(universal_newline: true).should == "\nfoo" + "\nfoo".encode(universal_newline: true).should == "\nfoo" end it "replaces invalid encoding in source with default replacement" do diff --git a/spec/ruby/core/string/modulo_spec.rb b/spec/ruby/core/string/modulo_spec.rb index bf96a82874..9045afa263 100644 --- a/spec/ruby/core/string/modulo_spec.rb +++ b/spec/ruby/core/string/modulo_spec.rb @@ -55,33 +55,48 @@ describe "String#%" do -> { ("foo%" % [])}.should raise_error(ArgumentError) end - it "formats single % character before a newline as literal %" do - ("%\n" % []).should == "%\n" - ("foo%\n" % []).should == "foo%\n" - ("%\n.3f" % 1.2).should == "%\n.3f" - end + ruby_version_is ""..."3.4" do + it "formats single % character before a newline as literal %" do + ("%\n" % []).should == "%\n" + ("foo%\n" % []).should == "foo%\n" + ("%\n.3f" % 1.2).should == "%\n.3f" + end - it "formats single % character before a NUL as literal %" do - ("%\0" % []).should == "%\0" - ("foo%\0" % []).should == "foo%\0" - ("%\0.3f" % 1.2).should == "%\0.3f" - end + it "formats single % character before a NUL as literal %" do + ("%\0" % []).should == "%\0" + ("foo%\0" % []).should == "foo%\0" + ("%\0.3f" % 1.2).should == "%\0.3f" + end - it "raises an error if single % appears anywhere else" do - -> { (" % " % []) }.should raise_error(ArgumentError) - -> { ("foo%quux" % []) }.should raise_error(ArgumentError) - end + it "raises an error if single % appears anywhere else" do + -> { (" % " % []) }.should raise_error(ArgumentError) + -> { ("foo%quux" % []) }.should raise_error(ArgumentError) + end - it "raises an error if NULL or \\n appear anywhere else in the format string" do - begin - old_debug, $DEBUG = $DEBUG, false + it "raises an error if NULL or \\n appear anywhere else in the format string" do + begin + old_debug, $DEBUG = $DEBUG, false + -> { "%.\n3f" % 1.2 }.should raise_error(ArgumentError) + -> { "%.3\nf" % 1.2 }.should raise_error(ArgumentError) + -> { "%.\03f" % 1.2 }.should raise_error(ArgumentError) + -> { "%.3\0f" % 1.2 }.should raise_error(ArgumentError) + ensure + $DEBUG = old_debug + end + end + end + + ruby_version_is "3.4" do + it "raises an ArgumentError if % is not followed by a conversion specifier" do + -> { "%" % [] }.should raise_error(ArgumentError) + -> { "%\n" % [] }.should raise_error(ArgumentError) + -> { "%\0" % [] }.should raise_error(ArgumentError) + -> { " % " % [] }.should raise_error(ArgumentError) -> { "%.\n3f" % 1.2 }.should raise_error(ArgumentError) -> { "%.3\nf" % 1.2 }.should raise_error(ArgumentError) -> { "%.\03f" % 1.2 }.should raise_error(ArgumentError) -> { "%.3\0f" % 1.2 }.should raise_error(ArgumentError) - ensure - $DEBUG = old_debug end end @@ -125,8 +140,16 @@ describe "String#%" do end end - it "replaces trailing absolute argument specifier without type with percent sign" do - ("hello %1$" % "foo").should == "hello %" + ruby_version_is ""..."3.4" do + it "replaces trailing absolute argument specifier without type with percent sign" do + ("hello %1$" % "foo").should == "hello %" + end + end + + ruby_version_is "3.4" do + it "raises an ArgumentError if absolute argument specifier is followed by a conversion specifier" do + -> { "hello %1$" % "foo" }.should raise_error(ArgumentError) + end end it "raises an ArgumentError when given invalid argument specifiers" do diff --git a/spec/ruby/core/string/shared/encode.rb b/spec/ruby/core/string/shared/encode.rb index 3776e0d709..9466308886 100644 --- a/spec/ruby/core/string/shared/encode.rb +++ b/spec/ruby/core/string/shared/encode.rb @@ -194,6 +194,190 @@ describe :string_encode, shared: true do end end + describe "given the fallback option" do + context "given a hash" do + it "looks up the replacement value from the hash" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: { "\ufffd" => "bar" }) + encoded.should == "Bbar" + end + + it "calls to_str on the returned value" do + obj = Object.new + obj.should_receive(:to_str).and_return("bar") + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: { "\ufffd" => obj }) + encoded.should == "Bbar" + end + + it "does not call to_s on the returned value" do + obj = Object.new + obj.should_not_receive(:to_s) + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: { "\ufffd" => obj }) + }.should raise_error(TypeError, "no implicit conversion of Object into String") + end + + it "raises an error if the key is not present in the hash" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: { "foo" => "bar" }) + }.should raise_error(Encoding::UndefinedConversionError, "U+FFFD from UTF-8 to US-ASCII") + end + + it "raises an error if the value is itself invalid" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: { "\ufffd" => "\uffee" }) + }.should raise_error(ArgumentError, "too big fallback string") + end + + it "uses the hash's default value if set" do + hash = {} + hash.default = "bar" + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: hash) + encoded.should == "Bbar" + end + + it "uses the result of calling default_proc if set" do + hash = {} + hash.default_proc = -> _, _ { "bar" } + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: hash) + encoded.should == "Bbar" + end + end + + context "given an object inheriting from Hash" do + before do + klass = Class.new(Hash) + @hash_like = klass.new + @hash_like["\ufffd"] = "bar" + end + + it "looks up the replacement value from the object" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: @hash_like) + encoded.should == "Bbar" + end + end + + context "given an object responding to []" do + before do + klass = Class.new do + def [](c) = c.bytes.inspect + end + @hash_like = klass.new + end + + it "calls [] on the object, passing the invalid character" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: @hash_like) + encoded.should == "B[239, 191, 189]" + end + end + + context "given an object not responding to []" do + before do + @non_hash_like = Object.new + end + + it "raises an error" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: @non_hash_like) + }.should raise_error(Encoding::UndefinedConversionError, "U+FFFD from UTF-8 to US-ASCII") + end + end + + context "given a proc" do + it "calls the proc to get the replacement value, passing in the invalid character" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: proc { |c| c.bytes.inspect }) + encoded.should == "B[239, 191, 189]" + end + + it "calls to_str on the returned value" do + obj = Object.new + obj.should_receive(:to_str).and_return("bar") + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: proc { |c| obj }) + encoded.should == "Bbar" + end + + it "does not call to_s on the returned value" do + obj = Object.new + obj.should_not_receive(:to_s) + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: proc { |c| obj }) + }.should raise_error(TypeError, "no implicit conversion of Object into String") + end + + it "raises an error if the returned value is itself invalid" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: -> c { "\uffee" }) + }.should raise_error(ArgumentError, "too big fallback string") + end + end + + context "given a lambda" do + it "calls the lambda to get the replacement value, passing in the invalid character" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: -> c { c.bytes.inspect }) + encoded.should == "B[239, 191, 189]" + end + + it "calls to_str on the returned value" do + obj = Object.new + obj.should_receive(:to_str).and_return("bar") + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: -> c { obj }) + encoded.should == "Bbar" + end + + it "does not call to_s on the returned value" do + obj = Object.new + obj.should_not_receive(:to_s) + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: -> c { obj }) + }.should raise_error(TypeError, "no implicit conversion of Object into String") + end + + it "raises an error if the returned value is itself invalid" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: -> c { "\uffee" }) + }.should raise_error(ArgumentError, "too big fallback string") + end + end + + context "given a method" do + def replace(c) = c.bytes.inspect + def replace_bad(c) = "\uffee" + + def replace_to_str(c) + obj = Object.new + obj.should_receive(:to_str).and_return("bar") + obj + end + + def replace_to_s(c) + obj = Object.new + obj.should_not_receive(:to_s) + obj + end + + it "calls the method to get the replacement value, passing in the invalid character" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: method(:replace)) + encoded.should == "B[239, 191, 189]" + end + + it "calls to_str on the returned value" do + encoded = "B\ufffd".encode(Encoding::US_ASCII, fallback: method(:replace_to_str)) + encoded.should == "Bbar" + end + + it "does not call to_s on the returned value" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: method(:replace_to_s)) + }.should raise_error(TypeError, "no implicit conversion of Object into String") + end + + it "raises an error if the returned value is itself invalid" do + -> { + "B\ufffd".encode(Encoding::US_ASCII, fallback: method(:replace_bad)) + }.should raise_error(ArgumentError, "too big fallback string") + end + end + end + describe "given the xml: :text option" do it "replaces all instances of '&' with '&'" do '& and &'.send(@method, "UTF-8", xml: :text).should == '& and &' diff --git a/spec/ruby/core/string/unpack/l_spec.rb b/spec/ruby/core/string/unpack/l_spec.rb index 18bb68b8d0..0adb567eca 100644 --- a/spec/ruby/core/string/unpack/l_spec.rb +++ b/spec/ruby/core/string/unpack/l_spec.rb @@ -14,7 +14,7 @@ describe "String#unpack with format 'L'" do it_behaves_like :string_unpack_32bit_be_unsigned, 'L>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_32bit_le, 'L<_' it_behaves_like :string_unpack_32bit_le, 'L_<' @@ -44,7 +44,7 @@ describe "String#unpack with format 'L'" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_64bit_le, 'L<_' it_behaves_like :string_unpack_64bit_le, 'L_<' @@ -86,7 +86,7 @@ describe "String#unpack with format 'l'" do it_behaves_like :string_unpack_32bit_be_signed, 'l>' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_32bit_le, 'l<_' it_behaves_like :string_unpack_32bit_le, 'l_<' @@ -116,7 +116,7 @@ describe "String#unpack with format 'l'" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "with modifier '<' and '_'" do it_behaves_like :string_unpack_64bit_le, 'l<_' it_behaves_like :string_unpack_64bit_le, 'l_<' @@ -160,7 +160,7 @@ little_endian do it_behaves_like :string_unpack_32bit_le_signed, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_32bit_le, 'L_' it_behaves_like :string_unpack_32bit_le_unsigned, 'L_' @@ -182,7 +182,7 @@ little_endian do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_64bit_le, 'L_' it_behaves_like :string_unpack_64bit_le_unsigned, 'L_' @@ -218,7 +218,7 @@ big_endian do it_behaves_like :string_unpack_32bit_be_signed, 'l' end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_32bit_be, 'L_' it_behaves_like :string_unpack_32bit_be_unsigned, 'L_' @@ -240,7 +240,7 @@ big_endian do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "String#unpack with format 'L' with modifier '_'" do it_behaves_like :string_unpack_64bit_be, 'L_' it_behaves_like :string_unpack_64bit_be_unsigned, 'L_' diff --git a/spec/ruby/core/struct/to_h_spec.rb b/spec/ruby/core/struct/to_h_spec.rb index bfb0af07ba..861ce3f49d 100644 --- a/spec/ruby/core/struct/to_h_spec.rb +++ b/spec/ruby/core/struct/to_h_spec.rb @@ -21,6 +21,18 @@ describe "Struct#to_h" do h.should == { "make" => "ford", "model" => "ranger", "year" => "" } end + it "passes to a block each pair's key and value as separate arguments" do + s = StructClasses::Ruby.new('3.2.4', 'macos') + + ScratchPad.record [] + s.to_h { |k, v| ScratchPad << [k, v]; [k, v] } + ScratchPad.recorded.sort.should == [[:platform, 'macos'], [:version, '3.2.4']] + + ScratchPad.record [] + s.to_h { |*args| ScratchPad << args; [args[0], args[1]] } + ScratchPad.recorded.sort.should == [[:platform, 'macos'], [:version, '3.2.4']] + end + it "raises ArgumentError if block returns longer or shorter array" do -> do StructClasses::Car.new.to_h { |k, v| [k.to_s, "#{v}".downcase, 1] } diff --git a/spec/ruby/core/thread/thread_variable_get_spec.rb b/spec/ruby/core/thread/thread_variable_get_spec.rb index 0ad19bfd88..1ea34cf2b3 100644 --- a/spec/ruby/core/thread/thread_variable_get_spec.rb +++ b/spec/ruby/core/thread/thread_variable_get_spec.rb @@ -14,12 +14,47 @@ describe "Thread#thread_variable_get" do end it "returns the value previously set by #thread_variable_set" do - @t.thread_variable_set :a, 49 + @t.thread_variable_set(:a, 49) @t.thread_variable_get(:a).should == 49 end it "returns a value private to self" do - @t.thread_variable_set :thread_variable_get_spec, 82 + @t.thread_variable_set(:thread_variable_get_spec, 82) Thread.current.thread_variable_get(:thread_variable_get_spec).should be_nil end + + it "accepts String and Symbol keys interchangeably" do + @t.thread_variable_set("a", 49) + @t.thread_variable_get("a").should == 49 + @t.thread_variable_get(:a).should == 49 + end + + it "converts a key that is neither String nor Symbol with #to_str" do + key = mock('key') + key.should_receive(:to_str).and_return('a') + @t.thread_variable_set(:a, 49) + @t.thread_variable_get(key).should == 49 + end + + it "does not raise FrozenError if the thread is frozen" do + @t.freeze + @t.thread_variable_get(:a).should be_nil + end + + it "raises a TypeError if the key is neither Symbol nor String when thread variables are already set" do + @t.thread_variable_set(:a, 49) + -> { @t.thread_variable_get(123) }.should raise_error(TypeError, /123 is not a symbol/) + end + + ruby_version_is '3.4' do + it "raises a TypeError if the key is neither Symbol nor String when no thread variables are set" do + -> { @t.thread_variable_get(123) }.should raise_error(TypeError, /123 is not a symbol/) + end + + it "raises a TypeError if the key is neither Symbol nor String without calling #to_sym" do + key = mock('key') + key.should_not_receive(:to_sym) + -> { @t.thread_variable_get(key) }.should raise_error(TypeError, /#{Regexp.escape(key.inspect)} is not a symbol/) + end + end end diff --git a/spec/ruby/core/thread/thread_variable_set_spec.rb b/spec/ruby/core/thread/thread_variable_set_spec.rb index 1338c306c7..eadee76afb 100644 --- a/spec/ruby/core/thread/thread_variable_set_spec.rb +++ b/spec/ruby/core/thread/thread_variable_set_spec.rb @@ -10,17 +10,53 @@ describe "Thread#thread_variable_set" do end it "returns the value set" do - (@t.thread_variable_set :a, 2).should == 2 + @t.thread_variable_set(:a, 2).should == 2 end it "sets a value that will be returned by #thread_variable_get" do - @t.thread_variable_set :a, 49 + @t.thread_variable_set(:a, 49) @t.thread_variable_get(:a).should == 49 end it "sets a value private to self" do - @t.thread_variable_set :thread_variable_get_spec, 82 + @t.thread_variable_set(:thread_variable_get_spec, 82) @t.thread_variable_get(:thread_variable_get_spec).should == 82 Thread.current.thread_variable_get(:thread_variable_get_spec).should be_nil end + + it "accepts String and Symbol keys interchangeably" do + @t.thread_variable_set('a', 49) + @t.thread_variable_get('a').should == 49 + + @t.thread_variable_set(:a, 50) + @t.thread_variable_get('a').should == 50 + end + + it "converts a key that is neither String nor Symbol with #to_str" do + key = mock('key') + key.should_receive(:to_str).and_return('a') + @t.thread_variable_set(key, 49) + @t.thread_variable_get(:a).should == 49 + end + + it "removes a key if the value is nil" do + @t.thread_variable_set(:a, 52) + @t.thread_variable_set(:a, nil) + @t.thread_variable?(:a).should be_false + end + + it "raises a FrozenError if the thread is frozen" do + @t.freeze + -> { @t.thread_variable_set(:a, 1) }.should raise_error(FrozenError, "can't modify frozen thread locals") + end + + it "raises a TypeError if the key is neither Symbol nor String, nor responds to #to_str" do + -> { @t.thread_variable_set(123, 1) }.should raise_error(TypeError, /123 is not a symbol/) + end + + it "does not try to convert the key with #to_sym" do + key = mock('key') + key.should_not_receive(:to_sym) + -> { @t.thread_variable_set(key, 42) }.should raise_error(TypeError, /#{Regexp.quote(key.inspect)} is not a symbol/) + end end diff --git a/spec/ruby/core/thread/thread_variable_spec.rb b/spec/ruby/core/thread/thread_variable_spec.rb index 6bd1950c04..1b021e9404 100644 --- a/spec/ruby/core/thread/thread_variable_spec.rb +++ b/spec/ruby/core/thread/thread_variable_spec.rb @@ -10,12 +10,51 @@ describe "Thread#thread_variable?" do end it "returns false if the thread variables do not contain 'key'" do - @t.thread_variable_set :a, 2 + @t.thread_variable_set(:a, 2) @t.thread_variable?(:b).should be_false end it "returns true if the thread variables contain 'key'" do - @t.thread_variable_set :a, 2 + @t.thread_variable_set(:a, 2) @t.thread_variable?(:a).should be_true end + + it "accepts String and Symbol keys interchangeably" do + @t.thread_variable?('a').should be_false + @t.thread_variable?(:a).should be_false + + @t.thread_variable_set(:a, 49) + + @t.thread_variable?('a').should be_true + @t.thread_variable?(:a).should be_true + end + + it "converts a key that is neither String nor Symbol with #to_str" do + key = mock('key') + key.should_receive(:to_str).and_return('a') + @t.thread_variable_set(:a, 49) + @t.thread_variable?(key).should be_true + end + + it "does not raise FrozenError if the thread is frozen" do + @t.freeze + @t.thread_variable?(:a).should be_false + end + + it "raises a TypeError if the key is neither Symbol nor String when thread variables are already set" do + @t.thread_variable_set(:a, 49) + -> { @t.thread_variable?(123) }.should raise_error(TypeError, /123 is not a symbol/) + end + + ruby_version_is '3.4' do + it "raises a TypeError if the key is neither Symbol nor String when no thread variables are set" do + -> { @t.thread_variable?(123) }.should raise_error(TypeError, /123 is not a symbol/) + end + + it "raises a TypeError if the key is neither Symbol nor String without calling #to_sym" do + key = mock('key') + key.should_not_receive(:to_sym) + -> { @t.thread_variable?(key) }.should raise_error(TypeError, /#{Regexp.escape(key.inspect)} is not a symbol/) + end + end end diff --git a/spec/ruby/core/thread/thread_variables_spec.rb b/spec/ruby/core/thread/thread_variables_spec.rb index 1bd68b17f1..51ceef3376 100644 --- a/spec/ruby/core/thread/thread_variables_spec.rb +++ b/spec/ruby/core/thread/thread_variables_spec.rb @@ -10,15 +10,15 @@ describe "Thread#thread_variables" do end it "returns the keys of all the values set" do - @t.thread_variable_set :a, 2 - @t.thread_variable_set :b, 4 - @t.thread_variable_set :c, 6 + @t.thread_variable_set(:a, 2) + @t.thread_variable_set(:b, 4) + @t.thread_variable_set(:c, 6) @t.thread_variables.sort.should == [:a, :b, :c] end - it "sets a value private to self" do - @t.thread_variable_set :a, 82 - @t.thread_variable_set :b, 82 + it "returns the keys private to self" do + @t.thread_variable_set(:a, 82) + @t.thread_variable_set(:b, 82) Thread.current.thread_variables.should_not include(:a, :b) end @@ -26,4 +26,14 @@ describe "Thread#thread_variables" do Thread.current.thread_variables.should == [] @t.thread_variables.should == [] end + + it "returns keys as Symbols" do + key = mock('key') + key.should_receive(:to_str).and_return('a') + + @t.thread_variable_set(key, 49) + @t.thread_variable_set('b', 50) + @t.thread_variable_set(:c, 51) + @t.thread_variables.sort.should == [:a, :b, :c] + end end diff --git a/spec/ruby/core/time/iso8601_spec.rb b/spec/ruby/core/time/iso8601_spec.rb new file mode 100644 index 0000000000..ad60c3bb32 --- /dev/null +++ b/spec/ruby/core/time/iso8601_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative 'shared/xmlschema' + +describe "Time#iso8601" do + it_behaves_like :time_xmlschema, :iso8601 +end diff --git a/spec/ruby/core/time/shared/xmlschema.rb b/spec/ruby/core/time/shared/xmlschema.rb new file mode 100644 index 0000000000..d68c18df36 --- /dev/null +++ b/spec/ruby/core/time/shared/xmlschema.rb @@ -0,0 +1,31 @@ +describe :time_xmlschema, shared: true do + ruby_version_is "3.4" do + it "generates ISO-8601 strings in Z for UTC times" do + t = Time.utc(1985, 4, 12, 23, 20, 50, 521245) + t.send(@method).should == "1985-04-12T23:20:50Z" + t.send(@method, 2).should == "1985-04-12T23:20:50.52Z" + t.send(@method, 9).should == "1985-04-12T23:20:50.521245000Z" + end + + it "generates ISO-8601 string with timeone offset for non-UTC times" do + t = Time.new(1985, 4, 12, 23, 20, 50, "+02:00") + t.send(@method).should == "1985-04-12T23:20:50+02:00" + t.send(@method, 2).should == "1985-04-12T23:20:50.00+02:00" + end + + it "year is always at least 4 digits" do + t = Time.utc(12, 4, 12) + t.send(@method).should == "0012-04-12T00:00:00Z" + end + + it "year can be more than 4 digits" do + t = Time.utc(40_000, 4, 12) + t.send(@method).should == "40000-04-12T00:00:00Z" + end + + it "year can be negative" do + t = Time.utc(-2000, 4, 12) + t.send(@method).should == "-2000-04-12T00:00:00Z" + end + end +end diff --git a/spec/ruby/core/time/xmlschema_spec.rb b/spec/ruby/core/time/xmlschema_spec.rb new file mode 100644 index 0000000000..bdf1dc7923 --- /dev/null +++ b/spec/ruby/core/time/xmlschema_spec.rb @@ -0,0 +1,6 @@ +require_relative '../../spec_helper' +require_relative 'shared/xmlschema' + +describe "Time#xmlschema" do + it_behaves_like :time_xmlschema, :xmlschema +end diff --git a/spec/ruby/core/time/yday_spec.rb b/spec/ruby/core/time/yday_spec.rb index 6ea5ff8f1b..e920c2e28d 100644 --- a/spec/ruby/core/time/yday_spec.rb +++ b/spec/ruby/core/time/yday_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative '../../shared/time/yday' describe "Time#yday" do it "returns an integer representing the day of the year, 1..366" do @@ -7,15 +8,5 @@ describe "Time#yday" do end end - it 'returns the correct value for each day of each month' do - mdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - - yday = 1 - mdays.each_with_index do |days, month| - days.times do |day| - Time.new(2014, month+1, day+1).yday.should == yday - yday += 1 - end - end - end + it_behaves_like :time_yday, -> year, month, day { Time.new(year, month, day).yday } end diff --git a/spec/ruby/core/tracepoint/inspect_spec.rb b/spec/ruby/core/tracepoint/inspect_spec.rb index cc6bf0f842..6cc2ebe243 100644 --- a/spec/ruby/core/tracepoint/inspect_spec.rb +++ b/spec/ruby/core/tracepoint/inspect_spec.rb @@ -24,6 +24,8 @@ describe 'TracePoint#inspect' do line = nil TracePoint.new(:line) { |tp| next unless TracePointSpec.target_thread? + next unless tp.path == __FILE__ + inspect ||= tp.inspect }.enable do line = __LINE__ @@ -37,6 +39,8 @@ describe 'TracePoint#inspect' do line = nil TracePoint.new(:call) { |tp| next unless TracePointSpec.target_thread? + next unless tp.path == __FILE__ + inspect ||= tp.inspect }.enable do line = __LINE__ + 1 @@ -52,6 +56,8 @@ describe 'TracePoint#inspect' do line = nil TracePoint.new(:return) { |tp| next unless TracePointSpec.target_thread? + next unless tp.path == __FILE__ + inspect ||= tp.inspect }.enable do line = __LINE__ + 4 @@ -61,6 +67,7 @@ describe 'TracePoint#inspect' do end trace_point_spec_test_return end + ruby_version_is("3.4") { line -= 1 } inspect.should =~ /\A#<TracePoint:return [`']trace_point_spec_test_return'#{@path_prefix}#{__FILE__}:#{line}>\z/ end @@ -69,6 +76,8 @@ describe 'TracePoint#inspect' do inspect = nil tracepoint = TracePoint.new(:c_call) { |tp| next unless TracePointSpec.target_thread? + next unless tp.path == __FILE__ + inspect ||= tp.inspect } line = __LINE__ + 2 @@ -84,6 +93,8 @@ describe 'TracePoint#inspect' do line = nil TracePoint.new(:class) { |tp| next unless TracePointSpec.target_thread? + next unless tp.path == __FILE__ + inspect ||= tp.inspect }.enable do line = __LINE__ + 1 @@ -100,6 +111,7 @@ describe 'TracePoint#inspect' do thread_inspection = nil TracePoint.new(:thread_begin) { |tp| next unless Thread.current == thread + inspect ||= tp.inspect }.enable(target_thread: nil) do thread = Thread.new {} @@ -116,6 +128,7 @@ describe 'TracePoint#inspect' do thread_inspection = nil TracePoint.new(:thread_end) { |tp| next unless Thread.current == thread + inspect ||= tp.inspect }.enable(target_thread: nil) do thread = Thread.new {} diff --git a/spec/ruby/core/warning/performance_warning_spec.rb b/spec/ruby/core/warning/performance_warning_spec.rb new file mode 100644 index 0000000000..ab0badcd3d --- /dev/null +++ b/spec/ruby/core/warning/performance_warning_spec.rb @@ -0,0 +1,28 @@ +require_relative '../../spec_helper' + + +describe "Performance warnings" do + guard -> { ruby_version_is("3.4") || RUBY_ENGINE == "truffleruby" } do + # Optimising Integer, Float or Symbol methods is kind of implementation detail + # but multiple implementations do so. So it seems reasonable to have a test case + # for at least one such common method. + # See https://bugs.ruby-lang.org/issues/20429 + context "when redefined optimised methods" do + it "emits performance warning for redefining Integer#+" do + code = <<~CODE + Warning[:performance] = true + + class Integer + ORIG_METHOD = instance_method(:+) + + def +(...) + ORIG_METHOD.bind(self).call(...) + end + end + CODE + + ruby_exe(code, args: "2>&1").should.include?("warning: Redefining 'Integer#+' disables interpreter and JIT optimizations") + end + end + end +end diff --git a/spec/ruby/core/warning/warn_spec.rb b/spec/ruby/core/warning/warn_spec.rb index 8f96fe9287..1c21fe29e0 100644 --- a/spec/ruby/core/warning/warn_spec.rb +++ b/spec/ruby/core/warning/warn_spec.rb @@ -121,6 +121,30 @@ describe "Warning.warn" do end end + ruby_bug '#19530', ''...'3.4' do + it "isn't called by Kernel.warn when category is :deprecated but Warning[:deprecated] is false" do + warn_deprecated = Warning[:deprecated] + begin + Warning[:deprecated] = false + Warning.should_not_receive(:warn) + Kernel.warn("foo", category: :deprecated) + ensure + Warning[:deprecated] = warn_deprecated + end + end + + it "isn't called by Kernel.warn when category is :experimental but Warning[:experimental] is false" do + warn_experimental = Warning[:experimental] + begin + Warning[:experimental] = false + Warning.should_not_receive(:warn) + Kernel.warn("foo", category: :experimental) + ensure + Warning[:experimental] = warn_experimental + end + end + end + it "prints the message when VERBOSE is false" do -> { Warning.warn("foo") }.should complain("foo") end diff --git a/spec/ruby/library/io-wait/fixtures/classes.rb b/spec/ruby/fixtures/io.rb index 837c7edd06..87ebbbb2bd 100644 --- a/spec/ruby/library/io-wait/fixtures/classes.rb +++ b/spec/ruby/fixtures/io.rb @@ -1,12 +1,12 @@ -module IOWaitSpec +module IOSpec def self.exhaust_write_buffer(io) written = 0 buf = " " * 4096 - begin + while true written += io.write_nonblock(buf) - rescue Errno::EAGAIN, Errno::EWOULDBLOCK - return written - end while true + end + rescue Errno::EAGAIN, Errno::EWOULDBLOCK + written end end diff --git a/spec/ruby/language/block_spec.rb b/spec/ruby/language/block_spec.rb index 578d9cb3b0..cf0931b688 100644 --- a/spec/ruby/language/block_spec.rb +++ b/spec/ruby/language/block_spec.rb @@ -960,24 +960,27 @@ describe "Post-args" do end describe "with a circular argument reference" do - it "raises a SyntaxError if using an existing local with the same name as the argument" do - a = 1 - -> { - @proc = eval "proc { |a=a| a }" - }.should raise_error(SyntaxError) + ruby_version_is ""..."3.4" do + it "raises a SyntaxError if using the argument in its default value" do + a = 1 + -> { + eval "proc { |a=a| a }" + }.should raise_error(SyntaxError) + end end - it "raises a SyntaxError if there is an existing method with the same name as the argument" do - def a; 1; end - -> { - @proc = eval "proc { |a=a| a }" - }.should raise_error(SyntaxError) + ruby_version_is "3.4" do + it "is nil if using the argument in its default value" do + -> { + eval "proc { |a=a| a }.call" + }.call.should == nil + end end + end - it "calls an existing method with the same name as the argument if explicitly using ()" do - def a; 1; end - proc { |a=a()| a }.call.should == 1 - end + it "calls an existing method with the same name as the argument if explicitly using ()" do + def a; 1; end + proc { |a=a()| a }.call.should == 1 end end diff --git a/spec/ruby/language/break_spec.rb b/spec/ruby/language/break_spec.rb index e725e77e80..7e5b6fb328 100644 --- a/spec/ruby/language/break_spec.rb +++ b/spec/ruby/language/break_spec.rb @@ -252,6 +252,25 @@ describe "Break inside a while loop" do end end +describe "The break statement in a method" do + it "is invalid and raises a SyntaxError" do + -> { + eval("def m; break; end") + }.should raise_error(SyntaxError) + end +end + +describe "The break statement in a module literal" do + it "is invalid and raises a SyntaxError" do + code = <<~RUBY + module BreakSpecs:ModuleWithBreak + break + end + RUBY + + -> { eval(code) }.should raise_error(SyntaxError) + end +end # TODO: Rewrite all the specs from here to the end of the file in the style # above. diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb index 3262f09dd5..464d06e46a 100644 --- a/spec/ruby/language/case_spec.rb +++ b/spec/ruby/language/case_spec.rb @@ -416,17 +416,34 @@ describe "The 'case'-construct" do self.test(true).should == true end - it "warns if there are identical when clauses" do - -> { - eval <<~RUBY - case 1 - when 2 - :foo - when 2 - :bar - end - RUBY - }.should complain(/warning: duplicated .when' clause with line \d+ is ignored/, verbose: true) + ruby_version_is ""..."3.4" do + it "warns if there are identical when clauses" do + -> { + eval <<~RUBY + case 1 + when 2 + :foo + when 2 + :bar + end + RUBY + }.should complain(/warning: (duplicated .when' clause with line \d+ is ignored|'when' clause on line \d+ duplicates 'when' clause on line \d+ and is ignored)/, verbose: true) + end + end + + ruby_version_is "3.4" do + it "warns if there are identical when clauses" do + -> { + eval <<~RUBY + case 1 + when 2 + :foo + when 2 + :bar + end + RUBY + }.should complain(/warning: 'when' clause on line \d+ duplicates 'when' clause on line \d+ and is ignored/, verbose: true) + end end end diff --git a/spec/ruby/language/def_spec.rb b/spec/ruby/language/def_spec.rb index 42e721c68c..ce8077eb69 100644 --- a/spec/ruby/language/def_spec.rb +++ b/spec/ruby/language/def_spec.rb @@ -197,15 +197,25 @@ describe "An instance method with a default argument" do foo(2,3,3).should == [2,3,[3]] end - it "raises a SyntaxError when there is an existing method with the same name as the local variable" do - def bar - 1 + ruby_version_is ""..."3.4" do + it "raises a SyntaxError if using the argument in its default value" do + -> { + eval "def foo(bar = bar) + bar + end" + }.should raise_error(SyntaxError) + end + end + + ruby_version_is "3.4" do + it "is nil if using the argument in its default value" do + -> { + eval "def foo(bar = bar) + bar + end + foo" + }.call.should == nil end - -> { - eval "def foo(bar = bar) - bar - end" - }.should raise_error(SyntaxError) end it "calls a method with the same name as the local when explicitly using ()" do diff --git a/spec/ruby/language/execution_spec.rb b/spec/ruby/language/execution_spec.rb index ef1de38899..51bcde62e8 100644 --- a/spec/ruby/language/execution_spec.rb +++ b/spec/ruby/language/execution_spec.rb @@ -38,7 +38,7 @@ describe "``" do 2.times do runner.instance_exec do - `test #{:command}` + `test #{:command}` # rubocop:disable Lint/LiteralInInterpolation end end @@ -84,7 +84,7 @@ describe "%x" do 2.times do runner.instance_exec do - %x{test #{:command}} + %x{test #{:command}} # rubocop:disable Lint/LiteralInInterpolation end end diff --git a/spec/ruby/language/for_spec.rb b/spec/ruby/language/for_spec.rb index 0ad5ea88af..b8ddfe5f0d 100644 --- a/spec/ruby/language/for_spec.rb +++ b/spec/ruby/language/for_spec.rb @@ -19,6 +19,27 @@ describe "The for expression" do end end + it "iterates over a list of arrays and destructures with an empty splat" do + for i, * in [[1,2]] + i.should == 1 + end + end + + it "iterates over a list of arrays and destructures with a splat" do + for i, *j in [[1,2]] + i.should == 1 + j.should == [2] + end + end + + it "iterates over a list of arrays and destructures with a splat and additional targets" do + for i, *j, k in [[1,2,3,4]] + i.should == 1 + j.should == [2,3] + k.should == 4 + end + end + it "iterates over an Hash passing each key-value pair to the block" do k = 0 l = 0 @@ -81,6 +102,88 @@ describe "The for expression" do end end + it "allows a global variable as an iterator name" do + old_global_var = $var + m = [1,2,3] + n = 0 + for $var in m + n += 1 + end + $var.should == 3 + n.should == 3 + $var = old_global_var + end + + it "allows an attribute as an iterator name" do + class OFor + attr_accessor :target + end + + ofor = OFor.new + m = [1,2,3] + n = 0 + for ofor.target in m + n += 1 + end + ofor.target.should == 3 + n.should == 3 + end + + # Segfault in MRI 3.3 and lower: https://bugs.ruby-lang.org/issues/20468 + ruby_bug "#20468", ""..."3.4" do + it "allows an attribute with safe navigation as an iterator name" do + class OFor + attr_accessor :target + end + + ofor = OFor.new + m = [1,2,3] + n = 0 + eval <<~RUBY + for ofor&.target in m + n += 1 + end + RUBY + ofor.target.should == 3 + n.should == 3 + end + + it "allows an attribute with safe navigation on a nil base as an iterator name" do + ofor = nil + m = [1,2,3] + n = 0 + eval <<~RUBY + for ofor&.target in m + n += 1 + end + RUBY + ofor.should be_nil + n.should == 3 + end + end + + it "allows an array index writer as an iterator name" do + arr = [:a, :b, :c] + m = [1,2,3] + n = 0 + for arr[1] in m + n += 1 + end + arr.should == [:a, 3, :c] + n.should == 3 + end + + it "allows a hash index writer as an iterator name" do + hash = { a: 10, b: 20, c: 30 } + m = [1,2,3] + n = 0 + for hash[:b] in m + n += 1 + end + hash.should == { a: 10, b: 3, c: 30 } + n.should == 3 + end + # 1.9 behaviour verified by nobu in # http://redmine.ruby-lang.org/issues/show/2053 it "yields only as many values as there are arguments" do diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb index a7631fb0d6..068ac0f39c 100644 --- a/spec/ruby/language/hash_spec.rb +++ b/spec/ruby/language/hash_spec.rb @@ -86,6 +86,30 @@ describe "Hash literal" do -> { eval("{:a ==> 1}") }.should raise_error(SyntaxError) end + it "recognizes '!' at the end of the key" do + eval("{:a! =>1}").should == {:"a!" => 1} + eval("{:a! => 1}").should == {:"a!" => 1} + + eval("{a!:1}").should == {:"a!" => 1} + eval("{a!: 1}").should == {:"a!" => 1} + end + + it "raises a SyntaxError if there is no space between `!` and `=>`" do + -> { eval("{:a!=> 1}") }.should raise_error(SyntaxError) + end + + it "recognizes '?' at the end of the key" do + eval("{:a? =>1}").should == {:"a?" => 1} + eval("{:a? => 1}").should == {:"a?" => 1} + + eval("{a?:1}").should == {:"a?" => 1} + eval("{a?: 1}").should == {:"a?" => 1} + end + + it "raises a SyntaxError if there is no space between `?` and `=>`" do + -> { eval("{:a?=> 1}") }.should raise_error(SyntaxError) + end + it "constructs a new hash with the given elements" do {foo: 123}.should == {foo: 123} h = {rbx: :cool, specs: 'fail_sometimes'} @@ -271,6 +295,14 @@ describe "The ** operator" do a.new.foo(1).should == {bar: "baz", val: 1} end + + it "raises a SyntaxError when the hash key ends with `!`" do + -> { eval("{a!:}") }.should raise_error(SyntaxError, /identifier a! is not valid to get/) + end + + it "raises a SyntaxError when the hash key ends with `?`" do + -> { eval("{a?:}") }.should raise_error(SyntaxError, /identifier a\? is not valid to get/) + end end end end diff --git a/spec/ruby/language/heredoc_spec.rb b/spec/ruby/language/heredoc_spec.rb index b3b160fd11..47ee9c2c51 100644 --- a/spec/ruby/language/heredoc_spec.rb +++ b/spec/ruby/language/heredoc_spec.rb @@ -106,4 +106,14 @@ HERE SquigglyHeredocSpecs.least_indented_on_the_first_line_single.should == "a\n b\n c\n" SquigglyHeredocSpecs.least_indented_on_the_last_line_single.should == " a\n b\nc\n" end + + it "reports line numbers inside HEREDOC with method call" do + -> { + <<-HERE.chomp + a + b + #{c} + HERE + }.should raise_error(NameError) { |e| e.backtrace[0].should.start_with?("#{__FILE__}:#{__LINE__ - 2}") } + end end diff --git a/spec/ruby/language/keyword_arguments_spec.rb b/spec/ruby/language/keyword_arguments_spec.rb index ffb5b1fab0..8668799d26 100644 --- a/spec/ruby/language/keyword_arguments_spec.rb +++ b/spec/ruby/language/keyword_arguments_spec.rb @@ -395,4 +395,32 @@ describe "Keyword arguments" do end end end + + context "in define_method(name, &proc)" do + # This tests that a free-standing proc used in define_method and converted to ruby2_keywords adopts that logic. + # See jruby/jruby#8119 for a case where aggressive JIT optimization broke later ruby2_keywords changes. + it "works with ruby2_keywords" do + m = Class.new do + def bar(a, foo: nil) + [a, foo] + end + + # define_method and ruby2_keywords using send to avoid peephole optimizations + def self.setup + pr = make_proc + send :define_method, :foo, &pr + send :ruby2_keywords, :foo + end + + # create proc in isolated method to force jit compilation on some implementations + def self.make_proc + proc { |a, *args| bar(a, *args) } + end + end + + m.setup + + m.new.foo(1, foo:2).should == [1, 2] + end + end end diff --git a/spec/ruby/language/lambda_spec.rb b/spec/ruby/language/lambda_spec.rb index 3ab3569ebe..ed5a1c69e8 100644 --- a/spec/ruby/language/lambda_spec.rb +++ b/spec/ruby/language/lambda_spec.rb @@ -263,18 +263,21 @@ describe "A lambda literal -> () { }" do end describe "with circular optional argument reference" do - it "raises a SyntaxError if using an existing local with the same name as the argument" do - a = 1 - -> { - @proc = eval "-> (a=a) { a }" - }.should raise_error(SyntaxError) + ruby_version_is ""..."3.4" do + it "raises a SyntaxError if using the argument in its default value" do + a = 1 + -> { + eval "-> (a=a) { a }" + }.should raise_error(SyntaxError) + end end - it "raises a SyntaxError if there is an existing method with the same name as the argument" do - def a; 1; end - -> { - @proc = eval "-> (a=a) { a }" - }.should raise_error(SyntaxError) + ruby_version_is "3.4" do + it "is nil if using the argument in its default value" do + -> { + eval "-> (a=a) { a }.call" + }.call.should == nil + end end it "calls an existing method with the same name as the argument if explicitly using ()" do diff --git a/spec/ruby/language/pattern_matching/3.1.rb b/spec/ruby/language/pattern_matching/3.1.rb new file mode 100644 index 0000000000..7a09084e41 --- /dev/null +++ b/spec/ruby/language/pattern_matching/3.1.rb @@ -0,0 +1,75 @@ +describe "Pattern matching" do + before :each do + ScratchPad.record [] + end + + describe "Ruby 3.1 improvements" do + ruby_version_is "3.1" do + it "can omit parentheses in one line pattern matching" do + [1, 2] => a, b + [a, b].should == [1, 2] + + {a: 1} => a: + a.should == 1 + end + + it "supports pinning instance variables" do + @a = /a/ + case 'abc' + in ^@a + true + end.should == true + end + + it "supports pinning class variables" do + result = nil + Module.new do + result = module_eval(<<~RUBY) + @@a = 0..10 + + case 2 + in ^@@a + true + end + RUBY + end + + result.should == true + end + + it "supports pinning global variables" do + $a = /a/ + case 'abc' + in ^$a + true + end.should == true + end + + it "supports pinning expressions" do + case 'abc' + in ^(/a/) + true + end.should == true + + case 0 + in ^(0 + 0) + true + end.should == true + end + + it "supports pinning expressions in array pattern" do + case [3] + in [^(1 + 2)] + true + end.should == true + end + + it "supports pinning expressions in hash pattern" do + case {name: '2.6', released_at: Time.new(2018, 12, 25)} + in {released_at: ^(Time.new(2010)..Time.new(2020))} + true + end.should == true + end + end + end +end diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb index a8ec078cd0..52608b48be 100644 --- a/spec/ruby/language/pattern_matching_spec.rb +++ b/spec/ruby/language/pattern_matching_spec.rb @@ -1,155 +1,143 @@ require_relative '../spec_helper' describe "Pattern matching" do - # TODO: Remove excessive eval calls when Ruby 3 is the minimum version. - # It is best to keep the eval's longer if other Ruby impls cannot parse pattern matching yet. - before :each do ScratchPad.record [] end - describe "can be standalone assoc operator that" do + describe "Rightward assignment (`=>`) that can be standalone assoc operator that" do it "deconstructs value" do suppress_warning do - eval(<<-RUBY).should == [0, 1] - [0, 1] => [a, b] - [a, b] - RUBY + [0, 1] => [a, b] + [a, b].should == [0, 1] end end it "deconstructs value and properly scopes variables" do suppress_warning do - eval(<<-RUBY).should == [0, nil] - a = nil - eval(<<-PATTERN) - [0, 1] => [a, b] - PATTERN - [a, defined?(b)] - RUBY + a = nil + 1.times { + [0, 1] => [a, b] + } + [a, defined?(b)].should == [0, nil] end end + + it "can work with keywords" do + { a: 0, b: 1 } => { a:, b: } + [a, b].should == [0, 1] + end + end + + describe "One-line pattern matching" do + it "can be used to check if a pattern matches for Array-like entities" do + ([0, 1] in [a, b]).should == true + ([0, 1] in [a, b, c]).should == false + end + + it "can be used to check if a pattern matches for Hash-like entities" do + ({ a: 0, b: 1 } in { a:, b: }).should == true + ({ a: 0, b: 1 } in { a:, b:, c: }).should == false + end end describe "find pattern" do it "captures preceding elements to the pattern" do - eval(<<~RUBY).should == [0, 1] - case [0, 1, 2, 3] - in [*pre, 2, 3] - pre - else - false - end - RUBY + case [0, 1, 2, 3] + in [*pre, 2, 3] + pre + else + false + end.should == [0, 1] end it "captures following elements to the pattern" do - eval(<<~RUBY).should == [2, 3] - case [0, 1, 2, 3] - in [0, 1, *post] - post - else - false - end - RUBY + case [0, 1, 2, 3] + in [0, 1, *post] + post + else + false + end.should == [2, 3] end it "captures both preceding and following elements to the pattern" do - eval(<<~RUBY).should == [[0, 1], [3, 4]] - case [0, 1, 2, 3, 4] - in [*pre, 2, *post] - [pre, post] - else - false - end - RUBY + case [0, 1, 2, 3, 4] + in [*pre, 2, *post] + [pre, post] + else + false + end.should == [[0, 1], [3, 4]] end it "can capture the entirety of the pattern" do - eval(<<~RUBY).should == [0, 1, 2, 3, 4] - case [0, 1, 2, 3, 4] - in [*everything] - everything - else - false - end - RUBY + case [0, 1, 2, 3, 4] + in [*everything] + everything + else + false + end.should == [0, 1, 2, 3, 4] end it "will match an empty Array-like structure" do - eval(<<~RUBY).should == [] - case [] - in [*everything] - everything - else - false - end - RUBY + case [] + in [*everything] + everything + else + false + end.should == [] end it "can be nested" do - eval(<<~RUBY).should == [[0, [2, 4, 6]], [[4, 16, 64]], 27] - case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]] - in [*pre, [*, 9, a], *post] - [pre, post, a] - else - false - end - RUBY + case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]] + in [*pre, [*, 9, a], *post] + [pre, post, a] + else + false + end.should == [[0, [2, 4, 6]], [[4, 16, 64]], 27] end it "can be nested with an array pattern" do - eval(<<~RUBY).should == [[4, 16, 64]] - case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]] - in [_, _, [*, 9, *], *post] - post - else - false - end - RUBY + case [0, [2, 4, 6], [3, 9, 27], [4, 16, 64]] + in [_, _, [*, 9, *], *post] + post + else + false + end.should == [[4, 16, 64]] end it "can be nested within a hash pattern" do - eval(<<~RUBY).should == [27] - case {a: [3, 9, 27]} - in {a: [*, 9, *post]} - post - else - false - end - RUBY + case {a: [3, 9, 27]} + in {a: [*, 9, *post]} + post + else + false + end.should == [27] end it "can nest hash and array patterns" do - eval(<<~RUBY).should == [42, 2] - case [0, {a: 42, b: [0, 1]}, {a: 42, b: [1, 2]}] - in [*, {a:, b: [1, c]}, *] - [a, c] - else - false - end - RUBY + case [0, {a: 42, b: [0, 1]}, {a: 42, b: [1, 2]}] + in [*, {a:, b: [1, c]}, *] + [a, c] + else + false + end.should == [42, 2] end end it "extends case expression with case/in construction" do - eval(<<~RUBY).should == :bar - case [0, 1] - in [0] - :foo - in [0, 1] - :bar - end - RUBY + case [0, 1] + in [0] + :foo + in [0, 1] + :bar + end.should == :bar end it "allows using then operator" do - eval(<<~RUBY).should == :bar - case [0, 1] - in [0] then :foo - in [0, 1] then :bar - end - RUBY + case [0, 1] + in [0] then :foo + in [0, 1] then :bar + end.should == :bar end describe "warning" do @@ -191,12 +179,10 @@ describe "Pattern matching" do end it "binds variables" do - eval(<<~RUBY).should == 1 - case [0, 1] - in [0, a] - a - end - RUBY + case [0, 1] + in [0, a] + a + end.should == 1 end it "cannot mix in and when operators" do @@ -220,47 +206,45 @@ describe "Pattern matching" do end it "checks patterns until the first matching" do - eval(<<~RUBY).should == :bar - case [0, 1] - in [0] - :foo - in [0, 1] - :bar - in [0, 1] - :baz - end - RUBY + case [0, 1] + in [0] + :foo + in [0, 1] + :bar + in [0, 1] + :baz + end.should == :bar end it "executes else clause if no pattern matches" do - eval(<<~RUBY).should == false - case [0, 1] - in [0] - true - else - false - end - RUBY + case [0, 1] + in [0] + true + else + false + end.should == false end it "raises NoMatchingPatternError if no pattern matches and no else clause" do -> { - eval <<~RUBY - case [0, 1] - in [0] - end - RUBY + case [0, 1] + in [0] + end }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) + + -> { + case {a: 0, b: 1} + in a: 1, b: 1 + end + }.should raise_error(NoMatchingPatternError, /\{:a=>0, :b=>1\}/) end it "raises NoMatchingPatternError if no pattern matches and evaluates the expression only once" do evals = 0 -> { - eval <<~RUBY - case (evals += 1; [0, 1]) - in [0] - end - RUBY + case (evals += 1; [0, 1]) + in [0] + end }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) evals.should == 1 end @@ -273,230 +257,185 @@ describe "Pattern matching" do true end RUBY - }.should raise_error(SyntaxError, /unexpected|expected a delimiter after the predicates of a `when` clause/) + }.should raise_error(SyntaxError, /unexpected|expected a delimiter after the patterns of an `in` clause/) end it "evaluates the case expression once for multiple patterns, caching the result" do - eval(<<~RUBY).should == true - case (ScratchPad << :foo; 1) - in 0 - false - in 1 - true - end - RUBY + case (ScratchPad << :foo; 1) + in 0 + false + in 1 + true + end.should == true ScratchPad.recorded.should == [:foo] end describe "guards" do it "supports if guard" do - eval(<<~RUBY).should == false - case 0 - in 0 if false - true - else - false - end - RUBY + case 0 + in 0 if false + true + else + false + end.should == false - eval(<<~RUBY).should == true - case 0 - in 0 if true - true - else - false - end - RUBY + case 0 + in 0 if true + true + else + false + end.should == true end it "supports unless guard" do - eval(<<~RUBY).should == false - case 0 - in 0 unless true - true - else - false - end - RUBY + case 0 + in 0 unless true + true + else + false + end.should == false - eval(<<~RUBY).should == true - case 0 - in 0 unless false - true - else - false - end - RUBY + case 0 + in 0 unless false + true + else + false + end.should == true end it "makes bound variables visible in guard" do - eval(<<~RUBY).should == true - case [0, 1] - in [a, 1] if a >= 0 - true - end - RUBY + case [0, 1] + in [a, 1] if a >= 0 + true + end.should == true end it "does not evaluate guard if pattern does not match" do - eval <<~RUBY - case 0 - in 1 if (ScratchPad << :foo) || true - else - end - RUBY + case 0 + in 1 if (ScratchPad << :foo) || true + else + end ScratchPad.recorded.should == [] end it "takes guards into account when there are several matching patterns" do - eval(<<~RUBY).should == :bar - case 0 - in 0 if false - :foo - in 0 if true - :bar - end - RUBY + case 0 + in 0 if false + :foo + in 0 if true + :bar + end.should == :bar end it "executes else clause if no guarded pattern matches" do - eval(<<~RUBY).should == false - case 0 - in 0 if false - true - else - false - end - RUBY + case 0 + in 0 if false + true + else + false + end.should == false end it "raises NoMatchingPatternError if no guarded pattern matches and no else clause" do -> { - eval <<~RUBY - case [0, 1] - in [0, 1] if false - end - RUBY + case [0, 1] + in [0, 1] if false + end }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) end end describe "value pattern" do it "matches an object such that pattern === object" do - eval(<<~RUBY).should == true - case 0 - in 0 - true - end - RUBY + case 0 + in 0 + true + end.should == true - eval(<<~RUBY).should == true - case 0 - in (-1..1) - true - end - RUBY + case 0 + in ( + -1..1) + true + end.should == true - eval(<<~RUBY).should == true - case 0 - in Integer - true - end - RUBY + case 0 + in Integer + true + end.should == true - eval(<<~RUBY).should == true - case "0" - in /0/ - true - end - RUBY + case "0" + in /0/ + true + end.should == true - eval(<<~RUBY).should == true - case "0" - in ->(s) { s == "0" } - true - end - RUBY + case "0" + in -> s { s == "0" } + true + end.should == true end it "allows string literal with interpolation" do x = "x" - eval(<<~RUBY).should == true - case "x" - in "#{x + ""}" - true - end - RUBY + case "x" + in "#{x + ""}" + true + end.should == true end end describe "variable pattern" do it "matches a value and binds variable name to this value" do - eval(<<~RUBY).should == 0 - case 0 - in a - a - end - RUBY + case 0 + in a + a + end.should == 0 end it "makes bounded variable visible outside a case statement scope" do - eval(<<~RUBY).should == 0 - case 0 - in a - end + case 0 + in a + end - a - RUBY + a.should == 0 end it "create local variables even if a pattern doesn't match" do - eval(<<~RUBY).should == [0, nil, nil] - case 0 - in a - in b - in c - end + case 0 + in a + in b + in c + end - [a, b, c] - RUBY + [a, b, c].should == [0, nil, nil] end it "allow using _ name to drop values" do - eval(<<~RUBY).should == 0 - case [0, 1] - in [a, _] - a - end - RUBY + case [0, 1] + in [a, _] + a + end.should == 0 end it "supports using _ in a pattern several times" do - eval(<<~RUBY).should == true - case [0, 1, 2] - in [0, _, _] - true - end - RUBY + case [0, 1, 2] + in [0, _, _] + true + end.should == true end it "supports using any name with _ at the beginning in a pattern several times" do - eval(<<~RUBY).should == true - case [0, 1, 2] - in [0, _x, _x] - true - end - RUBY + case [0, 1, 2] + in [0, _x, _x] + true + end.should == true - eval(<<~RUBY).should == true - case {a: 0, b: 1, c: 2} - in {a: 0, b: _x, c: _x} - true - end - RUBY + case {a: 0, b: 1, c: 2} + in {a: 0, b: _x, c: _x} + true + end.should == true end it "does not support using variable name (except _) several times" do @@ -512,30 +451,24 @@ describe "Pattern matching" do it "supports existing variables in a pattern specified with ^ operator" do a = 0 - eval(<<~RUBY).should == true - case 0 - in ^a - true - end - RUBY + case 0 + in ^a + true + end.should == true end it "allows applying ^ operator to bound variables" do - eval(<<~RUBY).should == 1 - case [1, 1] - in [n, ^n] - n - end - RUBY + case [1, 1] + in [n, ^n] + n + end.should == 1 - eval(<<~RUBY).should == false - case [1, 2] - in [n, ^n] - true - else - false - end - RUBY + case [1, 2] + in [n, ^n] + true + else + false + end.should == false end it "requires bound variable to be specified in a pattern before ^ operator when it relies on a bound variable" do @@ -554,12 +487,10 @@ describe "Pattern matching" do describe "alternative pattern" do it "matches if any of patterns matches" do - eval(<<~RUBY).should == true - case 0 - in 0 | 1 | 2 - true - end - RUBY + case 0 + in 0 | 1 | 2 + true + end.should == true end it "does not support variable binding" do @@ -573,120 +504,99 @@ describe "Pattern matching" do end it "support underscore prefixed variables in alternation" do - eval(<<~RUBY).should == true - case [0, 1] - in [1, _] - false - in [0, 0] | [0, _a] - true - end - RUBY + case [0, 1] + in [1, _] + false + in [0, 0] | [0, _a] + true + end.should == true end it "can be used as a nested pattern" do - eval(<<~RUBY).should == true - case [[1], ["2"]] - in [[0] | nil, _] - false - in [[1], [1]] - false - in [[1], [2 | "2"]] - true - end - RUBY + case [[1], ["2"]] + in [[0] | nil, _] + false + in [[1], [1]] + false + in [[1], [2 | "2"]] + true + end.should == true - eval(<<~RUBY).should == true - case [1, 2] - in [0, _] | {a: 0} - false - in {a: 1, b: 2} | [1, 2] - true - end - RUBY + case [1, 2] + in [0, _] | {a: 0} + false + in {a: 1, b: 2} | [1, 2] + true + end.should == true end end describe "AS pattern" do it "binds a variable to a value if pattern matches" do - eval(<<~RUBY).should == 0 - case 0 - in Integer => n - n - end - RUBY + case 0 + in Integer => n + n + end.should == 0 end it "can be used as a nested pattern" do - eval(<<~RUBY).should == [2, 3] - case [1, [2, 3]] - in [1, Array => ary] - ary - end - RUBY + case [1, [2, 3]] + in [1, Array => ary] + ary + end.should == [2, 3] end end describe "Array pattern" do it "supports form Constant(pat, pat, ...)" do - eval(<<~RUBY).should == true - case [0, 1, 2] - in Array(0, 1, 2) - true - end - RUBY + case [0, 1, 2] + in Array(0, 1, 2) + true + end.should == true end it "supports form Constant[pat, pat, ...]" do - eval(<<~RUBY).should == true - case [0, 1, 2] - in Array[0, 1, 2] - true - end - RUBY + case [0, 1, 2] + in Array[0, 1, 2] + true + end.should == true end it "supports form [pat, pat, ...]" do - eval(<<~RUBY).should == true - case [0, 1, 2] - in [0, 1, 2] - true - end - RUBY + case [0, 1, 2] + in [0, 1, 2] + true + end.should == true end it "supports form pat, pat, ..." do - eval(<<~RUBY).should == true - case [0, 1, 2] - in 0, 1, 2 - true - end - RUBY + case [0, 1, 2] + in 0, 1, 2 + true + end.should == true - eval(<<~RUBY).should == 1 - case [0, 1, 2] - in 0, a, 2 - a - end - RUBY + case [0, 1, 2] + in 0, a, 2 + a + end.should == 1 - eval(<<~RUBY).should == [1, 2] - case [0, 1, 2] - in 0, *rest - rest - end - RUBY + case [0, 1, 2] + in 0, *rest + rest + end.should == [1, 2] end it "matches an object with #deconstruct method which returns an array and each element in array matches element in pattern" do obj = Object.new - def obj.deconstruct; [0, 1] end - eval(<<~RUBY).should == true - case obj - in [Integer, Integer] - true - end - RUBY + def obj.deconstruct + [0, 1] + end + + case obj + in [Integer, Integer] + true + end.should == true end it "calls #deconstruct once for multiple patterns, caching the result" do @@ -697,314 +607,267 @@ describe "Pattern matching" do [0, 1] end - eval(<<~RUBY).should == true - case obj - in [1, 2] - false - in [0, 1] - true - end - RUBY + case obj + in [1, 2] + false + in [0, 1] + true + end.should == true ScratchPad.recorded.should == [:deconstruct] end it "calls #deconstruct even on objects that are already an array" do obj = [1, 2] + def obj.deconstruct ScratchPad << :deconstruct [3, 4] end - eval(<<~RUBY).should == true - case obj - in [3, 4] - true - else - false - end - RUBY + case obj + in [3, 4] + true + else + false + end.should == true ScratchPad.recorded.should == [:deconstruct] end it "does not match object if Constant === object returns false" do - eval(<<~RUBY).should == false - case [0, 1, 2] - in String[0, 1, 2] - true - else - false - end - RUBY + case [0, 1, 2] + in String[0, 1, 2] + true + else + false + end.should == false end it "checks Constant === object before calling #deconstruct" do c1 = Class.new obj = c1.new obj.should_not_receive(:deconstruct) - eval(<<~RUBY).should == false - case obj - in String[1] - true - else - false - end - RUBY + + case obj + in String[1] + true + else + false + end.should == false end it "does not match object without #deconstruct method" do obj = Object.new obj.should_receive(:respond_to?).with(:deconstruct) - eval(<<~RUBY).should == false - case obj - in Object[] - true - else - false - end - RUBY + case obj + in Object[] + true + else + false + end.should == false end it "raises TypeError if #deconstruct method does not return array" do obj = Object.new - def obj.deconstruct; "" end + + def obj.deconstruct + "" + end -> { - eval <<~RUBY - case obj - in Object[] - else - end - RUBY + case obj + in Object[] + else + end }.should raise_error(TypeError, /deconstruct must return Array/) end it "accepts a subclass of Array from #deconstruct" do obj = Object.new + def obj.deconstruct Class.new(Array).new([0, 1]) end - eval(<<~RUBY).should == true - case obj - in [1, 2] - false - in [0, 1] - true - end - RUBY + case obj + in [1, 2] + false + in [0, 1] + true + end.should == true end it "does not match object if elements of array returned by #deconstruct method does not match elements in pattern" do obj = Object.new - def obj.deconstruct; [1] end - eval(<<~RUBY).should == false - case obj - in Object[0] - true - else - false - end - RUBY + def obj.deconstruct + [1] + end + + case obj + in Object[0] + true + else + false + end.should == false end it "binds variables" do - eval(<<~RUBY).should == [0, 1, 2] - case [0, 1, 2] - in [a, b, c] - [a, b, c] - end - RUBY + case [0, 1, 2] + in [a, b, c] + [a, b, c] + end.should == [0, 1, 2] end it "supports splat operator *rest" do - eval(<<~RUBY).should == [1, 2] - case [0, 1, 2] - in [0, *rest] - rest - end - RUBY + case [0, 1, 2] + in [0, *rest] + rest + end.should == [1, 2] end it "does not match partially by default" do - eval(<<~RUBY).should == false - case [0, 1, 2, 3] - in [1, 2] - true - else - false - end - RUBY + case [0, 1, 2, 3] + in [1, 2] + true + else + false + end.should == false end it "does match partially from the array beginning if list + , syntax used" do - eval(<<~RUBY).should == true - case [0, 1, 2, 3] - in [0, 1,] - true - end - RUBY + case [0, 1, 2, 3] + in [0, 1, ] + true + end.should == true - eval(<<~RUBY).should == true - case [0, 1, 2, 3] - in 0, 1,; - true - end - RUBY + case [0, 1, 2, 3] + in 0, 1,; + true + end.should == true end it "matches [] with []" do - eval(<<~RUBY).should == true - case [] - in [] - true - end - RUBY + case [] + in [] + true + end.should == true end it "matches anything with *" do - eval(<<~RUBY).should == true - case [0, 1] - in *; - true - end - RUBY + case [0, 1] + in *; + true + end.should == true end it "can be used as a nested pattern" do - eval(<<~RUBY).should == true - case [[1], ["2"]] - in [[0] | nil, _] - false - in [[1], [1]] - false - in [[1], [2 | "2"]] - true - end - RUBY + case [[1], ["2"]] + in [[0] | nil, _] + false + in [[1], [1]] + false + in [[1], [2 | "2"]] + true + end.should == true - eval(<<~RUBY).should == true - case [1, 2] - in [0, _] | {a: 0} - false - in {a: 1, b: 2} | [1, 2] - true - end - RUBY + case [1, 2] + in [0, _] | {a: 0} + false + in {a: 1, b: 2} | [1, 2] + true + end.should == true end end describe "Hash pattern" do it "supports form Constant(id: pat, id: pat, ...)" do - eval(<<~RUBY).should == true - case {a: 0, b: 1} - in Hash(a: 0, b: 1) - true - end - RUBY + case {a: 0, b: 1} + in Hash(a: 0, b: 1) + true + end.should == true end it "supports form Constant[id: pat, id: pat, ...]" do - eval(<<~RUBY).should == true - case {a: 0, b: 1} - in Hash[a: 0, b: 1] - true - end - RUBY + case {a: 0, b: 1} + in Hash[a: 0, b: 1] + true + end.should == true end it "supports form {id: pat, id: pat, ...}" do - eval(<<~RUBY).should == true - case {a: 0, b: 1} - in {a: 0, b: 1} - true - end - RUBY + case {a: 0, b: 1} + in {a: 0, b: 1} + true + end.should == true end it "supports form id: pat, id: pat, ..." do - eval(<<~RUBY).should == true - case {a: 0, b: 1} - in a: 0, b: 1 - true - end - RUBY + case {a: 0, b: 1} + in a: 0, b: 1 + true + end.should == true - eval(<<~RUBY).should == [0, 1] - case {a: 0, b: 1} - in a: a, b: b - [a, b] - end - RUBY + case {a: 0, b: 1} + in a: a, b: b + [a, b] + end.should == [0, 1] - eval(<<~RUBY).should == { b: 1, c: 2 } - case {a: 0, b: 1, c: 2} - in a: 0, **rest - rest - end - RUBY + case {a: 0, b: 1, c: 2} + in a: 0, **rest + rest + end.should == {b: 1, c: 2} end it "supports a: which means a: a" do - eval(<<~RUBY).should == [0, 1] - case {a: 0, b: 1} - in Hash(a:, b:) - [a, b] - end - RUBY + case {a: 0, b: 1} + in Hash(a:, b:) + [a, b] + end.should == [0, 1] a = b = nil - eval(<<~RUBY).should == [0, 1] - case {a: 0, b: 1} - in Hash[a:, b:] - [a, b] - end - RUBY + + case {a: 0, b: 1} + in Hash[a:, b:] + [a, b] + end.should == [0, 1] a = b = nil - eval(<<~RUBY).should == [0, 1] - case {a: 0, b: 1} - in {a:, b:} - [a, b] - end - RUBY + + case {a: 0, b: 1} + in {a:, b:} + [a, b] + end.should == [0, 1] a = nil - eval(<<~RUBY).should == [0, {b: 1, c: 2}] - case {a: 0, b: 1, c: 2} - in {a:, **rest} - [a, rest] - end - RUBY + + case {a: 0, b: 1, c: 2} + in {a:, **rest} + [a, rest] + end.should == [0, {b: 1, c: 2}] a = b = nil - eval(<<~RUBY).should == [0, 1] - case {a: 0, b: 1} - in a:, b: - [a, b] - end - RUBY + + case {a: 0, b: 1} + in a:, b: + [a, b] + end.should == [0, 1] end it "can mix key (a:) and key-value (a: b) declarations" do - eval(<<~RUBY).should == [0, 1] - case {a: 0, b: 1} - in Hash(a:, b: x) - [a, x] - end - RUBY + case {a: 0, b: 1} + in Hash(a:, b: x) + [a, x] + end.should == [0, 1] end it "supports 'string': key literal" do - eval(<<~RUBY).should == true - case {a: 0} - in {"a": 0} - true - end - RUBY + case {a: 0} + in {"a": 0} + true + end.should == true end it "does not support non-symbol keys" do @@ -1018,8 +881,6 @@ describe "Pattern matching" do end it "does not support string interpolation in keys" do - x = "a" - -> { eval <<~'RUBY' case {a: 1} @@ -1041,14 +902,15 @@ describe "Pattern matching" do it "matches an object with #deconstruct_keys method which returns a Hash with equal keys and each value in Hash matches value in pattern" do obj = Object.new - def obj.deconstruct_keys(*); {a: 1} end - eval(<<~RUBY).should == true - case obj - in {a: 1} - true - end - RUBY + def obj.deconstruct_keys(*) + {a: 1} + end + + case obj + in {a: 1} + true + end.should == true end it "calls #deconstruct_keys per pattern" do @@ -1059,96 +921,92 @@ describe "Pattern matching" do {a: 1} end - eval(<<~RUBY).should == true - case obj - in {b: 1} - false - in {a: 1} - true - end - RUBY + case obj + in {b: 1} + false + in {a: 1} + true + end.should == true ScratchPad.recorded.should == [:deconstruct_keys, :deconstruct_keys] end it "does not match object if Constant === object returns false" do - eval(<<~RUBY).should == false - case {a: 1} - in String[a: 1] - true - else - false - end - RUBY + case {a: 1} + in String[a: 1] + true + else + false + end.should == false end it "checks Constant === object before calling #deconstruct_keys" do c1 = Class.new obj = c1.new obj.should_not_receive(:deconstruct_keys) - eval(<<~RUBY).should == false - case obj - in String(a: 1) - true - else - false - end - RUBY + + case obj + in String(a: 1) + true + else + false + end.should == false end it "does not match object without #deconstruct_keys method" do obj = Object.new obj.should_receive(:respond_to?).with(:deconstruct_keys) - eval(<<~RUBY).should == false - case obj - in Object[a: 1] - true - else - false - end - RUBY + case obj + in Object[a: 1] + true + else + false + end.should == false end it "does not match object if #deconstruct_keys method does not return Hash" do obj = Object.new - def obj.deconstruct_keys(*); "" end + + def obj.deconstruct_keys(*) + "" + end -> { - eval <<~RUBY - case obj - in Object[a: 1] - end - RUBY + case obj + in Object[a: 1] + end }.should raise_error(TypeError, /deconstruct_keys must return Hash/) end it "does not match object if #deconstruct_keys method returns Hash with non-symbol keys" do obj = Object.new - def obj.deconstruct_keys(*); {"a" => 1} end - eval(<<~RUBY).should == false - case obj - in Object[a: 1] - true - else - false - end - RUBY + def obj.deconstruct_keys(*) + {"a" => 1} + end + + case obj + in Object[a: 1] + true + else + false + end.should == false end it "does not match object if elements of Hash returned by #deconstruct_keys method does not match values in pattern" do obj = Object.new - def obj.deconstruct_keys(*); {a: 1} end - eval(<<~RUBY).should == false - case obj - in Object[a: 2] - true - else - false - end - RUBY + def obj.deconstruct_keys(*) + {a: 1} + end + + case obj + in Object[a: 2] + true + else + false + end.should == false end it "passes keys specified in pattern as arguments to #deconstruct_keys method" do @@ -1159,11 +1017,9 @@ describe "Pattern matching" do {a: 1, b: 2, c: 3} end - eval <<~RUBY - case obj - in Object[a: 1, b: 2, c: 3] - end - RUBY + case obj + in Object[a: 1, b: 2, c: 3] + end ScratchPad.recorded.sort.should == [[[:a, :b, :c]]] end @@ -1176,11 +1032,9 @@ describe "Pattern matching" do {a: 1, b: 2, c: 3} end - eval <<~RUBY - case obj - in Object[a: 1, b: 2, **] - end - RUBY + case obj + in Object[a: 1, b: 2, **] + end ScratchPad.recorded.sort.should == [[[:a, :b]]] end @@ -1193,131 +1047,105 @@ describe "Pattern matching" do {a: 1, b: 2} end - eval <<~RUBY - case obj - in Object[a: 1, **rest] - end - RUBY + case obj + in Object[a: 1, **rest] + end ScratchPad.recorded.should == [[nil]] end it "binds variables" do - eval(<<~RUBY).should == [0, 1, 2] - case {a: 0, b: 1, c: 2} - in {a: x, b: y, c: z} - [x, y, z] - end - RUBY + case {a: 0, b: 1, c: 2} + in {a: x, b: y, c: z} + [x, y, z] + end.should == [0, 1, 2] end it "supports double splat operator **rest" do - eval(<<~RUBY).should == {b: 1, c: 2} - case {a: 0, b: 1, c: 2} - in {a: 0, **rest} - rest - end - RUBY + case {a: 0, b: 1, c: 2} + in {a: 0, **rest} + rest + end.should == {b: 1, c: 2} end it "treats **nil like there should not be any other keys in a matched Hash" do - eval(<<~RUBY).should == true - case {a: 1, b: 2} - in {a: 1, b: 2, **nil} - true - end - RUBY + case {a: 1, b: 2} + in {a: 1, b: 2, **nil} + true + end.should == true - eval(<<~RUBY).should == false - case {a: 1, b: 2} - in {a: 1, **nil} - true - else - false - end - RUBY + case {a: 1, b: 2} + in {a: 1, **nil} + true + else + false + end.should == false end it "can match partially" do - eval(<<~RUBY).should == true - case {a: 1, b: 2} - in {a: 1} - true - end - RUBY + case {a: 1, b: 2} + in {a: 1} + true + end.should == true end it "matches {} with {}" do - eval(<<~RUBY).should == true - case {} - in {} - true - end - RUBY + case {} + in {} + true + end.should == true end it "in {} only matches empty hashes" do - eval(<<~RUBY).should == false - case {a: 1} - in {} - true - else - false - end - RUBY + case {a: 1} + in {} + true + else + false + end.should == false end it "in {**nil} only matches empty hashes" do - eval(<<~RUBY).should == true - case {} - in {**nil} - true - else - false - end - RUBY + case {} + in {**nil} + true + else + false + end.should == true - eval(<<~RUBY).should == false - case {a: 1} - in {**nil} - true - else - false - end - RUBY + case {a: 1} + in {**nil} + true + else + false + end.should == false end it "matches anything with **" do - eval(<<~RUBY).should == true - case {a: 1} - in **; - true - end - RUBY + case {a: 1} + in **; + true + end.should == true end it "can be used as a nested pattern" do - eval(<<~RUBY).should == true - case {a: {a: 1, b: 1}, b: {a: 1, b: 2}} - in {a: {a: 0}} - false - in {a: {a: 1}, b: {b: 1}} - false - in {a: {a: 1}, b: {b: 2}} - true - end - RUBY + case {a: {a: 1, b: 1}, b: {a: 1, b: 2}} + in {a: {a: 0}} + false + in {a: {a: 1}, b: {b: 1}} + false + in {a: {a: 1}, b: {b: 2} } + true + end.should == true - eval(<<~RUBY).should == true - case [{a: 1, b: [1]}, {a: 1, c: ["2"]}] - in [{a:, c:},] - false - in [{a: 1, b:}, {a: 1, c: [Integer]}] - false - in [_, {a: 1, c: [String]}] - true - end - RUBY + case [{a: 1, b: [1]}, {a: 1, c: ["2"]}] + in [{a:, c:}, ] + false + in [{a: 1, b:}, {a: 1, c: [Integer]}] + false + in [_, {a: 1, c: [String]}] + true + end.should == true end end @@ -1335,12 +1163,11 @@ describe "Pattern matching" do Module.new do using refinery - result = eval(<<~RUBY) + result = case [] in [0] true end - RUBY end result.should == true @@ -1359,12 +1186,11 @@ describe "Pattern matching" do Module.new do using refinery - result = eval(<<~RUBY) + result = case {} in a: 0 true end - RUBY end result.should == true @@ -1383,127 +1209,18 @@ describe "Pattern matching" do Module.new do using refinery - result = eval(<<~RUBY) + result = case {} in Array true end - RUBY end result.should == true end end +end - describe "Ruby 3.1 improvements" do - ruby_version_is "3.1" do - it "can omit parentheses in one line pattern matching" do - eval(<<~RUBY).should == [1, 2] - [1, 2] => a, b - [a, b] - RUBY - - eval(<<~RUBY).should == 1 - {a: 1} => a: - a - RUBY - end - - it "supports pinning instance variables" do - eval(<<~RUBY).should == true - @a = /a/ - case 'abc' - in ^@a - true - end - RUBY - end - - it "supports pinning class variables" do - result = nil - Module.new do - result = module_eval(<<~RUBY) - @@a = 0..10 - - case 2 - in ^@@a - true - end - RUBY - end - - result.should == true - end - - it "supports pinning global variables" do - eval(<<~RUBY).should == true - $a = /a/ - case 'abc' - in ^$a - true - end - RUBY - end - - it "supports pinning expressions" do - eval(<<~RUBY).should == true - case 'abc' - in ^(/a/) - true - end - RUBY - - eval(<<~RUBY).should == true - case 0 - in ^(0+0) - true - end - RUBY - end - - it "supports pinning expressions in array pattern" do - eval(<<~RUBY).should == true - case [3] - in [^(1+2)] - true - end - RUBY - end - - it "supports pinning expressions in hash pattern" do - eval(<<~RUBY).should == true - case {name: '2.6', released_at: Time.new(2018, 12, 25)} - in {released_at: ^(Time.new(2010)..Time.new(2020))} - true - end - RUBY - end - end - end - - describe "value in pattern" do - it "returns true if the pattern matches" do - eval("1 in 1").should == true - - eval("1 in Integer").should == true - - e = nil - eval("[1, 2] in [1, e]").should == true - e.should == 2 - - k = nil - eval("{k: 1} in {k:}").should == true - k.should == 1 - end - - it "returns false if the pattern does not match" do - eval("1 in 2").should == false - - eval("1 in Float").should == false - - eval("[1, 2] in [2, e]").should == false - - eval("{k: 1} in {k: 2}").should == false - end - end +ruby_version_is "3.1" do + require_relative 'pattern_matching/3.1' end diff --git a/spec/ruby/language/regexp/back-references_spec.rb b/spec/ruby/language/regexp/back-references_spec.rb index 26750c20c5..627c8daace 100644 --- a/spec/ruby/language/regexp/back-references_spec.rb +++ b/spec/ruby/language/regexp/back-references_spec.rb @@ -22,6 +22,15 @@ describe "Regexps with back-references" do $10.should == "0" end + it "returns nil for numbered variable with too large index" do + -> { + eval(<<~CODE).should == nil + "a" =~ /(.)/ + eval('$4294967296') + CODE + }.should complain(/warning: ('|`)\$4294967296' is too big for a number variable, always nil/) + end + it "will not clobber capture variables across threads" do cap1, cap2, cap3 = nil "foo" =~ /(o+)/ diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb index a3ee4807ac..4dc25a5b45 100644 --- a/spec/ruby/language/rescue_spec.rb +++ b/spec/ruby/language/rescue_spec.rb @@ -52,6 +52,16 @@ describe "The rescue keyword" do RescueSpecs::SafeNavigationSetterCaptor.should_capture_exception end + it 'using a safely navigated setter method on a nil target' do + target = nil + begin + raise SpecificExampleException, "Raising this to be handled below" + rescue SpecificExampleException => target&.captured_error + :caught + end.should == :caught + target.should be_nil + end + it 'using a setter method' do RescueSpecs::SetterCaptor.should_capture_exception end diff --git a/spec/ruby/language/retry_spec.rb b/spec/ruby/language/retry_spec.rb index ee5377946f..669d5f0ff5 100644 --- a/spec/ruby/language/retry_spec.rb +++ b/spec/ruby/language/retry_spec.rb @@ -31,8 +31,11 @@ describe "The retry statement" do results.should == [1, 2, 3, 1, 2, 4, 5, 6, 4, 5] end - it "raises a SyntaxError when used outside of a begin statement" do + it "raises a SyntaxError when used outside of a rescue statement" do -> { eval 'retry' }.should raise_error(SyntaxError) + -> { eval 'begin; retry; end' }.should raise_error(SyntaxError) + -> { eval 'def m; retry; end' }.should raise_error(SyntaxError) + -> { eval 'module RetrySpecs; retry; end' }.should raise_error(SyntaxError) end end diff --git a/spec/ruby/language/yield_spec.rb b/spec/ruby/language/yield_spec.rb index 5283517636..e125cf8e73 100644 --- a/spec/ruby/language/yield_spec.rb +++ b/spec/ruby/language/yield_spec.rb @@ -206,3 +206,15 @@ describe "Using yield in non-lambda block" do -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/) end end + +describe "Using yield in a module literal" do + it 'raises a SyntaxError' do + code = <<~RUBY + module YieldSpecs::ModuleWithYield + yield + end + RUBY + + -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/) + end +end diff --git a/spec/ruby/library/bigdecimal/sqrt_spec.rb b/spec/ruby/library/bigdecimal/sqrt_spec.rb index 8fd1ec0f39..42cf4545cb 100644 --- a/spec/ruby/library/bigdecimal/sqrt_spec.rb +++ b/spec/ruby/library/bigdecimal/sqrt_spec.rb @@ -36,7 +36,7 @@ describe "BigDecimal#sqrt" do BigDecimal('121').sqrt(5).should be_close(11, 0.00001) end - platform_is_not wordsize: 32 do # fails on i686 + platform_is_not c_long_size: 32 do # fails on i686 it "returns square root of 0.9E-99999 with desired precision" do @frac_2.sqrt(1).to_s.should =~ /\A0\.3E-49999\z/i end diff --git a/spec/ruby/library/coverage/fixtures/code_with_begin.rb b/spec/ruby/library/coverage/fixtures/code_with_begin.rb new file mode 100644 index 0000000000..9a6384e337 --- /dev/null +++ b/spec/ruby/library/coverage/fixtures/code_with_begin.rb @@ -0,0 +1,3 @@ +begin + 'coverage with begin' +end diff --git a/spec/ruby/library/coverage/result_spec.rb b/spec/ruby/library/coverage/result_spec.rb index 33276778e8..54a3249e45 100644 --- a/spec/ruby/library/coverage/result_spec.rb +++ b/spec/ruby/library/coverage/result_spec.rb @@ -6,6 +6,7 @@ describe 'Coverage.result' do @class_file = fixture __FILE__, 'some_class.rb' @config_file = fixture __FILE__, 'start_coverage.rb' @eval_code_file = fixture __FILE__, 'eval_code.rb' + @with_begin_file = fixture __FILE__, 'code_with_begin.rb' end before :each do @@ -16,6 +17,7 @@ describe 'Coverage.result' do $LOADED_FEATURES.delete(@class_file) $LOADED_FEATURES.delete(@config_file) $LOADED_FEATURES.delete(@eval_code_file) + $LOADED_FEATURES.delete(@with_begin_file) Coverage.result if Coverage.running? end @@ -354,4 +356,16 @@ describe 'Coverage.result' do Coverage.peek_result.should == result end + + it 'covers 100% lines with begin' do + Coverage.start + require @with_begin_file.chomp('.rb') + result = Coverage.result + + result.should == { + @with_begin_file => [ + nil, 1, nil + ] + } + end end diff --git a/spec/ruby/library/date/accessor_spec.rb b/spec/ruby/library/date/accessor_spec.rb index 68a2d9f3de..74ed0e9c21 100644 --- a/spec/ruby/library/date/accessor_spec.rb +++ b/spec/ruby/library/date/accessor_spec.rb @@ -38,7 +38,7 @@ describe "Date#year" do end describe "Date#yday" do - it "determines the year" do + it "determines the day of the year" do Date.civil(2007, 1, 17).yday.should == 17 Date.civil(2008, 10, 28).yday.should == 302 end diff --git a/spec/ruby/library/time/to_date_spec.rb b/spec/ruby/library/date/time/to_date_spec.rb index baeafe0847..f9132da289 100644 --- a/spec/ruby/library/time/to_date_spec.rb +++ b/spec/ruby/library/date/time/to_date_spec.rb @@ -1,5 +1,5 @@ -require_relative '../../spec_helper' +require_relative '../../../spec_helper' require 'time' describe "Time#to_date" do diff --git a/spec/ruby/library/date/yday_spec.rb b/spec/ruby/library/date/yday_spec.rb index cfb174a4c2..7dd42e52a5 100644 --- a/spec/ruby/library/date/yday_spec.rb +++ b/spec/ruby/library/date/yday_spec.rb @@ -1,6 +1,7 @@ require_relative '../../spec_helper' +require_relative '../../shared/time/yday' require 'date' describe "Date#yday" do - it "needs to be reviewed for spec completeness" + it_behaves_like :time_yday, -> year, month, day { Date.new(year, month, day).yday } end diff --git a/spec/ruby/library/time/to_datetime_spec.rb b/spec/ruby/library/datetime/time/to_datetime_spec.rb index 9c44f38e5c..1125dbe851 100644 --- a/spec/ruby/library/time/to_datetime_spec.rb +++ b/spec/ruby/library/datetime/time/to_datetime_spec.rb @@ -1,4 +1,4 @@ -require_relative '../../spec_helper' +require_relative '../../../spec_helper' require 'time' require 'date' date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0' diff --git a/spec/ruby/library/datetime/yday_spec.rb b/spec/ruby/library/datetime/yday_spec.rb new file mode 100644 index 0000000000..08a72c6480 --- /dev/null +++ b/spec/ruby/library/datetime/yday_spec.rb @@ -0,0 +1,7 @@ +require_relative '../../spec_helper' +require_relative '../../shared/time/yday' +require 'date' + +describe "DateTime#yday" do + it_behaves_like :time_yday, -> year, month, day { DateTime.new(year, month, day).yday } +end diff --git a/spec/ruby/library/find/fixtures/common.rb b/spec/ruby/library/find/fixtures/common.rb index 14a7edb09a..99f3bbb45a 100644 --- a/spec/ruby/library/find/fixtures/common.rb +++ b/spec/ruby/library/find/fixtures/common.rb @@ -71,13 +71,17 @@ module FindDirSpecs end def self.create_mock_dirs + tmp('') # make sure there is an tmpdir umask = File.umask 0 - mock_dir_files.each do |name| - file = File.join mock_dir, name - mkdir_p File.dirname(file) - touch file + begin + mock_dir_files.each do |name| + file = File.join mock_dir, name + mkdir_p File.dirname(file) + touch file + end + ensure + File.umask umask end - File.umask umask end def self.delete_mock_dirs diff --git a/spec/ruby/library/io-wait/wait_readable_spec.rb b/spec/ruby/library/io-wait/wait_readable_spec.rb index 06ffbda5c8..df25fdb931 100644 --- a/spec/ruby/library/io-wait/wait_readable_spec.rb +++ b/spec/ruby/library/io-wait/wait_readable_spec.rb @@ -24,4 +24,23 @@ describe "IO#wait_readable" do it "waits for the IO to become readable with the given large timeout" do @io.wait_readable(365 * 24 * 60 * 60).should == @io end + + it "can be interrupted" do + rd, wr = IO.pipe + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + rd.wait_readable(10) + end + + Thread.pass until t.stop? + t.kill + t.join + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + ensure + rd.close + wr.close + end end diff --git a/spec/ruby/library/io-wait/wait_spec.rb b/spec/ruby/library/io-wait/wait_spec.rb index fc07c6a8d9..5952f127f7 100644 --- a/spec/ruby/library/io-wait/wait_spec.rb +++ b/spec/ruby/library/io-wait/wait_spec.rb @@ -1,5 +1,5 @@ require_relative '../../spec_helper' -require_relative 'fixtures/classes' +require_relative '../../fixtures/io' ruby_version_is ''...'3.2' do require 'io/wait' @@ -55,7 +55,7 @@ describe "IO#wait" do end it "waits for the WRITABLE event to be ready" do - written_bytes = IOWaitSpec.exhaust_write_buffer(@w) + written_bytes = IOSpec.exhaust_write_buffer(@w) @w.wait(IO::WRITABLE, 0).should == nil @r.read(written_bytes) @@ -67,7 +67,7 @@ describe "IO#wait" do end it "returns nil when the WRITABLE event is not ready during the timeout" do - IOWaitSpec.exhaust_write_buffer(@w) + IOSpec.exhaust_write_buffer(@w) @w.wait(IO::WRITABLE, 0).should == nil end @@ -92,7 +92,7 @@ describe "IO#wait" do end it "changes thread status to 'sleep' when waits for WRITABLE event" do - written_bytes = IOWaitSpec.exhaust_write_buffer(@w) + IOSpec.exhaust_write_buffer(@w) t = Thread.new { @w.wait(IO::WRITABLE, 10) } sleep 1 @@ -100,6 +100,37 @@ describe "IO#wait" do t.kill t.join # Thread#kill doesn't wait for the thread to end end + + it "can be interrupted when waiting for READABLE event" do + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + @r.wait(IO::READABLE, 10) + end + + Thread.pass until t.stop? + t.kill + t.join # Thread#kill doesn't wait for the thread to end + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + end + + it "can be interrupted when waiting for WRITABLE event" do + IOSpec.exhaust_write_buffer(@w) + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + @w.wait(IO::WRITABLE, 10) + end + + Thread.pass until t.stop? + t.kill + t.join # Thread#kill doesn't wait for the thread to end + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + end end context "[timeout, mode] passed" do diff --git a/spec/ruby/library/io-wait/wait_writable_spec.rb b/spec/ruby/library/io-wait/wait_writable_spec.rb index 8c44780d39..8639dd717b 100644 --- a/spec/ruby/library/io-wait/wait_writable_spec.rb +++ b/spec/ruby/library/io-wait/wait_writable_spec.rb @@ -1,4 +1,5 @@ require_relative '../../spec_helper' +require_relative '../../fixtures/io' ruby_version_is ''...'3.2' do require 'io/wait' @@ -17,4 +18,24 @@ describe "IO#wait_writable" do # Represents one year and is larger than a 32-bit int STDOUT.wait_writable(365 * 24 * 60 * 60).should == STDOUT end + + it "can be interrupted" do + rd, wr = IO.pipe + IOSpec.exhaust_write_buffer(wr) + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + wr.wait_writable(10) + end + + Thread.pass until t.stop? + t.kill + t.join + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + ensure + rd.close unless rd.closed? + wr.close unless wr.closed? + end end diff --git a/spec/ruby/library/net-ftp/shared/puttextfile.rb b/spec/ruby/library/net-ftp/shared/puttextfile.rb index 4722439674..e2c0453352 100644 --- a/spec/ruby/library/net-ftp/shared/puttextfile.rb +++ b/spec/ruby/library/net-ftp/shared/puttextfile.rb @@ -34,8 +34,16 @@ describe :net_ftp_puttextfile, shared: true do remote_lines.should == local_lines.gsub("\n", "\r\n") end - it "returns nil" do - @ftp.send(@method, @local_fixture_file, "text").should be_nil + guard -> { Net::FTP::VERSION < '0.3.6' } do + it "returns nil" do + @ftp.send(@method, @local_fixture_file, "text").should be_nil + end + end + + guard -> { Net::FTP::VERSION >= '0.3.6' } do + it "returns the response" do + @ftp.send(@method, @local_fixture_file, "text").should == @ftp.last_response + end end describe "when passed a block" do diff --git a/spec/ruby/library/rbconfig/rbconfig_spec.rb b/spec/ruby/library/rbconfig/rbconfig_spec.rb index b90cc90970..3e06219621 100644 --- a/spec/ruby/library/rbconfig/rbconfig_spec.rb +++ b/spec/ruby/library/rbconfig/rbconfig_spec.rb @@ -88,6 +88,30 @@ describe 'RbConfig::CONFIG' do end end end + + guard -> { %w[aarch64 arm64].include? RbConfig::CONFIG['host_cpu'] } do + it "['host_cpu'] returns CPU architecture properly for AArch64" do + platform_is :darwin do + RbConfig::CONFIG['host_cpu'].should == 'arm64' + end + + platform_is_not :darwin do + RbConfig::CONFIG['host_cpu'].should == 'aarch64' + end + end + end + + guard -> { platform_is(:linux) || platform_is(:darwin) } do + it "['host_os'] returns a proper OS name or platform" do + platform_is :darwin do + RbConfig::CONFIG['host_os'].should.match?(/darwin/) + end + + platform_is :linux do + RbConfig::CONFIG['host_os'].should.match?(/linux/) + end + end + end end describe "RbConfig::TOPDIR" do @@ -99,3 +123,34 @@ describe "RbConfig::TOPDIR" do end end end + +describe "RUBY_PLATFORM" do + it "RUBY_PLATFORM contains a proper CPU architecture" do + RUBY_PLATFORM.should.include? RbConfig::CONFIG['host_cpu'] + end + + guard -> { platform_is(:linux) || platform_is(:darwin) } do + it "RUBY_PLATFORM contains OS name" do + # don't use RbConfig::CONFIG['host_os'] as far as it could be slightly different, e.g. linux-gnu + platform_is(:linux) do + RUBY_PLATFORM.should.include? 'linux' + end + + platform_is(:darwin) do + RUBY_PLATFORM.should.include? 'darwin' + end + end + end +end + +describe "RUBY_DESCRIPTION" do + guard_not -> { RUBY_ENGINE == "ruby" && !RbConfig::TOPDIR } do + it "contains version" do + RUBY_DESCRIPTION.should.include? RUBY_VERSION + end + + it "contains RUBY_PLATFORM" do + RUBY_DESCRIPTION.should.include? RUBY_PLATFORM + end + end +end diff --git a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb index 17c846054d..df42c116fb 100644 --- a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb @@ -52,9 +52,19 @@ describe "Socket::BasicSocket#recv_nonblock" do @s2.send("data", 0, @s1.getsockname) IO.select([@s1], nil, nil, 2) - buf = +"foo" - @s1.recv_nonblock(5, 0, buf) - buf.should == "data" + buffer = +"foo" + @s1.recv_nonblock(5, 0, buffer).should.equal?(buffer) + buffer.should == "data" + end + + it "preserves the encoding of the given buffer" do + @s1.bind(Socket.pack_sockaddr_in(0, ip_address)) + @s2.send("data", 0, @s1.getsockname) + IO.select([@s1], nil, nil, 2) + + buffer = ''.encode(Encoding::ISO_8859_1) + @s1.recv_nonblock(5, 0, buffer) + buffer.encoding.should == Encoding::ISO_8859_1 end it "does not block if there's no data available" do diff --git a/spec/ruby/library/socket/basicsocket/recv_spec.rb b/spec/ruby/library/socket/basicsocket/recv_spec.rb index 9fe8c52f9a..e82a357d3d 100644 --- a/spec/ruby/library/socket/basicsocket/recv_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recv_spec.rb @@ -100,13 +100,29 @@ describe "BasicSocket#recv" do socket.write("data") client = @server.accept - buf = +"foo" + buffer = +"foo" begin - client.recv(4, 0, buf) + client.recv(4, 0, buffer).should.equal?(buffer) ensure client.close end - buf.should == "data" + buffer.should == "data" + + socket.close + end + + it "preserves the encoding of the given buffer" do + socket = TCPSocket.new('127.0.0.1', @port) + socket.write("data") + + client = @server.accept + buffer = ''.encode(Encoding::ISO_8859_1) + begin + client.recv(4, 0, buffer) + ensure + client.close + end + buffer.encoding.should == Encoding::ISO_8859_1 socket.close end diff --git a/spec/ruby/library/socket/ipsocket/getaddress_spec.rb b/spec/ruby/library/socket/ipsocket/getaddress_spec.rb index 96324982e5..329f8267d3 100644 --- a/spec/ruby/library/socket/ipsocket/getaddress_spec.rb +++ b/spec/ruby/library/socket/ipsocket/getaddress_spec.rb @@ -2,7 +2,6 @@ require_relative '../spec_helper' require_relative '../fixtures/classes' describe "Socket::IPSocket#getaddress" do - it "returns the IP address of hostname" do addr_local = IPSocket.getaddress(SocketSpecs.hostname) ["127.0.0.1", "::1"].include?(addr_local).should == true @@ -14,6 +13,10 @@ describe "Socket::IPSocket#getaddress" do IPSocket.getaddress('::1').should == '::1' end + it 'returns IPv4 compatible IPv6 addresses' do + IPSocket.getaddress('::ffff:192.168.1.1').should == '::ffff:192.168.1.1' + end + # There is no way to make this fail-proof on all machines, because # DNS servers like opendns return A records for ANY host, including # traditionally invalidly named ones. diff --git a/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb b/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb index 94f58ac49f..5596f91bb8 100644 --- a/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb +++ b/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb @@ -52,6 +52,27 @@ describe 'Socket#recvfrom_nonblock' do end end + it "allows an output buffer as third argument" do + @client.write('hello') + + IO.select([@server]) + buffer = +'' + message, = @server.recvfrom_nonblock(5, 0, buffer) + + message.should.equal?(buffer) + buffer.should == 'hello' + end + + it "preserves the encoding of the given buffer" do + @client.write('hello') + + IO.select([@server]) + buffer = ''.encode(Encoding::ISO_8859_1) + @server.recvfrom_nonblock(5, 0, buffer) + + buffer.encoding.should == Encoding::ISO_8859_1 + end + describe 'the returned data' do it 'is the same as the sent data' do 5.times do diff --git a/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb b/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb index 650a061221..b804099589 100644 --- a/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb +++ b/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb @@ -58,6 +58,15 @@ describe 'UDPSocket#recvfrom_nonblock' do buffer.should == 'h' end + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + IO.select([@server]) + message, = @server.recvfrom_nonblock(1, 0, buffer) + + message.should.equal?(buffer) + buffer.encoding.should == Encoding::ISO_8859_1 + end + describe 'the returned Array' do before do IO.select([@server]) diff --git a/spec/ruby/library/socket/unixsocket/pair_spec.rb b/spec/ruby/library/socket/unixsocket/pair_spec.rb index d80b60894d..b0a3b2af99 100644 --- a/spec/ruby/library/socket/unixsocket/pair_spec.rb +++ b/spec/ruby/library/socket/unixsocket/pair_spec.rb @@ -1,9 +1,11 @@ require_relative '../spec_helper' require_relative '../fixtures/classes' require_relative '../shared/partially_closable_sockets' +require_relative 'shared/pair' with_feature :unix_socket do describe "UNIXSocket.pair" do + it_should_behave_like :unixsocket_pair it_should_behave_like :partially_closable_sockets before :each do @@ -14,25 +16,5 @@ with_feature :unix_socket do @s1.close @s2.close end - - it "returns a pair of connected sockets" do - @s1.puts "foo" - @s2.gets.should == "foo\n" - end - - it "returns sockets with no name" do - @s1.path.should == @s2.path - @s1.path.should == "" - end - - it "returns sockets with no address" do - @s1.addr.should == ["AF_UNIX", ""] - @s2.addr.should == ["AF_UNIX", ""] - end - - it "returns sockets with no peeraddr" do - @s1.peeraddr.should == ["AF_UNIX", ""] - @s2.peeraddr.should == ["AF_UNIX", ""] - end end end diff --git a/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb b/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb index fedf74bb2f..d849fdc302 100644 --- a/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb +++ b/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb @@ -31,6 +31,29 @@ with_feature :unix_socket do sock.close end + it "allows an output buffer as third argument" do + buffer = +'' + + @client.send("foobar", 0) + sock = @server.accept + message, = sock.recvfrom(6, 0, buffer) + sock.close + + message.should.equal?(buffer) + buffer.should == "foobar" + end + + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + + @client.send("foobar", 0) + sock = @server.accept + sock.recvfrom(6, 0, buffer) + sock.close + + buffer.encoding.should == Encoding::ISO_8859_1 + end + it "uses different message options" do @client.send("foobar", Socket::MSG_PEEK) sock = @server.accept diff --git a/spec/ruby/library/socket/unixsocket/shared/pair.rb b/spec/ruby/library/socket/unixsocket/shared/pair.rb new file mode 100644 index 0000000000..ade7fc9852 --- /dev/null +++ b/spec/ruby/library/socket/unixsocket/shared/pair.rb @@ -0,0 +1,29 @@ +require_relative '../../spec_helper' +require_relative '../../fixtures/classes' + +describe :unixsocket_pair, shared: true do + it "returns two UNIXSockets" do + @s1.should be_an_instance_of(UNIXSocket) + @s2.should be_an_instance_of(UNIXSocket) + end + + it "returns a pair of connected sockets" do + @s1.puts "foo" + @s2.gets.should == "foo\n" + end + + it "sets the socket paths to empty Strings" do + @s1.path.should == "" + @s2.path.should == "" + end + + it "sets the socket addresses to empty Strings" do + @s1.addr.should == ["AF_UNIX", ""] + @s2.addr.should == ["AF_UNIX", ""] + end + + it "sets the socket peer addresses to empty Strings" do + @s1.peeraddr.should == ["AF_UNIX", ""] + @s2.peeraddr.should == ["AF_UNIX", ""] + end +end diff --git a/spec/ruby/library/socket/unixsocket/socketpair_spec.rb b/spec/ruby/library/socket/unixsocket/socketpair_spec.rb index 3e9646f76b..5f34008df3 100644 --- a/spec/ruby/library/socket/unixsocket/socketpair_spec.rb +++ b/spec/ruby/library/socket/unixsocket/socketpair_spec.rb @@ -1,40 +1,20 @@ require_relative '../spec_helper' +require_relative '../fixtures/classes' +require_relative '../shared/partially_closable_sockets' +require_relative 'shared/pair' with_feature :unix_socket do - describe 'UNIXSocket.socketpair' do - before do + describe "UNIXSocket.socketpair" do + it_should_behave_like :unixsocket_pair + it_should_behave_like :partially_closable_sockets + + before :each do @s1, @s2 = UNIXSocket.socketpair end - after do + after :each do @s1.close @s2.close end - - it 'returns two UNIXSockets' do - @s1.should be_an_instance_of(UNIXSocket) - @s2.should be_an_instance_of(UNIXSocket) - end - - it 'connects the sockets to each other' do - @s1.write('hello') - - @s2.recv(5).should == 'hello' - end - - it 'sets the socket paths to empty Strings' do - @s1.path.should == '' - @s2.path.should == '' - end - - it 'sets the socket addresses to empty Strings' do - @s1.addr.should == ['AF_UNIX', ''] - @s2.addr.should == ['AF_UNIX', ''] - end - - it 'sets the socket peer addresses to empty Strings' do - @s1.peeraddr.should == ['AF_UNIX', ''] - @s2.peeraddr.should == ['AF_UNIX', ''] - end end end diff --git a/spec/ruby/library/stringio/initialize_spec.rb b/spec/ruby/library/stringio/initialize_spec.rb index ad067a0be1..6f4d2e456c 100644 --- a/spec/ruby/library/stringio/initialize_spec.rb +++ b/spec/ruby/library/stringio/initialize_spec.rb @@ -130,6 +130,26 @@ describe "StringIO#initialize when passed [Object, mode]" do -> { @io.send(:initialize, str, "w") }.should raise_error(Errno::EACCES) -> { @io.send(:initialize, str, "a") }.should raise_error(Errno::EACCES) end + + it "truncates all the content if passed w mode" do + io = StringIO.allocate + source = +"example".encode(Encoding::ISO_8859_1); + + io.send(:initialize, source, "w") + + io.string.should.empty? + io.string.encoding.should == Encoding::ISO_8859_1 + end + + it "truncates all the content if passed IO::TRUNC mode" do + io = StringIO.allocate + source = +"example".encode(Encoding::ISO_8859_1); + + io.send(:initialize, source, IO::TRUNC) + + io.string.should.empty? + io.string.encoding.should == Encoding::ISO_8859_1 + end end describe "StringIO#initialize when passed [Object]" do @@ -172,7 +192,7 @@ end # NOTE: Synchronise with core/io/new_spec.rb (core/io/shared/new.rb) describe "StringIO#initialize when passed keyword arguments" do it "sets the mode based on the passed :mode option" do - io = StringIO.new("example", "r") + io = StringIO.new("example", mode: "r") io.closed_read?.should be_false io.closed_write?.should be_true end diff --git a/spec/ruby/library/stringio/shared/read.rb b/spec/ruby/library/stringio/shared/read.rb index e3840786d9..8ef6ec2734 100644 --- a/spec/ruby/library/stringio/shared/read.rb +++ b/spec/ruby/library/stringio/shared/read.rb @@ -11,10 +11,28 @@ describe :stringio_read, shared: true do end it "reads length bytes and writes them to the buffer String" do - @io.send(@method, 7, buffer = +"") + @io.send(@method, 7, buffer = +"").should.equal?(buffer) buffer.should == "example" end + ruby_version_is ""..."3.4" do + it "does not preserve the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + @io.send(@method, 7, buffer) + + buffer.encoding.should_not == Encoding::ISO_8859_1 + end + end + + ruby_version_is "3.4" do + it "preserves the encoding of the given buffer" do + buffer = ''.encode(Encoding::ISO_8859_1) + @io.send(@method, 7, buffer) + + buffer.encoding.should == Encoding::ISO_8859_1 + end + end + it "tries to convert the passed buffer Object to a String using #to_str" do obj = mock("to_str") obj.should_receive(:to_str).and_return(buffer = +"") diff --git a/spec/ruby/library/stringscanner/check_until_spec.rb b/spec/ruby/library/stringscanner/check_until_spec.rb index ad222fd76b..1d89f88a25 100644 --- a/spec/ruby/library/stringscanner/check_until_spec.rb +++ b/spec/ruby/library/stringscanner/check_until_spec.rb @@ -13,9 +13,11 @@ describe "StringScanner#check_until" do @s.check_until(/test/).should == "This is a test" end - it "raises TypeError if given a String" do - -> { - @s.check_until('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.check_until('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/exist_spec.rb b/spec/ruby/library/stringscanner/exist_spec.rb index ff860a0d3e..a18f5ce352 100644 --- a/spec/ruby/library/stringscanner/exist_spec.rb +++ b/spec/ruby/library/stringscanner/exist_spec.rb @@ -22,9 +22,11 @@ describe "StringScanner#exist?" do @s.exist?(/i/).should == nil end - it "raises TypeError if given a String" do - -> { - @s.exist?('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.exist?('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/scan_until_spec.rb b/spec/ruby/library/stringscanner/scan_until_spec.rb index 6b7782572d..1e318d053b 100644 --- a/spec/ruby/library/stringscanner/scan_until_spec.rb +++ b/spec/ruby/library/stringscanner/scan_until_spec.rb @@ -7,9 +7,9 @@ describe "StringScanner#scan_until" do end it "returns the substring up to and including the end of the match" do - @s.scan_until(/a/).should == "This is a" - @s.pre_match.should == "This is " - @s.post_match.should == " test" + @s.scan_until(/a/).should == "This is a" + @s.pre_match.should == "This is " + @s.post_match.should == " test" end it "returns nil if there's no match" do @@ -21,9 +21,11 @@ describe "StringScanner#scan_until" do @s.scan_until(/^h/).should == "h" end - it "raises TypeError if given a String" do - -> { - @s.scan_until('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.scan_until('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/search_full_spec.rb b/spec/ruby/library/stringscanner/search_full_spec.rb index 7d2a714fa5..713ab00d22 100644 --- a/spec/ruby/library/stringscanner/search_full_spec.rb +++ b/spec/ruby/library/stringscanner/search_full_spec.rb @@ -28,9 +28,11 @@ describe "StringScanner#search_full" do @s.pos.should == 4 end - it "raises TypeError if given a String" do - -> { - @s.search_full('T', true, true) - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.search_full('T', true, true) + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/stringscanner/skip_until_spec.rb b/spec/ruby/library/stringscanner/skip_until_spec.rb index 7b56f13e4f..b6a020f9ba 100644 --- a/spec/ruby/library/stringscanner/skip_until_spec.rb +++ b/spec/ruby/library/stringscanner/skip_until_spec.rb @@ -16,9 +16,11 @@ describe "StringScanner#skip_until" do @s.skip_until(/d+/).should == nil end - it "raises TypeError if given a String" do - -> { - @s.skip_until('T') - }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + ruby_version_is ""..."3.4" do + it "raises TypeError if given a String" do + -> { + @s.skip_until('T') + }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)') + end end end diff --git a/spec/ruby/library/time/iso8601_spec.rb b/spec/ruby/library/time/iso8601_spec.rb index 4a9eb45613..9e2607fbd0 100644 --- a/spec/ruby/library/time/iso8601_spec.rb +++ b/spec/ruby/library/time/iso8601_spec.rb @@ -3,5 +3,5 @@ require_relative 'shared/xmlschema' require 'time' describe "Time.xmlschema" do - it_behaves_like :time_xmlschema, :iso8601 + it_behaves_like :time_library_xmlschema, :iso8601 end diff --git a/spec/ruby/library/time/shared/xmlschema.rb b/spec/ruby/library/time/shared/xmlschema.rb index 44d33cda7e..831d8509a7 100644 --- a/spec/ruby/library/time/shared/xmlschema.rb +++ b/spec/ruby/library/time/shared/xmlschema.rb @@ -1,4 +1,4 @@ -describe :time_xmlschema, shared: true do +describe :time_library_xmlschema, shared: true do it "parses ISO-8601 strings" do t = Time.utc(1985, 4, 12, 23, 20, 50, 520000) s = "1985-04-12T23:20:50.52Z" diff --git a/spec/ruby/library/time/xmlschema_spec.rb b/spec/ruby/library/time/xmlschema_spec.rb index 4279311199..ff3c864a02 100644 --- a/spec/ruby/library/time/xmlschema_spec.rb +++ b/spec/ruby/library/time/xmlschema_spec.rb @@ -3,5 +3,5 @@ require_relative 'shared/xmlschema' require 'time' describe "Time.xmlschema" do - it_behaves_like :time_xmlschema, :xmlschema + it_behaves_like :time_library_xmlschema, :xmlschema end diff --git a/spec/ruby/library/uri/shared/parse.rb b/spec/ruby/library/uri/shared/parse.rb index 87e1ee933e..c5057b6c4b 100644 --- a/spec/ruby/library/uri/shared/parse.rb +++ b/spec/ruby/library/uri/shared/parse.rb @@ -192,8 +192,15 @@ describe :uri_parse, shared: true do file.should be_kind_of(URI::Generic) end - it "raises errors on malformed URIs" do - -> { @object.parse('http://a_b:80/') }.should raise_error(URI::InvalidURIError) - -> { @object.parse('http://a_b/') }.should raise_error(URI::InvalidURIError) + if URI::DEFAULT_PARSER == URI::RFC2396_Parser + it "raises errors on malformed URIs" do + -> { @object.parse('http://a_b:80/') }.should raise_error(URI::InvalidURIError) + -> { @object.parse('http://a_b/') }.should raise_error(URI::InvalidURIError) + end + elsif URI::DEFAULT_PARSER == URI::RFC3986_Parser + it "does not raise errors on URIs contained underscore" do + -> { @object.parse('http://a_b:80/') }.should_not raise_error(URI::InvalidURIError) + -> { @object.parse('http://a_b/') }.should_not raise_error(URI::InvalidURIError) + end end end diff --git a/spec/ruby/optional/capi/bignum_spec.rb b/spec/ruby/optional/capi/bignum_spec.rb index cde929af28..179f053eec 100644 --- a/spec/ruby/optional/capi/bignum_spec.rb +++ b/spec/ruby/optional/capi/bignum_spec.rb @@ -7,21 +7,23 @@ def ensure_bignum(n) n end -full_range_longs = (fixnum_max == 2**(0.size * 8 - 1) - 1) +full_range_longs = (fixnum_max == max_long) +max_ulong = begin + require 'rbconfig/sizeof' + RbConfig::LIMITS['ULONG_MAX'] +rescue LoadError + nil +end +# If the system doesn't offer ULONG_MAX, assume 2's complement and derive it +# from LONG_MAX. +max_ulong ||= 2 * (max_long + 1) - 1 describe "CApiBignumSpecs" do before :each do @s = CApiBignumSpecs.new - - if full_range_longs - @max_long = 2**(0.size * 8 - 1) - 1 - @min_long = -@max_long - 1 - @max_ulong = ensure_bignum(2**(0.size * 8) - 1) - else - @max_long = ensure_bignum(2**(0.size * 8 - 1) - 1) - @min_long = ensure_bignum(-@max_long - 1) - @max_ulong = ensure_bignum(2**(0.size * 8) - 1) - end + @max_long = max_long + @min_long = min_long + @max_ulong = ensure_bignum(max_ulong) end describe "rb_big2long" do @@ -123,7 +125,7 @@ describe "CApiBignumSpecs" do val.should == @max_ulong end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "packs max_ulong into 2 ulongs to allow sign bit" do val = @s.rb_big_pack_length(@max_ulong) val.should == 2 diff --git a/spec/ruby/optional/capi/class_spec.rb b/spec/ruby/optional/capi/class_spec.rb index d0a9913570..a231245ebe 100644 --- a/spec/ruby/optional/capi/class_spec.rb +++ b/spec/ruby/optional/capi/class_spec.rb @@ -487,4 +487,16 @@ describe "C-API Class function" do @s.rb_class_real(0).should == 0 end end + + describe "rb_class_get_superclass" do + it "returns parent class for a provided class" do + a = Class.new + @s.rb_class_get_superclass(Class.new(a)).should == a + end + + it "returns false when there is no parent class" do + @s.rb_class_get_superclass(BasicObject).should == false + @s.rb_class_get_superclass(Module.new).should == false + end + end end diff --git a/spec/ruby/optional/capi/data_spec.rb b/spec/ruby/optional/capi/data_spec.rb index 18c769332e..d000eba6e3 100644 --- a/spec/ruby/optional/capi/data_spec.rb +++ b/spec/ruby/optional/capi/data_spec.rb @@ -1,52 +1,53 @@ require_relative 'spec_helper' +ruby_version_is ""..."3.4" do + load_extension("data") -load_extension("data") - -describe "CApiAllocSpecs (a class with an alloc func defined)" do - it "calls the alloc func" do - @s = CApiAllocSpecs.new - @s.wrapped_data.should == 42 # not defined in initialize - end -end - -describe "CApiWrappedStruct" do - before :each do - @s = CApiWrappedStructSpecs.new - end - - it "wraps with Data_Wrap_Struct and Data_Get_Struct returns data" do - a = @s.wrap_struct(1024) - @s.get_struct(a).should == 1024 + describe "CApiAllocSpecs (a class with an alloc func defined)" do + it "calls the alloc func" do + @s = CApiAllocSpecs.new + @s.wrapped_data.should == 42 # not defined in initialize + end end - describe "RDATA()" do - it "returns the struct data" do - a = @s.wrap_struct(1024) - @s.get_struct_rdata(a).should == 1024 + describe "CApiWrappedStruct" do + before :each do + @s = CApiWrappedStructSpecs.new end - it "allows changing the wrapped struct" do + it "wraps with Data_Wrap_Struct and Data_Get_Struct returns data" do a = @s.wrap_struct(1024) - @s.change_struct(a, 100) - @s.get_struct(a).should == 100 + @s.get_struct(a).should == 1024 end - it "raises a TypeError if the object does not wrap a struct" do - -> { @s.get_struct(Object.new) }.should raise_error(TypeError) + describe "RDATA()" do + it "returns the struct data" do + a = @s.wrap_struct(1024) + @s.get_struct_rdata(a).should == 1024 + end + + it "allows changing the wrapped struct" do + a = @s.wrap_struct(1024) + @s.change_struct(a, 100) + @s.get_struct(a).should == 100 + end + + it "raises a TypeError if the object does not wrap a struct" do + -> { @s.get_struct(Object.new) }.should raise_error(TypeError) + end end - end - describe "rb_check_type" do - it "does not raise an exception when checking data objects" do - a = @s.wrap_struct(1024) - @s.rb_check_type(a, a).should == true + describe "rb_check_type" do + it "does not raise an exception when checking data objects" do + a = @s.wrap_struct(1024) + @s.rb_check_type(a, a).should == true + end end - end - describe "DATA_PTR" do - it "returns the struct data" do - a = @s.wrap_struct(1024) - @s.get_struct_data_ptr(a).should == 1024 + describe "DATA_PTR" do + it "returns the struct data" do + a = @s.wrap_struct(1024) + @s.get_struct_data_ptr(a).should == 1024 + end end end end diff --git a/spec/ruby/optional/capi/ext/class_spec.c b/spec/ruby/optional/capi/ext/class_spec.c index f376534924..c13f02ecf2 100644 --- a/spec/ruby/optional/capi/ext/class_spec.c +++ b/spec/ruby/optional/capi/ext/class_spec.c @@ -79,6 +79,10 @@ static VALUE class_spec_rb_class_real(VALUE self, VALUE object) { } } +static VALUE class_spec_rb_class_get_superclass(VALUE self, VALUE klass) { + return rb_class_get_superclass(klass); +} + static VALUE class_spec_rb_class_superclass(VALUE self, VALUE klass) { return rb_class_superclass(klass); } @@ -160,6 +164,7 @@ void Init_class_spec(void) { rb_define_method(cls, "rb_class_new_instance_kw", class_spec_rb_class_new_instance_kw, 2); #endif rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1); + rb_define_method(cls, "rb_class_get_superclass", class_spec_rb_class_get_superclass, 1); rb_define_method(cls, "rb_class_superclass", class_spec_rb_class_superclass, 1); rb_define_method(cls, "rb_cvar_defined", class_spec_cvar_defined, 2); rb_define_method(cls, "rb_cvar_get", class_spec_cvar_get, 2); diff --git a/spec/ruby/optional/capi/ext/data_spec.c b/spec/ruby/optional/capi/ext/data_spec.c index ef069ef0ba..efefe37c3a 100644 --- a/spec/ruby/optional/capi/ext/data_spec.c +++ b/spec/ruby/optional/capi/ext/data_spec.c @@ -3,6 +3,7 @@ #include <string.h> +#ifndef RUBY_VERSION_IS_3_4 #ifdef __cplusplus extern "C" { #endif @@ -70,8 +71,10 @@ VALUE sws_rb_check_type(VALUE self, VALUE obj, VALUE other) { rb_check_type(obj, TYPE(other)); return Qtrue; } +#endif void Init_data_spec(void) { +#ifndef RUBY_VERSION_IS_3_4 VALUE cls = rb_define_class("CApiAllocSpecs", rb_cObject); rb_define_alloc_func(cls, sdaf_alloc_func); rb_define_method(cls, "wrapped_data", sdaf_get_struct, 0); @@ -82,6 +85,7 @@ void Init_data_spec(void) { rb_define_method(cls, "get_struct_data_ptr", sws_get_struct_data_ptr, 1); rb_define_method(cls, "change_struct", sws_change_struct, 2); rb_define_method(cls, "rb_check_type", sws_rb_check_type, 2); +#endif } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c index 1392bc6ee6..2637ad27ac 100644 --- a/spec/ruby/optional/capi/ext/gc_spec.c +++ b/spec/ruby/optional/capi/ext/gc_spec.c @@ -16,6 +16,8 @@ VALUE registered_after_rb_global_variable_bignum; VALUE registered_after_rb_global_variable_float; VALUE rb_gc_register_address_outside_init; +VALUE rb_gc_register_mark_object_not_referenced_float; + static VALUE registered_tagged_address(VALUE self) { return registered_tagged_value; } @@ -90,6 +92,10 @@ static VALUE gc_spec_rb_gc_register_mark_object(VALUE self, VALUE obj) { return Qnil; } +static VALUE gc_spec_rb_gc_register_mark_object_not_referenced_float(VALUE self) { + return rb_gc_register_mark_object_not_referenced_float; +} + void Init_gc_spec(void) { VALUE cls = rb_define_class("CApiGCSpecs", rb_cObject); @@ -115,6 +121,9 @@ void Init_gc_spec(void) { registered_after_rb_global_variable_float = DBL2NUM(6.28); rb_global_variable(®istered_after_rb_global_variable_float); + rb_gc_register_mark_object_not_referenced_float = DBL2NUM(1.61); + rb_gc_register_mark_object(rb_gc_register_mark_object_not_referenced_float); + rb_define_method(cls, "registered_tagged_address", registered_tagged_address, 0); rb_define_method(cls, "registered_reference_address", registered_reference_address, 0); rb_define_method(cls, "registered_before_rb_gc_register_address", get_registered_before_rb_gc_register_address, 0); @@ -131,6 +140,7 @@ void Init_gc_spec(void) { rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0); rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1); rb_define_method(cls, "rb_gc_register_mark_object", gc_spec_rb_gc_register_mark_object, 1); + rb_define_method(cls, "rb_gc_register_mark_object_not_referenced_float", gc_spec_rb_gc_register_mark_object_not_referenced_float, 0); rb_define_method(cls, "rb_gc_latest_gc_info", gc_spec_rb_gc_latest_gc_info, 1); } diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c index 1a73331386..1b4d4fccce 100644 --- a/spec/ruby/optional/capi/ext/io_spec.c +++ b/spec/ruby/optional/capi/ext/io_spec.c @@ -330,13 +330,15 @@ static VALUE io_spec_errno_set(VALUE self, VALUE val) { } VALUE io_spec_mode_sync_flag(VALUE self, VALUE io) { + int mode; #ifdef RUBY_VERSION_IS_3_3 - if (rb_io_mode(io) & FMODE_SYNC) { + mode = rb_io_mode(io); #else rb_io_t *fp; GetOpenFile(io, fp); - if (fp->mode & FMODE_SYNC) { + mode = fp->mode; #endif + if (mode & FMODE_SYNC) { return Qtrue; } else { return Qfalse; diff --git a/spec/ruby/optional/capi/ext/kernel_spec.c b/spec/ruby/optional/capi/ext/kernel_spec.c index 1761599081..04252b2848 100644 --- a/spec/ruby/optional/capi/ext/kernel_spec.c +++ b/spec/ruby/optional/capi/ext/kernel_spec.c @@ -221,7 +221,7 @@ static VALUE kernel_spec_rb_eval_string_protect(VALUE self, VALUE str, VALUE ary VALUE kernel_spec_rb_sys_fail(VALUE self, VALUE msg) { errno = 1; if (msg == Qnil) { - rb_sys_fail(0); + rb_sys_fail(NULL); } else if (self != Qundef) { rb_sys_fail(StringValuePtr(msg)); } diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c index 8aa98cc5ce..aa60662e1e 100644 --- a/spec/ruby/optional/capi/ext/object_spec.c +++ b/spec/ruby/optional/capi/ext/object_spec.c @@ -390,22 +390,22 @@ static VALUE speced_allocator(VALUE klass) { return instance; } -static VALUE define_alloc_func(VALUE self, VALUE klass) { +static VALUE object_spec_rb_define_alloc_func(VALUE self, VALUE klass) { rb_define_alloc_func(klass, speced_allocator); return Qnil; } -static VALUE undef_alloc_func(VALUE self, VALUE klass) { +static VALUE object_spec_rb_undef_alloc_func(VALUE self, VALUE klass) { rb_undef_alloc_func(klass); return Qnil; } -static VALUE speced_allocator_p(VALUE self, VALUE klass) { +static VALUE object_spec_speced_allocator_p(VALUE self, VALUE klass) { rb_alloc_func_t allocator = rb_get_alloc_func(klass); return (allocator == speced_allocator) ? Qtrue : Qfalse; } -static VALUE custom_alloc_func_p(VALUE self, VALUE klass) { +static VALUE object_spec_custom_alloc_func_p(VALUE self, VALUE klass) { rb_alloc_func_t allocator = rb_get_alloc_func(klass); return allocator ? Qtrue : Qfalse; } @@ -485,10 +485,10 @@ void Init_object_spec(void) { rb_define_method(cls, "rb_ivar_defined", object_spec_rb_ivar_defined, 2); rb_define_method(cls, "rb_copy_generic_ivar", object_spec_rb_copy_generic_ivar, 2); rb_define_method(cls, "rb_free_generic_ivar", object_spec_rb_free_generic_ivar, 1); - rb_define_method(cls, "rb_define_alloc_func", define_alloc_func, 1); - rb_define_method(cls, "rb_undef_alloc_func", undef_alloc_func, 1); - rb_define_method(cls, "speced_allocator?", speced_allocator_p, 1); - rb_define_method(cls, "custom_alloc_func?", custom_alloc_func_p, 1); + rb_define_method(cls, "rb_define_alloc_func", object_spec_rb_define_alloc_func, 1); + rb_define_method(cls, "rb_undef_alloc_func", object_spec_rb_undef_alloc_func, 1); + rb_define_method(cls, "speced_allocator?", object_spec_speced_allocator_p, 1); + rb_define_method(cls, "custom_alloc_func?", object_spec_custom_alloc_func_p, 1); rb_define_method(cls, "not_implemented_method", rb_f_notimplement, -1); rb_define_method(cls, "rb_ivar_foreach", object_spec_rb_ivar_foreach, 1); } diff --git a/spec/ruby/optional/capi/ext/rubyspec.h b/spec/ruby/optional/capi/ext/rubyspec.h index 09135774af..1df274ead1 100644 --- a/spec/ruby/optional/capi/ext/rubyspec.h +++ b/spec/ruby/optional/capi/ext/rubyspec.h @@ -46,6 +46,10 @@ (RUBY_VERSION_MAJOR == (major) && RUBY_VERSION_MINOR == (minor) && RUBY_VERSION_TEENY < (teeny))) #define RUBY_VERSION_SINCE(major,minor,teeny) (!RUBY_VERSION_BEFORE(major, minor, teeny)) +#if RUBY_VERSION_SINCE(3, 4, 0) +#define RUBY_VERSION_IS_3_4 +#endif + #if RUBY_VERSION_SINCE(3, 3, 0) #define RUBY_VERSION_IS_3_3 #endif diff --git a/spec/ruby/optional/capi/ext/typed_data_spec.c b/spec/ruby/optional/capi/ext/typed_data_spec.c index 38889ecf5c..221f1c8ac4 100644 --- a/spec/ruby/optional/capi/ext/typed_data_spec.c +++ b/spec/ruby/optional/capi/ext/typed_data_spec.c @@ -106,6 +106,8 @@ VALUE sws_typed_wrap_struct(VALUE self, VALUE val) { return TypedData_Wrap_Struct(rb_cObject, &sample_typed_wrapped_struct_data_type, bar); } +#undef RUBY_UNTYPED_DATA_WARNING +#define RUBY_UNTYPED_DATA_WARNING 0 VALUE sws_untyped_wrap_struct(VALUE self, VALUE val) { int* data = (int*) malloc(sizeof(int)); *data = FIX2INT(val); diff --git a/spec/ruby/optional/capi/fixnum_spec.rb b/spec/ruby/optional/capi/fixnum_spec.rb index aa02a0543b..e691aa3893 100644 --- a/spec/ruby/optional/capi/fixnum_spec.rb +++ b/spec/ruby/optional/capi/fixnum_spec.rb @@ -25,7 +25,7 @@ describe "CApiFixnumSpecs" do end end - platform_is wordsize: 64 do # sizeof(long) > sizeof(int) + platform_is c_long_size: 64 do # sizeof(long) > sizeof(int) it "raises a TypeError if passed nil" do -> { @s.FIX2INT(nil) }.should raise_error(TypeError) end @@ -74,7 +74,7 @@ describe "CApiFixnumSpecs" do end end - platform_is wordsize: 64 do # sizeof(long) > sizeof(int) + platform_is c_long_size: 64 do # sizeof(long) > sizeof(int) it "raises a TypeError if passed nil" do -> { @s.FIX2UINT(nil) }.should raise_error(TypeError) end diff --git a/spec/ruby/optional/capi/gc_spec.rb b/spec/ruby/optional/capi/gc_spec.rb index aaced56483..d9661328ab 100644 --- a/spec/ruby/optional/capi/gc_spec.rb +++ b/spec/ruby/optional/capi/gc_spec.rb @@ -108,6 +108,10 @@ describe "CApiGCSpecs" do it "can be called with an object" do @f.rb_gc_register_mark_object(Object.new).should be_nil end + + it "keeps the value alive even if the value is not referenced by any Ruby object" do + @f.rb_gc_register_mark_object_not_referenced_float.should == 1.61 + end end describe "rb_gc_latest_gc_info" do diff --git a/spec/ruby/optional/capi/io_spec.rb b/spec/ruby/optional/capi/io_spec.rb index 870abef3ea..bdec46f5e1 100644 --- a/spec/ruby/optional/capi/io_spec.rb +++ b/spec/ruby/optional/capi/io_spec.rb @@ -1,4 +1,5 @@ require_relative 'spec_helper' +require_relative '../../fixtures/io' load_extension('io') @@ -279,6 +280,22 @@ describe "C-API IO function" do it "raises an IOError if the IO is not initialized" do -> { @o.rb_io_maybe_wait_writable(0, IO.allocate, nil) }.should raise_error(IOError, "uninitialized stream") end + + it "can be interrupted" do + IOSpec.exhaust_write_buffer(@w_io) + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + @o.rb_io_maybe_wait_writable(0, @w_io, 10) + end + + Thread.pass until t.stop? + t.kill + t.join + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + end end end @@ -355,6 +372,21 @@ describe "C-API IO function" do thr.join end + it "can be interrupted" do + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + @o.rb_io_maybe_wait_readable(0, @r_io, 10, false) + end + + Thread.pass until t.stop? + t.kill + t.join + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + end + it "raises an IOError if the IO is closed" do @r_io.close -> { @o.rb_io_maybe_wait_readable(0, @r_io, nil, false) }.should raise_error(IOError, "closed stream") @@ -438,6 +470,37 @@ describe "C-API IO function" do it "raises an IOError if the IO is not initialized" do -> { @o.rb_io_maybe_wait(0, IO.allocate, IO::WRITABLE, nil) }.should raise_error(IOError, "uninitialized stream") end + + it "can be interrupted when waiting for READABLE event" do + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + @o.rb_io_maybe_wait(0, @r_io, IO::READABLE, 10) + end + + Thread.pass until t.stop? + t.kill + t.join + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + end + + it "can be interrupted when waiting for WRITABLE event" do + IOSpec.exhaust_write_buffer(@w_io) + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + + t = Thread.new do + @o.rb_io_maybe_wait(0, @w_io, IO::WRITABLE, 10) + end + + Thread.pass until t.stop? + t.kill + t.join + + finish = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (finish - start).should < 9 + end end end diff --git a/spec/ruby/optional/capi/numeric_spec.rb b/spec/ruby/optional/capi/numeric_spec.rb index 95213d3f2b..e9667da5ba 100644 --- a/spec/ruby/optional/capi/numeric_spec.rb +++ b/spec/ruby/optional/capi/numeric_spec.rb @@ -106,7 +106,7 @@ describe "CApiNumericSpecs" do @s.NUM2LONG(5).should == 5 end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "converts -1 to an signed number" do @s.NUM2LONG(-1).should == -1 end @@ -120,7 +120,7 @@ describe "CApiNumericSpecs" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "converts -1 to an signed number" do @s.NUM2LONG(-1).should == -1 end @@ -210,7 +210,7 @@ describe "CApiNumericSpecs" do @s.NUM2ULONG(5).should == 5 end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "converts -1 to an unsigned number" do @s.NUM2ULONG(-1).should == 4294967295 end @@ -231,7 +231,7 @@ describe "CApiNumericSpecs" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "converts -1 to an unsigned number" do @s.NUM2ULONG(-1).should == 18446744073709551615 end diff --git a/spec/ruby/optional/capi/rbasic_spec.rb b/spec/ruby/optional/capi/rbasic_spec.rb index f3367e05ff..7b5b5b2fed 100644 --- a/spec/ruby/optional/capi/rbasic_spec.rb +++ b/spec/ruby/optional/capi/rbasic_spec.rb @@ -1,7 +1,9 @@ require_relative 'spec_helper' require_relative 'shared/rbasic' load_extension("rbasic") -load_extension("data") +ruby_version_is ""..."3.4" do + load_extension("data") +end load_extension("array") describe "RBasic support for regular objects" do @@ -12,33 +14,35 @@ describe "RBasic support for regular objects" do it_should_behave_like :rbasic end -describe "RBasic support for RData" do - before :all do - @specs = CApiRBasicRDataSpecs.new - @wrapping = CApiWrappedStructSpecs.new - @data = -> { [@wrapping.wrap_struct(1024), @wrapping.wrap_struct(1025)] } - end - it_should_behave_like :rbasic +ruby_version_is ""..."3.4" do + describe "RBasic support for RData" do + before :all do + @specs = CApiRBasicRDataSpecs.new + @wrapping = CApiWrappedStructSpecs.new + @data = -> { [@wrapping.wrap_struct(1024), @wrapping.wrap_struct(1025)] } + end + it_should_behave_like :rbasic - it "supports user flags" do - obj, _ = @data.call - initial = @specs.get_flags(obj) - @specs.set_flags(obj, 1 << 14 | 1 << 16 | initial).should == 1 << 14 | 1 << 16 | initial - @specs.get_flags(obj).should == 1 << 14 | 1 << 16 | initial - @specs.set_flags(obj, initial).should == initial - end + it "supports user flags" do + obj, _ = @data.call + initial = @specs.get_flags(obj) + @specs.set_flags(obj, 1 << 14 | 1 << 16 | initial).should == 1 << 14 | 1 << 16 | initial + @specs.get_flags(obj).should == 1 << 14 | 1 << 16 | initial + @specs.set_flags(obj, initial).should == initial + end - it "supports copying the flags from one object over to the other" do - obj1, obj2 = @data.call - initial = @specs.get_flags(obj1) - @specs.get_flags(obj2).should == initial - @specs.set_flags(obj1, 1 << 14 | 1 << 16 | initial) - @specs.get_flags(obj1).should == 1 << 14 | 1 << 16 | initial + it "supports copying the flags from one object over to the other" do + obj1, obj2 = @data.call + initial = @specs.get_flags(obj1) + @specs.get_flags(obj2).should == initial + @specs.set_flags(obj1, 1 << 14 | 1 << 16 | initial) + @specs.get_flags(obj1).should == 1 << 14 | 1 << 16 | initial - @specs.copy_flags(obj2, obj1) - @specs.get_flags(obj2).should == 1 << 14 | 1 << 16 | initial - @specs.set_flags(obj1, initial) - @specs.copy_flags(obj2, obj1) - @specs.get_flags(obj2).should == initial + @specs.copy_flags(obj2, obj1) + @specs.get_flags(obj2).should == 1 << 14 | 1 << 16 | initial + @specs.set_flags(obj1, initial) + @specs.copy_flags(obj2, obj1) + @specs.get_flags(obj2).should == initial + end end end diff --git a/spec/ruby/optional/capi/util_spec.rb b/spec/ruby/optional/capi/util_spec.rb index 9ff8b4760a..6cf064bf97 100644 --- a/spec/ruby/optional/capi/util_spec.rb +++ b/spec/ruby/optional/capi/util_spec.rb @@ -209,7 +209,7 @@ describe "C-API Util function" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do describe "rb_long2int" do it "raises a RangeError if the value is outside the range of a C int" do -> { @o.rb_long2int(0xffff_ffff_ffff) }.should raise_error(RangeError) diff --git a/spec/ruby/shared/kernel/at_exit.rb b/spec/ruby/shared/kernel/at_exit.rb index 16d41cb01c..29db79bb39 100644 --- a/spec/ruby/shared/kernel/at_exit.rb +++ b/spec/ruby/shared/kernel/at_exit.rb @@ -30,6 +30,12 @@ describe :kernel_at_exit, shared: true do result.lines.should.include?("The exception matches: true (message=foo)\n") end + it "gives access to an exception raised in a previous handler" do + code = "#{@method} { print '$!.message = ' + $!.message }; #{@method} { raise 'foo' }" + result = ruby_exe(code, args: "2>&1", exit_status: 1) + result.lines.should.include?("$!.message = foo") + end + it "both exceptions in a handler and in the main script are printed" do code = "#{@method} { raise 'at_exit_error' }; raise 'main_script_error'" result = ruby_exe(code, args: "2>&1", exit_status: 1) diff --git a/spec/ruby/shared/string/times.rb b/spec/ruby/shared/string/times.rb index aaf748bad9..4814f894cf 100644 --- a/spec/ruby/shared/string/times.rb +++ b/spec/ruby/shared/string/times.rb @@ -44,13 +44,13 @@ describe :string_times, shared: true do result.encoding.should equal(Encoding::UTF_8) end - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do -> { @object.call("abc", (2 ** 31) - 1) }.should raise_error(ArgumentError) end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do -> { @object.call("abc", (2 ** 63) - 1) }.should raise_error(ArgumentError) end diff --git a/spec/ruby/shared/time/yday.rb b/spec/ruby/shared/time/yday.rb new file mode 100644 index 0000000000..f81c45261c --- /dev/null +++ b/spec/ruby/shared/time/yday.rb @@ -0,0 +1,18 @@ +describe :time_yday, shared: true do + it 'returns the correct value for each day of each month' do + mdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + yday = 1 + mdays.each_with_index do |days, month| + days.times do |day| + @method.call(2014, month+1, day+1).should == yday + yday += 1 + end + end + end + + it 'supports leap years' do + @method.call(2016, 2, 29).should == 31 + 29 + @method.call(2016, 3, 1).should == 31 + 29 + 1 + end +end |