diff options
Diffstat (limited to 'spec/bundler/plugins')
| -rw-r--r-- | spec/bundler/plugins/command_spec.rb | 50 | ||||
| -rw-r--r-- | spec/bundler/plugins/hook_spec.rb | 330 | ||||
| -rw-r--r-- | spec/bundler/plugins/install_spec.rb | 267 | ||||
| -rw-r--r-- | spec/bundler/plugins/list_spec.rb | 60 | ||||
| -rw-r--r-- | spec/bundler/plugins/source/example_spec.rb | 171 | ||||
| -rw-r--r-- | spec/bundler/plugins/source_spec.rb | 19 | ||||
| -rw-r--r-- | spec/bundler/plugins/uninstall_spec.rb | 74 |
7 files changed, 802 insertions, 169 deletions
diff --git a/spec/bundler/plugins/command_spec.rb b/spec/bundler/plugins/command_spec.rb index 8275351d19..05d535a70c 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://#{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,15 +46,49 @@ RSpec.describe "command plugins" do end end - bundle "plugin install the-echoer --source file://#{gem_repo2}" + bundle "plugin install the-echoer --source https://gem.repo2" expect(out).to include("Installed plugin the-echoer") - bundle "echo tacos tofu lasange", "no-color" => false + bundle "echo tacos tofu lasange" expect(out).to eq("You gave me tacos, tofu, lasange") end + it "passes help flag to plugin" do + update_repo2 do + build_plugin "helpful" do |s| + s.write "plugins.rb", <<-RUBY + module Helpful + class Command + Bundler::Plugin::API.command "greet", self + + def exec(command, args) + if args.include?("--help") || args.include?("-h") + puts "Usage: bundle greet [NAME]" + else + puts "Hello" + end + end + end + end + RUBY + end + end + + bundle "plugin install helpful --source https://gem.repo2" + expect(out).to include("Installed plugin helpful") + + bundle "greet --help" + expect(out).to eq("Usage: bundle greet [NAME]") + + bundle "greet -h" + expect(out).to eq("Usage: bundle greet [NAME]") + + bundle "help greet" + expect(out).to eq("Usage: bundle greet [NAME]") + 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,12 +103,10 @@ RSpec.describe "command plugins" do end end - bundle "plugin install copycat --source file://#{gem_repo2}" + bundle "plugin install copycat --source https://gem.repo2", raise_on_error: false expect(out).not_to include("Installed plugin copycat") - expect(out).to include("Failed to install plugin") - - expect(out).to include("Command(s) `mahcommand` declared by copycat are already registered.") + expect(err).to include("Failed to install plugin `copycat`, due to Bundler::Plugin::Index::CommandConflict (Command(s) `mahcommand` declared by copycat are already registered.)") end end diff --git a/spec/bundler/plugins/hook_spec.rb b/spec/bundler/plugins/hook_spec.rb index 8bdf61a8ab..ad8a4daeff 100644 --- a/spec/bundler/plugins/hook_spec.rb +++ b/spec/bundler/plugins/hook_spec.rb @@ -1,27 +1,331 @@ # frozen_string_literal: true RSpec.describe "hook plugins" do - before do - build_repo2 do - build_plugin "before-install-plugin" do |s| - s.write "plugins.rb", <<-RUBY - Bundler::Plugin::API.hook "before-install-all" do |deps| - puts "gems to be installed \#{deps.map(&:name).join(", ")}" - end - RUBY + context "before-install-all hook" do + before do + build_repo2 do + build_plugin "before-install-all-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_INSTALL_ALL do |deps| + puts "gems to be installed \#{deps.map(&:name).join(", ")}" + end + RUBY + end end + + bundle "plugin install before-install-all-plugin --source https://gem.repo2" + end + + it "runs before all rubygems are installed" do + install_gemfile <<-G + source "https://gem.repo1" + gem "rake" + gem "myrack" + G + + expect(out).to include "gems to be installed rake, myrack" + end + end + + context "before-install hook" do + before do + build_repo2 do + build_plugin "before-install-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_INSTALL do |spec_install| + puts "installing gem \#{spec_install.name}" + end + RUBY + end + end + + bundle "plugin install before-install-plugin --source https://gem.repo2" + end + + it "runs before each rubygem is installed" do + install_gemfile <<-G + source "https://gem.repo1" + gem "rake" + gem "myrack" + G + + expect(out).to include "installing gem rake" + expect(out).to include "installing gem myrack" + end + end + + context "after-install-all hook" do + before do + build_repo2 do + build_plugin "after-install-all-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_INSTALL_ALL do |deps| + puts "installed gems \#{deps.map(&:name).join(", ")}" + end + RUBY + end + end + + bundle "plugin install after-install-all-plugin --source https://gem.repo2" + end + + it "runs after each all rubygems are installed" do + install_gemfile <<-G + source "https://gem.repo1" + gem "rake" + gem "myrack" + G + + expect(out).to include "installed gems rake, myrack" + end + end + + context "after-install hook" do + before do + build_repo2 do + build_plugin "after-install-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_INSTALL do |spec_install| + puts "installed gem \#{spec_install.name} : \#{spec_install.state}" + end + RUBY + end + end + + bundle "plugin install after-install-plugin --source https://gem.repo2" + end + + it "runs after each rubygem is installed" do + install_gemfile <<-G + source "https://gem.repo1" + gem "rake" + gem "myrack" + G + + expect(out).to include "installed gem rake : installed" + expect(out).to include "installed gem myrack : installed" + end + end + + context "before-require-all hook" do + before do + build_repo2 do + build_plugin "before-require-all-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_REQUIRE_ALL do |deps| + puts "gems to be required \#{deps.map(&:name).join(", ")}" + end + RUBY + end + end + + 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, myrack" + end + end + + context "before-require hook" do + before do + build_repo2 do + build_plugin "before-require-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_REQUIRE do |dep| + puts "requiring gem \#{dep.name}" + end + RUBY + end + end + + 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 myrack" + end + end + + context "after-require-all hook" do + before do + build_repo2 do + build_plugin "after-require-all-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_REQUIRE_ALL do |deps| + puts "required gems \#{deps.map(&:name).join(", ")}" + end + RUBY + end + end + + 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, myrack" + end + end + + context "after-require hook" do + before do + build_repo2 do + build_plugin "after-require-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_REQUIRE do |dep| + puts "required gem \#{dep.name}" + end + RUBY + end + end + + 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 myrack" + end + end + + context "before-eval hook" do + before do + build_repo2 do + build_plugin "before-eval-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_EVAL do |gemfile, lockfile| + puts "hooked eval start of \#{File.basename(gemfile)} to \#{File.basename(lockfile)}" + end + RUBY + end + end + + bundle "plugin install before-eval-plugin --source https://gem.repo2" + end + + it "runs before the Gemfile is evaluated" do + install_gemfile <<-G + source "https://gem.repo1" + gem "rake" + G + + expect(out).to include "hooked eval start of Gemfile to Gemfile.lock" + end + end + + context "after-eval hook" do + before do + build_repo2 do + build_plugin "after-eval-plugin" do |s| + s.write "plugins.rb", <<-RUBY + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_EVAL do |defn| + puts "hooked eval after with gems \#{defn.dependencies.map(&:name).join(", ")}" + end + RUBY + end + end + + bundle "plugin install after-eval-plugin --source https://gem.repo2" + end + + it "runs after the Gemfile is evaluated" do + install_gemfile <<-G + source "https://gem.repo1" + gem "myrack" + gem "rake" + G + + expect(out).to include "hooked eval after with gems myrack, rake" + end + end + + context "before-fetch and after-fetch hooks" do + before do + build_repo2 do + build_plugin "fetch-timing-plugin" do |s| + s.write "plugins.rb", <<-RUBY + @timing_start = nil + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_BEFORE_FETCH do |spec| + @timing_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + puts "gem \#{spec.name} started fetch at \#{@timing_start}" + end + Bundler::Plugin::API.hook Bundler::Plugin::Events::GEM_AFTER_FETCH do |spec| + timing_end = Process.clock_gettime(Process::CLOCK_MONOTONIC) + puts "gem \#{spec.name} took \#{timing_end - @timing_start} to fetch" + @timing_start = nil + end + RUBY + end + end + + bundle "plugin install fetch-timing-plugin --source https://gem.repo2" end - bundle "plugin install before-install-plugin --source file://#{gem_repo2}" + it "runs around each gem download" do + install_gemfile <<-G + source "https://gem.repo1" + gem "rake" + gem "myrack" + G + + expect(out).to include "gem rake started fetch at" + expect(out).to match(/gem rake took \d+\.\d+ to fetch/) + expect(out).to include "gem myrack started fetch at" + expect(out).to match(/gem myrack took \d+\.\d+ to fetch/) + end + end + + context "before-git-fetch and after-git-fetch hooks" do + before do + build_repo2 do + build_plugin "git-fetch-timing-plugin" do |s| + s.write "plugins.rb", <<-RUBY + @timing_start = nil + Bundler::Plugin::API.hook Bundler::Plugin::Events::GIT_BEFORE_FETCH do |source| + @timing_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + puts "git source \#{source.name} started fetch at \#{@timing_start}" + end + Bundler::Plugin::API.hook Bundler::Plugin::Events::GIT_AFTER_FETCH do |source| + timing_end = Process.clock_gettime(Process::CLOCK_MONOTONIC) + puts "git source \#{source.name} took \#{timing_end - @timing_start} to fetch" + @timing_start = nil + end + RUBY + end + end + + bundle "plugin install git-fetch-timing-plugin --source https://gem.repo2" + end + + it "runs around each git source fetch" 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 "git source foo started fetch at" + expect(out).to match(/git source foo took \d+\.\d+ to fetch/) + end end - it "runs after a rubygem is installed" do + def install_gemfile_and_bundler_require install_gemfile <<-G - source "file://#{gem_repo1}" + source "https://gem.repo1" gem "rake" - gem "rack" + gem "myrack" G - expect(out).to include "gems to be installed rake, rack" + ruby <<-RUBY + require "bundler" + Bundler.require + RUBY end end diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb index 9304d78062..dcacf764be 100644 --- a/spec/bundler/plugins/install_spec.rb +++ b/spec/bundler/plugins/install_spec.rb @@ -9,21 +9,54 @@ 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://#{gem_repo1}" + bundle "plugin install no-foo --source https://gem.repo1", raise_on_error: false - expect(out).to include("Could not find") + 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://#{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 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", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_SOURCES" => "https://gem.repo2" } + + expect(out).to include("Installed plugin foo") + plugin_should_be_installed("foo") + end + + it "shows help when --help flag is given" do + bundle "plugin install --help" + + # The help message defined in ../../lib/bundler/man/bundle-plugin.1.ronn will be output. + expect(out).to include("You can install, uninstall, and list plugin(s)") + end + + context "plugin is already installed" do + before do + bundle "plugin install foo --source https://gem.repo2" + end + + it "doesn't install plugin again" do + 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://#{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") @@ -37,13 +70,50 @@ RSpec.describe "bundler plugin install" do build_plugin "kung-foo", "1.1" end - bundle "plugin install foo kung-foo --version '1.0' --source file://#{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") end + it "installs the latest version if not installed" do + update_repo2 do + build_plugin "foo", "1.1" + end + + 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 https://gem.repo2 --verbose" + expect(out).to include("Installing foo 1.1") + + 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 https://gem.repo2", raise_on_error: false + + expect(out).not_to include("Installed plugin foo") + + expect(err).to include("--branch can only be used with git sources") + end + + it "raises an error when --ref specified" do + 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 https://gem.repo2 --branch main --ref v1.2.3", raise_on_error: false + + expect(out).not_to include("Installed plugin foo") + + expect(err).to include("You cannot specify `--branch` and `--ref` at the same time.") + end + it "works with different load paths" do build_repo2 do build_plugin "testing" do |s| @@ -61,7 +131,7 @@ RSpec.describe "bundler plugin install" do s.write("src/fubar.rb") end end - bundle "plugin install testing --source file://#{gem_repo2}" + bundle "plugin install testing --source https://gem.repo2" bundle "check2", "no-color" => false expect(out).to eq("mate") @@ -74,19 +144,19 @@ RSpec.describe "bundler plugin install" do build_plugin "kung-foo", "1.1" end - bundle "plugin install foo kung-foo --version '1.0' --source file://#{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://#{gem_repo2}" + bundle "plugin install charlie --source https://gem.repo2", raise_on_error: false - expect(out).to include("plugins.rb was not found") + expect(err).to include("Failed to install plugin `charlie`, due to Bundler::Plugin::MalformattedPlugin (plugins.rb was not found in the plugin.)") expect(global_plugin_gem("charlie-1.0")).not_to be_directory @@ -98,12 +168,12 @@ RSpec.describe "bundler plugin install" do build_repo2 do build_plugin "chaplin" do |s| s.write "plugins.rb", <<-RUBY - raise "I got you man" + raise RuntimeError, "threw exception on load" RUBY end end - bundle "plugin install chaplin --source file://#{gem_repo2}" + bundle "plugin install chaplin --source https://gem.repo2", raise_on_error: false expect(global_plugin_gem("chaplin-1.0")).not_to be_directory @@ -117,19 +187,72 @@ RSpec.describe "bundler plugin install" do s.write "plugins.rb" end - bundle "plugin install foo --git file://#{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") + end + + it "installs form a local git source" do + build_git "foo" do |s| + s.write "plugins.rb" + end + + bundle "plugin install foo --git #{lib_path("foo-1.0")}" expect(out).to include("Installed plugin foo") plugin_should_be_installed("foo") end end + context "path plugins" do + it "installs from a path source" do + build_lib "path_plugin" do |s| + s.write "plugins.rb" + end + bundle "plugin install path_plugin --path #{lib_path("path_plugin-1.0")}" + + expect(out).to include("Installed plugin path_plugin") + plugin_should_be_installed("path_plugin") + end + + it "installs from a relative path source" do + build_lib "path_plugin" do |s| + s.write "plugins.rb" + end + path = lib_path("path_plugin-1.0").relative_path_from(bundled_app) + bundle "plugin install path_plugin --path #{path}" + + expect(out).to include("Installed plugin path_plugin") + plugin_should_be_installed("path_plugin") + end + + it "installs from a relative path source when inside an app" do + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + gemfile "" + + build_lib "ga-plugin" do |s| + s.write "plugins.rb" + end + + path = lib_path("ga-plugin-1.0").relative_path_from(bundled_app) + bundle "plugin install ga-plugin --path #{path}" + + plugin_should_be_installed("ga-plugin") + expect(local_plugin_gem("foo-1.0")).not_to be_directory + end + end + context "Gemfile eval" do + before do + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + end + it "installs plugins listed in gemfile" do gemfile <<-G - source 'file://#{gem_repo2}' + source 'https://gem.repo2' plugin 'foo' - gem 'rack', "1.0.0" + gem 'myrack', "1.0.0" G bundle "install" @@ -138,17 +261,54 @@ 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 + it "overrides the index with the new plugin version" do + gemfile <<-G + source 'https://gem.repo2' + plugin 'foo', "1.0" + gem 'myrack', "1.0.0" + G + + bundle "install" + + update_repo2 do + build_plugin "foo", "2.0.0" + end + + gemfile <<-G + source 'https://gem.repo2' + plugin 'foo', "2.0" + gem 'myrack', "1.0.0" + G + + bundle "install" + + expected = local_plugin_gem("foo-2.0.0", "lib").to_s + expect(Bundler::Plugin.index.load_paths("foo")).to eq([expected]) + end + + it "respects bundler groups" do + gemfile <<-G + source 'https://gem.repo2' + plugin 'foo' + gem 'myrack', "1.0.0" + G + + bundle "install", env: { "BUNDLE_WITHOUT" => "default" } + + expect(out).to include("Bundle complete! 1 Gemfile dependency, 0 gems now installed.") + end + it "accepts plugin version" do update_repo2 do build_plugin "foo", "1.1.0" end - install_gemfile <<-G - source 'file://#{gem_repo2}' + gemfile <<-G + source 'https://gem.repo2' plugin 'foo', "1.0" G @@ -167,12 +327,65 @@ RSpec.describe "bundler plugin install" do end install_gemfile <<-G + source "https://gem.repo1" plugin 'ga-plugin', :git => "#{lib_path("ga-plugin-1.0")}" G expect(out).to include("Installed plugin ga-plugin") plugin_should_be_installed("ga-plugin") end + + it "accepts path sources" do + build_lib "ga-plugin" do |s| + s.write "plugins.rb" + end + + install_gemfile <<-G + source "https://gem.repo1" + plugin 'ga-plugin', :path => "#{lib_path("ga-plugin-1.0")}" + G + + expect(out).to include("Installed plugin ga-plugin") + plugin_should_be_installed("ga-plugin") + end + + it "accepts relative path sources" do + build_lib "ga-plugin" do |s| + s.write "plugins.rb" + end + + path = lib_path("ga-plugin-1.0").relative_path_from(bundled_app) + install_gemfile <<-G + source "https://gem.repo1" + plugin 'ga-plugin', :path => "#{path}" + G + + expect(out).to include("Installed plugin ga-plugin") + plugin_should_be_installed("ga-plugin") + end + + context "in deployment mode" do + it "installs plugins" do + install_gemfile <<-G + source 'https://gem.repo2' + gem 'myrack', "1.0.0" + G + + bundle_config "deployment true" + install_gemfile <<-G + source 'https://gem.repo2' + plugin 'foo' + 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("myrack 1.0.0") + plugin_should_be_installed("foo") + end + end end context "inline gemfiles" do @@ -181,20 +394,21 @@ RSpec.describe "bundler plugin install" do require "bundler/inline" gemfile do - source 'file://#{gem_repo2}' + source 'https://gem.repo2' plugin 'foo' end RUBY - ruby code + ruby code, artifice: "compact_index", env: { "BUNDLER_VERSION" => Bundler::VERSION } expect(local_plugin_gem("foo-1.0", "plugins.rb")).to exist end end describe "local plugin" 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://#{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 @@ -217,7 +431,7 @@ RSpec.describe "bundler plugin install" do end # inside the app - gemfile "source 'file://#{gem_repo2}'\nplugin 'fubar'" + gemfile "source 'https://gem.repo2'\nplugin 'fubar'" bundle "install" update_repo2 do @@ -235,21 +449,16 @@ RSpec.describe "bundler plugin install" do end # outside the app - Dir.chdir tmp - bundle "plugin install fubar --source file://#{gem_repo2}" + bundle "plugin install fubar --source https://gem.repo2", dir: tmp end it "inside the app takes precedence over global plugin" do - Dir.chdir bundled_app - bundle "shout" expect(out).to eq("local_one") end it "outside the app global plugin is used" do - Dir.chdir tmp - - bundle "shout" + bundle "shout", dir: tmp expect(out).to eq("global_one") end end diff --git a/spec/bundler/plugins/list_spec.rb b/spec/bundler/plugins/list_spec.rb new file mode 100644 index 0000000000..30e3f82467 --- /dev/null +++ b/spec/bundler/plugins/list_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +RSpec.describe "bundler plugin list" do + before do + build_repo2 do + build_plugin "foo" do |s| + s.write "plugins.rb", <<-RUBY + class Foo < Bundler::Plugin::API + command "shout" + + def exec(command, args) + puts "Foo shout" + end + end + RUBY + end + build_plugin "bar" do |s| + s.write "plugins.rb", <<-RUBY + class Bar < Bundler::Plugin::API + command "scream" + + def exec(command, args) + puts "Bar scream" + end + end + RUBY + end + end + end + + context "no plugins installed" do + it "shows proper no plugins installed message" do + bundle "plugin list" + + expect(out).to include("No plugins installed") + end + end + + context "single plugin installed" do + it "shows plugin name with commands list" do + bundle "plugin install foo --source https://gem.repo2" + plugin_should_be_installed("foo") + bundle "plugin list" + + expected_output = "foo\n-----\n shout" + expect(out).to include(expected_output) + end + end + + context "multiple plugins installed" do + it "shows plugin names with commands list" do + bundle "plugin install foo bar --source https://gem.repo2" + plugin_should_be_installed("foo", "bar") + bundle "plugin list" + + expected_output = "foo\n-----\n shout\n\nbar\n-----\n scream" + expect(out).to include(expected_output) + end + end +end diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb index 0dbd9a2a0f..4cd4a1a931 100644 --- a/spec/bundler/plugins/source/example_spec.rb +++ b/spec/bundler/plugins/source/example_spec.rb @@ -6,7 +6,6 @@ RSpec.describe "real source plugins" do build_repo2 do build_plugin "bundler-source-mpath" do |s| s.write "plugins.rb", <<-RUBY - require "bundler/vendored_fileutils" require "bundler-source-mpath" class MPath < Bundler::Plugin::API @@ -34,6 +33,7 @@ RSpec.describe "real source plugins" do def install(spec, opts) mkdir_p(install_path.parent) + require 'fileutils' FileUtils.cp_r(path, install_path) spec_path = install_path.join("\#{spec.full_name}.gemspec") @@ -52,7 +52,7 @@ RSpec.describe "real source plugins" do build_lib "a-path-gem" gemfile <<-G - source "file://#{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 @@ -67,10 +67,14 @@ RSpec.describe "real source plugins" do expect(the_bundle).to include_gems("a-path-gem 1.0") end - it "writes to lock file", :bundler => "< 2" do + it "writes to lockfile" do bundle "install" - lockfile_should_be <<-G + checksums = checksums_section_when_enabled do |c| + c.no_checksum "a-path-gem", "1.0" + end + + expect(lockfile).to eq <<~G PLUGIN SOURCE remote: #{lib_path("a-path-gem-1.0")} type: mpath @@ -78,42 +82,17 @@ RSpec.describe "real source plugins" do a-path-gem (1.0) GEM - remote: file:#{gem_repo2}/ + remote: https://gem.repo2/ specs: PLATFORMS - #{generic_local_platform} - - DEPENDENCIES - a-path-gem! - - BUNDLED WITH - #{Bundler::VERSION} - G - end - - it "writes to lock file", :bundler => "2" do - bundle "install" - - lockfile_should_be <<-G - GEM - remote: file:#{gem_repo2}/ - specs: - - PLUGIN SOURCE - remote: #{lib_path("a-path-gem-1.0")} - type: mpath - specs: - a-path-gem (1.0) - - PLATFORMS #{lockfile_platforms} DEPENDENCIES a-path-gem! - + #{checksums} BUNDLED WITH - #{Bundler::VERSION} + #{Bundler::VERSION} G end @@ -126,14 +105,14 @@ RSpec.describe "real source plugins" do end it "installs the gem executables" do - build_lib "gem-with-bin" do |s| + build_lib "gem_with_bin" do |s| s.executables = ["foo"] end install_gemfile <<-G - source "file://#{gem_repo2}" # plugin source - source "#{lib_path("gem-with-bin-1.0")}", :type => :mpath do - gem "gem-with-bin" + source "https://gem.repo2" # plugin source + source "#{lib_path("gem_with_bin-1.0")}", :type => :mpath do + gem "gem_with_bin" end G @@ -145,33 +124,35 @@ RSpec.describe "real source plugins" do let(:uri_hash) { Digest(:SHA1).hexdigest(lib_path("a-path-gem-1.0").to_s) } it "copies repository to vendor cache and uses it" do bundle "install" - bundle :cache, forgotten_command_line_options([:all, :cache_all] => true) + bundle :cache expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}/.git")).not_to exist expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}/.bundlecache")).to be_file - FileUtils.rm_rf lib_path("a-path-gem-1.0") + FileUtils.rm_r lib_path("a-path-gem-1.0") expect(the_bundle).to include_gems("a-path-gem 1.0") end - it "copies repository to vendor cache and uses it even when installed with bundle --path" do - bundle! :install, forgotten_command_line_options(:path => "vendor/bundle") - bundle! :cache, forgotten_command_line_options([:all, :cache_all] => true) + it "copies repository to vendor cache and uses it even when installed with `path` configured" do + bundle_config "path vendor/bundle" + bundle :install + bundle :cache expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist - FileUtils.rm_rf lib_path("a-path-gem-1.0") + FileUtils.rm_r lib_path("a-path-gem-1.0") expect(the_bundle).to include_gems("a-path-gem 1.0") end it "bundler package copies repository to vendor cache" do - bundle! :install, forgotten_command_line_options(:path => "vendor/bundle") - bundle! :package, forgotten_command_line_options([:all, :cache_all] => true) + bundle_config "path vendor/bundle" + bundle :install + bundle :cache expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist - FileUtils.rm_rf lib_path("a-path-gem-1.0") + FileUtils.rm_r lib_path("a-path-gem-1.0") expect(the_bundle).to include_gems("a-path-gem 1.0") end end @@ -186,7 +167,7 @@ RSpec.describe "real source plugins" do a-path-gem (1.0) GEM - remote: file:#{gem_repo2}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -196,12 +177,12 @@ RSpec.describe "real source plugins" do a-path-gem! BUNDLED WITH - #{Bundler::VERSION} + #{Bundler::VERSION} G end it "installs" do - bundle! "install" + bundle "install" expect(the_bundle).to include_gems("a-path-gem 1.0") end @@ -213,6 +194,8 @@ RSpec.describe "real source plugins" do build_repo2 do build_plugin "bundler-source-gitp" do |s| s.write "plugins.rb", <<-RUBY + require "open3" + class SPlugin < Bundler::Plugin::API source "gitp" @@ -221,7 +204,7 @@ RSpec.describe "real source plugins" do def initialize(opts) super - @ref = options["ref"] || options["branch"] || options["tag"] || "master" + @ref = options["ref"] || options["branch"] || options["tag"] || "main" @unlocked = false end @@ -252,9 +235,7 @@ RSpec.describe "real source plugins" do mkdir_p(install_path.dirname) rm_rf(install_path) `git clone --no-checkout --quiet "\#{cache_path}" "\#{install_path}"` - Dir.chdir install_path do - `git reset --hard \#{revision}` - end + Open3.capture2e("git reset --hard \#{revision}", :chdir => install_path) spec_path = install_path.join("\#{spec.full_name}.gemspec") spec_path.open("wb") {|f| f.write spec.to_ruby } @@ -267,7 +248,7 @@ RSpec.describe "real source plugins" do def options_to_lock opts = {"revision" => revision} - opts["ref"] = ref if ref != "master" + opts["ref"] = ref if ref != "main" opts end @@ -308,9 +289,8 @@ RSpec.describe "real source plugins" do cache_repo end - Dir.chdir cache_path do - `git rev-parse --verify \#{@ref}`.strip - end + output, _status = Open3.capture2e("git rev-parse --verify \#{@ref}", :chdir => cache_path) + output.strip end def base_name @@ -325,13 +305,7 @@ RSpec.describe "real source plugins" do @install_path ||= begin git_scope = "\#{base_name}-\#{shortref_for_path(revision)}" - path = gem_install_dir.join(git_scope) - - if !path.exist? && requires_sudo? - user_bundle_path.join(ruby_scope).join(git_scope) - else - path - end + gem_install_dir.join(git_scope) end end @@ -346,8 +320,8 @@ RSpec.describe "real source plugins" do build_git "ma-gitp-gem" gemfile <<-G - source "file://#{gem_repo2}" # plugin source - source "file://#{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 @@ -359,57 +333,34 @@ RSpec.describe "real source plugins" do expect(the_bundle).to include_gems("ma-gitp-gem 1.0") end - it "writes to lock file", :bundler => "< 2" do + it "writes to lockfile" do revision = revision_for(lib_path("ma-gitp-gem-1.0")) bundle "install" - lockfile_should_be <<-G + 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://#{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:#{gem_repo2}/ + remote: https://gem.repo2/ specs: PLATFORMS - #{generic_local_platform} - - DEPENDENCIES - ma-gitp-gem! - - BUNDLED WITH - #{Bundler::VERSION} - G - end - - it "writes to lock file", :bundler => "2" do - revision = revision_for(lib_path("ma-gitp-gem-1.0")) - bundle "install" - - lockfile_should_be <<-G - GEM - remote: file:#{gem_repo2}/ - specs: - - PLUGIN SOURCE - remote: file://#{lib_path("ma-gitp-gem-1.0")} - type: gitp - revision: #{revision} - specs: - ma-gitp-gem (1.0) - - PLATFORMS #{lockfile_platforms} DEPENDENCIES ma-gitp-gem! - + #{checksums} BUNDLED WITH - #{Bundler::VERSION} + #{Bundler::VERSION} G end @@ -418,14 +369,14 @@ RSpec.describe "real source plugins" do revision = revision_for(lib_path("ma-gitp-gem-1.0")) lockfile <<-G PLUGIN SOURCE - remote: file://#{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:#{gem_repo2}/ + remote: https://gem.repo2/ specs: PLATFORMS @@ -435,7 +386,7 @@ RSpec.describe "real source plugins" do ma-gitp-gem! BUNDLED WITH - #{Bundler::VERSION} + #{Bundler::VERSION} G end @@ -449,7 +400,7 @@ RSpec.describe "real source plugins" do bundle "install" run <<-RUBY - require 'ma-gitp-gem' + require 'ma/gitp/gem' puts "WIN" unless defined?(MAGITPGEM_PREV_REF) RUBY expect(out).to eq("WIN") @@ -460,17 +411,17 @@ RSpec.describe "real source plugins" do bundle "update ma-gitp-gem" run <<-RUBY - require 'ma-gitp-gem' + require 'ma/gitp/gem' puts "WIN" if defined?(MAGITPGEM_PREV_REF) RUBY expect(out).to eq("WIN") end 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 + update_git "ma-gitp-gem", "1.1", path: lib_path("ma-gitp-gem-1.0"), gemspec: true gemfile <<-G - source "file://#{gem_repo2}" # plugin source - source "file://#{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 @@ -483,21 +434,21 @@ RSpec.describe "real source plugins" do describe "bundle cache with gitp" do it "copies repository to vendor cache and uses it" do git = build_git "foo" - ref = git.ref_for("master", 11) + ref = git.ref_for("main", 11) install_gemfile <<-G - source "file://#{gem_repo2}" # plugin source + source "https://gem.repo2" # plugin source source '#{lib_path("foo-1.0")}', :type => :gitp do gem "foo" end G - bundle :cache, forgotten_command_line_options([:all, :cache_all] => true) + bundle :cache 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 - FileUtils.rm_rf lib_path("foo-1.0") + FileUtils.rm_r lib_path("foo-1.0") expect(the_bundle).to include_gems "foo 1.0" end end diff --git a/spec/bundler/plugins/source_spec.rb b/spec/bundler/plugins/source_spec.rb index 543e90eb60..995e50e653 100644 --- a/spec/bundler/plugins/source_spec.rb +++ b/spec/bundler/plugins/source_spec.rb @@ -16,11 +16,12 @@ RSpec.describe "bundler source plugin" do it "installs bundler-source-* gem when no handler for source is present" do install_gemfile <<-G - source "file://#{gem_repo2}" - source "file://#{lib_path("gitp")}", :type => :psource do + source "https://gem.repo2" + source "#{lib_path("gitp")}", :type => :psource do end G + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) plugin_should_be_installed("bundler-source-psource") end @@ -37,8 +38,8 @@ RSpec.describe "bundler source plugin" do end install_gemfile <<-G - source "file://#{gem_repo2}" - source "file://#{lib_path("gitp")}", :type => :psource do + source "https://gem.repo2" + source "#{lib_path("gitp")}", :type => :psource do end G @@ -61,11 +62,11 @@ RSpec.describe "bundler source plugin" do context "explicit presence in gemfile" do before do install_gemfile <<-G - source "file://#{gem_repo2}" + source "https://gem.repo2" plugin "another-psource" - source "file://#{lib_path("gitp")}", :type => :psource do + source "#{lib_path("gitp")}", :type => :psource do end G end @@ -75,6 +76,7 @@ RSpec.describe "bundler source plugin" do end it "installs the explicit one" do + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) plugin_should_be_installed("another-psource") end @@ -86,11 +88,11 @@ RSpec.describe "bundler source plugin" do context "explicit default source" do before do install_gemfile <<-G - source "file://#{gem_repo2}" + source "https://gem.repo2" plugin "bundler-source-psource" - source "file://#{lib_path("gitp")}", :type => :psource do + source "#{lib_path("gitp")}", :type => :psource do end G end @@ -100,6 +102,7 @@ RSpec.describe "bundler source plugin" do end it "installs the default one" do + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) plugin_should_be_installed("bundler-source-psource") end end diff --git a/spec/bundler/plugins/uninstall_spec.rb b/spec/bundler/plugins/uninstall_spec.rb new file mode 100644 index 0000000000..dedcc9f37c --- /dev/null +++ b/spec/bundler/plugins/uninstall_spec.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +RSpec.describe "bundler plugin uninstall" do + before do + build_repo2 do + build_plugin "foo" + build_plugin "kung-foo" + end + end + + it "shows proper error message when plugins are not specified" do + bundle "plugin uninstall" + expect(err).to include("No plugins to uninstall") + end + + it "uninstalls specified plugins" do + bundle "plugin install foo kung-foo --source https://gem.repo2" + plugin_should_be_installed("foo") + plugin_should_be_installed("kung-foo") + + bundle "plugin uninstall foo" + expect(out).to include("Uninstalled plugin foo") + plugin_should_not_be_installed("foo") + plugin_should_be_installed("kung-foo") + end + + it "shows proper message when plugin is not installed" do + bundle "plugin uninstall foo" + expect(err).to include("Plugin foo is not installed") + plugin_should_not_be_installed("foo") + end + + it "doesn't wipe out path plugins" do + build_lib "path_plugin" do |s| + s.write "plugins.rb" + end + path = lib_path("path_plugin-1.0") + expect(path).to be_a_directory + + allow(Bundler::SharedHelpers).to receive(:find_gemfile).and_return(bundled_app_gemfile) + + install_gemfile <<-G + source 'https://gem.repo2' + plugin 'path_plugin', :path => "#{path}" + gem 'myrack', '1.0.0' + G + + plugin_should_be_installed("path_plugin") + expect(Bundler::Plugin.index.plugin_path("path_plugin")).to eq path + + bundle "plugin uninstall path_plugin" + expect(out).to include("Uninstalled plugin path_plugin") + plugin_should_not_be_installed("path_plugin") + # the actual gem still exists though + expect(path).to be_a_directory + end + + describe "with --all" do + it "uninstalls all installed plugins" do + bundle "plugin install foo kung-foo --source https://gem.repo2" + plugin_should_be_installed("foo") + plugin_should_be_installed("kung-foo") + + bundle "plugin uninstall --all" + plugin_should_not_be_installed("foo") + plugin_should_not_be_installed("kung-foo") + end + + it "shows proper no plugins installed message when no plugins installed" do + bundle "plugin uninstall --all" + expect(out).to include("No plugins installed") + end + end +end |
