# frozen_string_literal: true RSpec.describe "bundle outdated" do before :each do build_repo2 do build_git "foo", :path => lib_path("foo") build_git "zebra", :path => lib_path("zebra") end install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "zebra", :git => "#{lib_path("zebra")}" gem "foo", :git => "#{lib_path("foo")}" gem "activesupport", "2.3.5" gem "weakling", "~> 0.0.1" gem "duradura", '7.0' gem "terranova", '8' G end describe "with no arguments" do it "returns a sorted list of outdated gems" do update_repo2 do build_gem "activesupport", "3.0" build_gem "weakling", "0.2" update_git "foo", :path => lib_path("foo") update_git "zebra", :path => lib_path("zebra") end bundle "outdated" expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip Gem Current Latest Requested Groups activesupport 2.3.5 3.0 = 2.3.5 default foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default weakling 0.0.3 0.2 ~> 0.0.1 default zebra 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default TABLE expect(out).to match(Regexp.new(expected_output)) end it "excludes header row from the sorting" do update_repo2 do build_gem "AAA", %w[1.0.0 2.0.0] end install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "AAA", "1.0.0" G bundle "outdated" expected_output = <<~TABLE Gem Current Latest Requested Groups AAA 1.0.0 2.0.0 = 1.0.0 default TABLE expect(out).to include(expected_output.strip) end it "returns non zero exit status if outdated gems present" do update_repo2 do build_gem "activesupport", "3.0" update_git "foo", :path => lib_path("foo") end bundle "outdated" expect(exitstatus).to_not be_zero if exitstatus end it "returns success exit status if no outdated gems present" do bundle "outdated" expect(exitstatus).to be_zero if exitstatus end it "adds gem group to dependency output when repo is updated" do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "terranova", '8' group :development, :test do gem 'activesupport', '2.3.5' end G update_repo2 { build_gem "activesupport", "3.0" } update_repo2 { build_gem "terranova", "9" } bundle "outdated" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 2.3.5 3.0 = 2.3.5 development, test terranova 8 9 = 8 default TABLE expect(out).to end_with(expected_output) end end describe "with --verbose option" do it "shows the location of the latest version's gemspec if installed" do bundle! "config set clean false" update_repo2 { build_gem "activesupport", "3.0" } update_repo2 { build_gem "terranova", "9" } install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "terranova", '9' gem 'activesupport', '2.3.5' G gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "terranova", '8' gem 'activesupport', '2.3.5' G bundle "outdated --verbose" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups Path activesupport 2.3.5 3.0 = 2.3.5 default terranova 8 9 = 8 default #{default_bundle_path("specifications/terranova-9.gemspec")} TABLE expect(out).to end_with(expected_output) end end describe "with --group option" do before do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "weakling", "~> 0.0.1" gem "terranova", '8' group :development, :test do gem "duradura", '7.0' gem 'activesupport', '2.3.5' end G end def test_group_option(group) update_repo2 do build_gem "activesupport", "3.0" build_gem "terranova", "9" build_gem "duradura", "8.0" end bundle "outdated --group #{group}" end it "works when the bundle is up to date" do bundle "outdated --group" 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") expected_output = <<~TABLE.strip Gem Current Latest Requested Groups terranova 8 9 = 8 default TABLE expect(out).to end_with(expected_output) end it "returns a sorted list of outdated gems from one group => 'development'" do test_group_option("development") expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 2.3.5 3.0 = 2.3.5 development, test duradura 7.0 8.0 = 7.0 development, test TABLE expect(out).to end_with(expected_output) end it "returns a sorted list of outdated gems from one group => 'test'" do test_group_option("test") expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 2.3.5 3.0 = 2.3.5 development, test duradura 7.0 8.0 = 7.0 development, test TABLE expect(out).to end_with(expected_output) end end describe "with --groups option and outdated transitive dependencies" do before do update_repo2 do build_gem "bar", %w[2.0.0] build_gem "bar_dependant", "7.0" do |s| s.add_dependency "bar", "~> 2.0" end end install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "bar_dependant", '7.0' G update_repo2 do build_gem "bar", %w[3.0.0] end end it "returns a sorted list of outdated gems" do bundle "outdated --groups" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups bar 2.0.0 3.0.0 TABLE expect(out).to end_with(expected_output) end end describe "with --groups option" do before do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "weakling", "~> 0.0.1" gem "terranova", '8' group :development, :test do gem 'activesupport', '2.3.5' gem "duradura", '7.0' end G end it "not outdated gems" do bundle "outdated --groups" expect(out).to end_with("Bundle up to date!") end it "returns a sorted list of outdated gems by groups" do update_repo2 do build_gem "activesupport", "3.0" build_gem "terranova", "9" build_gem "duradura", "8.0" end bundle "outdated --groups" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 2.3.5 3.0 = 2.3.5 development, test duradura 7.0 8.0 = 7.0 development, test terranova 8 9 = 8 default TABLE expect(out).to end_with(expected_output) end end describe "with --local option" do it "uses local cache to return a list of outdated gems" do update_repo2 do build_gem "activesupport", "2.3.4" end bundle! "config set clean false" install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "activesupport", "2.3.4" G bundle "outdated --local" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 2.3.4 2.3.5 = 2.3.4 default TABLE expect(out).to end_with(expected_output) end it "doesn't hit repo2" do FileUtils.rm_rf(gem_repo2) bundle "outdated --local" expect(out).not_to match(/Fetching (gem|version|dependency) metadata from/) end end shared_examples_for "a minimal output is desired" do context "and gems are outdated" do before do update_repo2 do build_gem "activesupport", "3.0" build_gem "weakling", "0.2" end end it "outputs a sorted list of outdated gems with a more minimal format" 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 end context "and no gems are outdated" do it "has empty output" do subject expect(out).to be_empty end end end describe "with --parseable option" do subject { bundle "outdated --parseable" } it_behaves_like "a minimal output is desired" end describe "with aliased --porcelain option" do subject { bundle "outdated --porcelain" } it_behaves_like "a minimal output is desired" end describe "with specified gems" do it "returns list of outdated gems" do update_repo2 do build_gem "activesupport", "3.0" update_git "foo", :path => lib_path("foo") end bundle "outdated foo" expected_output = <<~TABLE.gsub("x", "\\\h").tr(".", "\.").strip Gem Current Latest Requested Groups foo 1.0 xxxxxxx 1.0 xxxxxxx >= 0 default TABLE expect(out).to match(Regexp.new(expected_output)) end end describe "pre-release gems" do context "without the --pre option" do it "ignores pre-release versions" do update_repo2 do build_gem "activesupport", "3.0.0.beta" end bundle "outdated" expect(out).to end_with("Bundle up to date!") end end context "with the --pre option" do it "includes pre-release versions" do update_repo2 do build_gem "activesupport", "3.0.0.beta" end bundle "outdated --pre" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 2.3.5 3.0.0.beta = 2.3.5 default TABLE expect(out).to end_with(expected_output) end end context "when current gem is a pre-release" do it "includes the gem" do update_repo2 do build_gem "activesupport", "3.0.0.beta.1" build_gem "activesupport", "3.0.0.beta.2" end install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "activesupport", "3.0.0.beta.1" G bundle "outdated" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups activesupport 3.0.0.beta.1 3.0.0.beta.2 = 3.0.0.beta.1 default TABLE expect(out).to end_with(expected_output) end end end filter_strict_option = Bundler.feature_flag.bundler_2_mode? ? :"filter-strict" : :strict describe "with --#{filter_strict_option} option" do it "only reports gems that have a newer version that matches the specified dependency version requirements" do update_repo2 do build_gem "activesupport", "3.0" build_gem "weakling", "0.0.5" end bundle :outdated, filter_strict_option => true expected_output = <<~TABLE.strip Gem Current Latest Requested Groups weakling 0.0.3 0.0.5 ~> 0.0.1 default TABLE expect(out).to end_with(expected_output) end 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" G bundle :outdated, filter_strict_option => true expect(out).to end_with("Bundle up to date!") end 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)}" gem "activesupport", "~> 2.3" gem "weakling", ">= 0.0.1" G update_repo2 do build_gem "activesupport", %w[2.4.0 3.0.0] build_gem "weakling", "0.0.5" end bundle :outdated, filter_strict_option => true, "filter-patch" => true expected_output = <<~TABLE.strip Gem Current Latest Requested Groups weakling 0.0.3 0.0.5 >= 0.0.1 default TABLE expect(out).to end_with(expected_output) end it "only reports gems that match requirement and minor filter level" do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "activesupport", "~> 2.3" gem "weakling", ">= 0.0.1" G update_repo2 do build_gem "activesupport", %w[2.3.9] build_gem "weakling", "0.1.5" end bundle :outdated, filter_strict_option => true, "filter-minor" => true expected_output = <<~TABLE.strip Gem Current Latest Requested Groups weakling 0.0.3 0.1.5 >= 0.0.1 default TABLE expect(out).to end_with(expected_output) end it "only reports gems that match requirement and major filter level" do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "activesupport", "~> 2.3" gem "weakling", ">= 0.0.1" G update_repo2 do build_gem "activesupport", %w[2.4.0 2.5.0] build_gem "weakling", "1.1.5" end bundle :outdated, filter_strict_option => true, "filter-major" => true expected_output = <<~TABLE.strip Gem Current Latest Requested Groups weakling 0.0.3 1.1.5 >= 0.0.1 default TABLE expect(out).to end_with(expected_output) end end end describe "with invalid gem name" do it "returns could not find gem name" do bundle "outdated invalid_gem_name" expect(err).to include("Could not find gem 'invalid_gem_name'.") end it "returns non-zero exit code" do bundle "outdated invalid_gem_name" expect(exitstatus).to_not be_zero if exitstatus end end it "performs an automatic bundle install" do gemfile <<-G source "#{file_uri_for(gem_repo1)}" gem "rack", "0.9.1" gem "foo" G bundle "config set auto_install 1" bundle :outdated expect(out).to include("Installing foo 1.0") end context "after bundle install --deployment", :bundler => "< 3" do before do install_gemfile <<-G, forgotten_command_line_options(:deployment => true) source "#{file_uri_for(gem_repo2)}" gem "rack" gem "foo" G end it "outputs a helpful message about being in deployment mode" do update_repo2 { build_gem "activesupport", "3.0" } bundle "outdated" expect(last_command).to be_failure expect(err).to include("You are trying to check outdated gems in deployment mode.") expect(err).to include("Run `bundle outdated` elsewhere.") expect(err).to include("If this is a development machine, remove the ") expect(err).to include("Gemfile freeze\nby running `bundle config unset deployment`.") end end context "after bundle config set deployment true" do before do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "rack" gem "foo" G bundle! "config set deployment true" end it "outputs a helpful message about being in deployment mode" do update_repo2 { build_gem "activesupport", "3.0" } bundle "outdated" expect(last_command).to be_failure expect(err).to include("You are trying to check outdated gems in deployment mode.") expect(err).to include("Run `bundle outdated` elsewhere.") expect(err).to include("If this is a development machine, remove the ") expect(err).to include("Gemfile freeze\nby running `bundle config unset deployment`.") end end context "update available for a gem on a different platform" do before do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "laduradura", '= 5.15.2' G end it "reports that no updates are available" do bundle "outdated" expect(out).to end_with("Bundle up to date!") end end context "update available for a gem on the same platform while multiple platforms used for gem" do it "reports that updates are available if the Ruby platform is used" do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby] G bundle "outdated" expect(out).to end_with("Bundle up to date!") end it "reports that updates are available if the JRuby platform is used", :jruby do install_gemfile <<-G source "#{file_uri_for(gem_repo2)}" gem "laduradura", '= 5.15.2', :platforms => [:ruby, :jruby] G bundle "outdated" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups laduradura 5.15.2 5.15.3 = 5.15.2 default TABLE expect(out).to end_with(expected_output) end end shared_examples_for "version update is detected" do it "reports that a gem has a newer version" do subject outdated_gems = out.split("\n").drop_while {|l| !l.start_with?("Gem") }[1..-1] expect(outdated_gems.size).to be > 0 end end shared_examples_for "major version updates are detected" do before do update_repo2 do build_gem "activesupport", "3.3.5" build_gem "weakling", "0.8.0" end end it_behaves_like "version update is detected" end context "when on a new machine" do before do simulate_new_machine update_git "foo", :path => lib_path("foo") update_repo2 do build_gem "activesupport", "3.3.5" build_gem "weakling", "0.8.0" end end subject { bundle "outdated" } it_behaves_like "version update is detected" end shared_examples_for "minor version updates are detected" do before do update_repo2 do build_gem "activesupport", "2.7.5" build_gem "weakling", "2.0.1" end end it_behaves_like "version update is detected" end shared_examples_for "patch version updates are detected" do before do update_repo2 do build_gem "activesupport", "2.3.7" build_gem "weakling", "0.3.1" end end it_behaves_like "version update is detected" end shared_examples_for "no version updates are detected" do it "does not detect any version updates" do subject expect(out).to end_with("updates to display.") end end shared_examples_for "major version is ignored" do before do update_repo2 do build_gem "activesupport", "3.3.5" build_gem "weakling", "1.0.1" end end it_behaves_like "no version updates are detected" end shared_examples_for "minor version is ignored" do before do update_repo2 do build_gem "activesupport", "2.4.5" build_gem "weakling", "0.3.1" end end it_behaves_like "no version updates are detected" end shared_examples_for "patch version is ignored" do before do update_repo2 do build_gem "activesupport", "2.3.6" build_gem "weakling", "0.0.4" end end it_behaves_like "no version updates are detected" end describe "with --filter-major option" do subject { bundle "outdated --filter-major" } it_behaves_like "major version updates are detected" it_behaves_like "minor version is ignored" it_behaves_like "patch version is ignored" end describe "with --filter-minor option" do subject { bundle "outdated --filter-minor" } it_behaves_like "minor version updates are detected" it_behaves_like "major version is ignored" it_behaves_like "patch version is ignored" end describe "with --filter-patch option" do subject { bundle "outdated --filter-patch" } it_behaves_like "patch version updates are detected" it_behaves_like "major version is ignored" it_behaves_like "minor version is ignored" end describe "with --filter-minor --filter-patch options" do subject { bundle "outdated --filter-minor --filter-patch" } it_behaves_like "minor version updates are detected" it_behaves_like "patch version updates are detected" it_behaves_like "major version is ignored" end describe "with --filter-major --filter-minor options" do subject { bundle "outdated --filter-major --filter-minor" } it_behaves_like "major version updates are detected" it_behaves_like "minor version updates are detected" it_behaves_like "patch version is ignored" end describe "with --filter-major --filter-patch options" do subject { bundle "outdated --filter-major --filter-patch" } it_behaves_like "major version updates are detected" it_behaves_like "patch version updates are detected" it_behaves_like "minor version is ignored" end describe "with --filter-major --filter-minor --filter-patch options" do subject { bundle "outdated --filter-major --filter-minor --filter-patch" } it_behaves_like "major version updates are detected" it_behaves_like "minor version updates are detected" it_behaves_like "patch version updates are detected" end context "conservative updates" do context "without update-strict" do before do build_repo4 do build_gem "patch", %w[1.0.0 1.0.1] build_gem "minor", %w[1.0.0 1.0.1 1.1.0] build_gem "major", %w[1.0.0 1.0.1 1.1.0 2.0.0] end # establish a lockfile set to 1.0.0 install_gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'patch', '1.0.0' gem 'minor', '1.0.0' gem 'major', '1.0.0' G # remove 1.4.3 requirement and bar altogether # to setup update specs below gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'patch' gem 'minor' gem 'major' G end it "shows nothing when patching and filtering to minor" do bundle "outdated --patch --filter-minor" expect(out).to end_with("No minor updates to display.") end it "shows all gems when patching and filtering to patch" do bundle "outdated --patch --filter-patch" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups major 1.0.0 1.0.1 >= 0 default minor 1.0.0 1.0.1 >= 0 default patch 1.0.0 1.0.1 >= 0 default TABLE expect(out).to end_with(expected_output) end it "shows minor and major when updating to minor and filtering to patch and minor" do bundle "outdated --minor --filter-minor" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups major 1.0.0 1.1.0 >= 0 default minor 1.0.0 1.1.0 >= 0 default TABLE expect(out).to end_with(expected_output) end it "shows minor when updating to major and filtering to minor with parseable" do bundle "outdated --major --filter-minor --parseable" expect(out).not_to include("patch (newest") expect(out).to include("minor (newest") expect(out).not_to include("major (newest") end end context "with update-strict" do before do build_repo4 do build_gem "foo", %w[1.4.3 1.4.4] do |s| s.add_dependency "bar", "~> 2.0" end build_gem "foo", %w[1.4.5 1.5.0] do |s| s.add_dependency "bar", "~> 2.1" end build_gem "foo", %w[1.5.1] do |s| s.add_dependency "bar", "~> 3.0" end build_gem "bar", %w[2.0.3 2.0.4 2.0.5 2.1.0 2.1.1 3.0.0] build_gem "qux", %w[1.0.0 1.1.0 2.0.0] end # establish a lockfile set to 1.4.3 install_gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'foo', '1.4.3' gem 'bar', '2.0.3' gem 'qux', '1.0.0' G # remove 1.4.3 requirement and bar altogether # to setup update specs below gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'foo' gem 'qux' G end it "shows gems with update-strict updating to patch and filtering to patch" do bundle "outdated --patch --update-strict --filter-patch" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups bar 2.0.3 2.0.5 foo 1.4.3 1.4.4 >= 0 default TABLE expect(out).to end_with(expected_output) end end end describe "with --only-explicit" do it "does not report outdated dependent gems" do build_repo4 do build_gem "weakling", %w[0.2 0.3] do |s| s.add_dependency "bar", "~> 2.1" end build_gem "bar", %w[2.1 2.2] end install_gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'weakling', '0.2' gem 'bar', '2.1' G gemfile <<-G source "#{file_uri_for(gem_repo4)}" gem 'weakling' G bundle "outdated --only-explicit" expected_output = <<~TABLE.strip Gem Current Latest Requested Groups weakling 0.2 0.3 >= 0 default TABLE expect(out).to end_with(expected_output) end end end