summaryrefslogtreecommitdiff
path: root/spec/bundler/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bundler/plugins')
-rw-r--r--spec/bundler/plugins/command_spec.rb50
-rw-r--r--spec/bundler/plugins/hook_spec.rb330
-rw-r--r--spec/bundler/plugins/install_spec.rb267
-rw-r--r--spec/bundler/plugins/list_spec.rb60
-rw-r--r--spec/bundler/plugins/source/example_spec.rb171
-rw-r--r--spec/bundler/plugins/source_spec.rb19
-rw-r--r--spec/bundler/plugins/uninstall_spec.rb74
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