aboutsummaryrefslogtreecommitdiffstats
path: root/spec/bundler/plugins
diff options
context:
space:
mode:
authorhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-08 08:45:41 +0000
committerhsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-08 08:45:41 +0000
commit8598f8c2dc78c6d1ae87cb6ae19c34ba2cb29241 (patch)
tree0bbd28f684e745cb212761b7c74fe08668f85cc8 /spec/bundler/plugins
parentf2e04b77aa8a363d7e36ce5a9cdb60714a537a3c (diff)
downloadruby-8598f8c2dc78c6d1ae87cb6ae19c34ba2cb29241.tar.gz
Merge bundler to standard libraries.
rubygems 2.7.x depends bundler-1.15.x. This is preparation for rubygems and bundler migration. * lib/bundler.rb, lib/bundler/*: files of bundler-1.15.4 * spec/bundler/*: rspec examples of bundler-1.15.4. I applied patches. * https://github.com/bundler/bundler/pull/6007 * Exclude not working examples on ruby repository. * Fake ruby interpriter instead of installed ruby. * Makefile.in: Added test task named `test-bundler`. This task is only working macOS/linux yet. I'm going to support Windows environment later. * tool/sync_default_gems.rb: Added sync task for bundler. [Feature #12733][ruby-core:77172] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59779 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/bundler/plugins')
-rw-r--r--spec/bundler/plugins/command_spec.rb81
-rw-r--r--spec/bundler/plugins/hook_spec.rb28
-rw-r--r--spec/bundler/plugins/install_spec.rb258
-rw-r--r--spec/bundler/plugins/source/example_spec.rb446
-rw-r--r--spec/bundler/plugins/source_spec.rb109
5 files changed, 922 insertions, 0 deletions
diff --git a/spec/bundler/plugins/command_spec.rb b/spec/bundler/plugins/command_spec.rb
new file mode 100644
index 0000000000..6ad782b758
--- /dev/null
+++ b/spec/bundler/plugins/command_spec.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe "command plugins" do
+ before do
+ build_repo2 do
+ build_plugin "command-mah" do |s|
+ s.write "plugins.rb", <<-RUBY
+ module Mah
+ class Plugin < Bundler::Plugin::API
+ command "mahcommand" # declares the command
+
+ def exec(command, args)
+ puts "MahHello"
+ end
+ end
+ end
+ RUBY
+ end
+ end
+
+ bundle "plugin install command-mah --source file://#{gem_repo2}"
+ end
+
+ it "executes without arguments" do
+ expect(out).to include("Installed plugin command-mah")
+
+ bundle "mahcommand"
+ expect(out).to eq("MahHello")
+ end
+
+ it "accepts the arguments" do
+ build_repo2 do
+ build_plugin "the-echoer" do |s|
+ s.write "plugins.rb", <<-RUBY
+ module Resonance
+ class Echoer
+ # Another method to declare the command
+ Bundler::Plugin::API.command "echo", self
+
+ def exec(command, args)
+ puts "You gave me \#{args.join(", ")}"
+ end
+ end
+ end
+ RUBY
+ end
+ end
+
+ bundle "plugin install the-echoer --source file://#{gem_repo2}"
+ expect(out).to include("Installed plugin the-echoer")
+
+ bundle "echo tacos tofu lasange", "no-color" => false
+ expect(out).to eq("You gave me tacos, tofu, lasange")
+ end
+
+ it "raises error on redeclaration of command" do
+ build_repo2 do
+ build_plugin "copycat" do |s|
+ s.write "plugins.rb", <<-RUBY
+ module CopyCat
+ class Cheater < Bundler::Plugin::API
+ command "mahcommand", self
+
+ def exec(command, args)
+ end
+ end
+ end
+ RUBY
+ end
+ end
+
+ bundle "plugin install copycat --source file://#{gem_repo2}"
+
+ 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.")
+ end
+end
diff --git a/spec/bundler/plugins/hook_spec.rb b/spec/bundler/plugins/hook_spec.rb
new file mode 100644
index 0000000000..9850d850ac
--- /dev/null
+++ b/spec/bundler/plugins/hook_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+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
+ end
+ end
+
+ bundle "plugin install before-install-plugin --source file://#{gem_repo2}"
+ end
+
+ it "runs after a rubygem is installed" do
+ install_gemfile <<-G
+ source "file://#{gem_repo1}"
+ gem "rake"
+ gem "rack"
+ G
+
+ expect(out).to include "gems to be installed rake, rack"
+ end
+end
diff --git a/spec/bundler/plugins/install_spec.rb b/spec/bundler/plugins/install_spec.rb
new file mode 100644
index 0000000000..e2d351181c
--- /dev/null
+++ b/spec/bundler/plugins/install_spec.rb
@@ -0,0 +1,258 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe "bundler plugin install" do
+ before do
+ build_repo2 do
+ build_plugin "foo"
+ build_plugin "kung-foo"
+ end
+ end
+
+ it "shows proper message when gem in not found in the source" do
+ bundle "plugin install no-foo --source file://#{gem_repo1}"
+
+ expect(out).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}"
+
+ expect(out).to include("Installed plugin foo")
+ plugin_should_be_installed("foo")
+ end
+
+ it "installs multiple plugins" do
+ bundle "plugin install foo kung-foo --source file://#{gem_repo2}"
+
+ expect(out).to include("Installed plugin foo")
+ expect(out).to include("Installed plugin kung-foo")
+
+ plugin_should_be_installed("foo", "kung-foo")
+ end
+
+ it "uses the same version for multiple plugins" do
+ update_repo2 do
+ build_plugin "foo", "1.1"
+ build_plugin "kung-foo", "1.1"
+ end
+
+ bundle "plugin install foo kung-foo --version '1.0' --source file://#{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 "works with different load paths" do
+ build_repo2 do
+ build_plugin "testing" do |s|
+ s.write "plugins.rb", <<-RUBY
+ require "fubar"
+ class Test < Bundler::Plugin::API
+ command "check2"
+
+ def exec(command, args)
+ puts "mate"
+ end
+ end
+ RUBY
+ s.require_paths = %w(lib src)
+ s.write("src/fubar.rb")
+ end
+ end
+ bundle "plugin install testing --source file://#{gem_repo2}"
+
+ bundle "check2", "no-color" => false
+ expect(out).to eq("mate")
+ end
+
+ context "malformatted plugin" do
+ it "fails when plugins.rb is missing" do
+ update_repo2 do
+ build_plugin "foo", "1.1"
+ build_plugin "kung-foo", "1.1"
+ end
+
+ bundle "plugin install foo kung-foo --version '1.0' --source file://#{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
+ build_gem "charlie"
+ end
+
+ bundle "plugin install charlie --source file://#{gem_repo2}"
+
+ expect(out).to include("plugins.rb was not found")
+
+ expect(global_plugin_gem("charlie-1.0")).not_to be_directory
+
+ plugin_should_be_installed("foo", "kung-foo")
+ plugin_should_not_be_installed("charlie")
+ end
+
+ it "fails when plugins.rb throws exception on load" do
+ build_repo2 do
+ build_plugin "chaplin" do |s|
+ s.write "plugins.rb", <<-RUBY
+ raise "I got you man"
+ RUBY
+ end
+ end
+
+ bundle "plugin install chaplin --source file://#{gem_repo2}"
+
+ expect(global_plugin_gem("chaplin-1.0")).not_to be_directory
+
+ plugin_should_not_be_installed("chaplin")
+ end
+ end
+
+ context "git plugins" do
+ it "installs form a git source" do
+ build_git "foo" do |s|
+ s.write "plugins.rb"
+ end
+
+ bundle "plugin install foo --git file://#{lib_path("foo-1.0")}"
+
+ expect(out).to include("Installed plugin foo")
+ plugin_should_be_installed("foo")
+ end
+ end
+
+ context "Gemfile eval" do
+ it "installs plugins listed in gemfile" do
+ gemfile <<-G
+ source 'file://#{gem_repo2}'
+ plugin 'foo'
+ gem 'rack', "1.0.0"
+ G
+
+ bundle "install"
+
+ expect(out).to include("Installed plugin foo")
+
+ expect(out).to include("Bundle complete!")
+
+ expect(the_bundle).to include_gems("rack 1.0.0")
+ plugin_should_be_installed("foo")
+ end
+
+ it "accepts plugin version" do
+ update_repo2 do
+ build_plugin "foo", "1.1.0"
+ end
+
+ install_gemfile <<-G
+ source 'file://#{gem_repo2}'
+ plugin 'foo', "1.0"
+ G
+
+ bundle "install"
+
+ expect(out).to include("Installing foo 1.0")
+
+ plugin_should_be_installed("foo")
+
+ expect(out).to include("Bundle complete!")
+ end
+
+ it "accepts git sources" do
+ build_git "ga-plugin" do |s|
+ s.write "plugins.rb"
+ end
+
+ install_gemfile <<-G
+ 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
+ end
+
+ context "inline gemfiles" do
+ it "installs the listed plugins" do
+ code = <<-RUBY
+ require "bundler/inline"
+
+ gemfile do
+ source 'file://#{gem_repo2}'
+ plugin 'foo'
+ end
+ RUBY
+
+ ruby code
+ 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
+ gemfile ""
+ bundle "plugin install foo --source file://#{gem_repo2}"
+
+ plugin_should_be_installed("foo")
+ expect(local_plugin_gem("foo-1.0")).to be_directory
+ end
+
+ context "conflict with global plugin" do
+ before do
+ update_repo2 do
+ build_plugin "fubar" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class Fubar < Bundler::Plugin::API
+ command "shout"
+
+ def exec(command, args)
+ puts "local_one"
+ end
+ end
+ RUBY
+ end
+ end
+
+ # inside the app
+ gemfile "source 'file://#{gem_repo2}'\nplugin 'fubar'"
+ bundle "install"
+
+ update_repo2 do
+ build_plugin "fubar", "1.1" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class Fubar < Bundler::Plugin::API
+ command "shout"
+
+ def exec(command, args)
+ puts "global_one"
+ end
+ end
+ RUBY
+ end
+ end
+
+ # outside the app
+ Dir.chdir tmp
+ bundle "plugin install fubar --source file://#{gem_repo2}"
+ 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"
+ expect(out).to eq("global_one")
+ end
+ end
+ end
+end
diff --git a/spec/bundler/plugins/source/example_spec.rb b/spec/bundler/plugins/source/example_spec.rb
new file mode 100644
index 0000000000..2ae34caf73
--- /dev/null
+++ b/spec/bundler/plugins/source/example_spec.rb
@@ -0,0 +1,446 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe "real source plugins" do
+ context "with a minimal source plugin" do
+ before do
+ build_repo2 do
+ build_plugin "bundler-source-mpath" do |s|
+ s.write "plugins.rb", <<-RUBY
+ require "fileutils"
+ require "bundler-source-mpath"
+
+ class MPath < Bundler::Plugin::API
+ source "mpath"
+
+ attr_reader :path
+
+ def initialize(opts)
+ super
+
+ @path = Pathname.new options["uri"]
+ end
+
+ def fetch_gemspec_files
+ @spec_files ||= begin
+ glob = "{,*,*/*}.gemspec"
+ if installed?
+ search_path = install_path
+ else
+ search_path = path
+ end
+ Dir["\#{search_path.to_s}/\#{glob}"]
+ end
+ end
+
+ def install(spec, opts)
+ mkdir_p(install_path.parent)
+ FileUtils.cp_r(path, install_path)
+
+ post_install(spec)
+
+ nil
+ end
+ end
+ RUBY
+ end # build_plugin
+ end
+
+ build_lib "a-path-gem"
+
+ gemfile <<-G
+ source "file://#{gem_repo2}" # plugin source
+ source "#{lib_path("a-path-gem-1.0")}", :type => :mpath do
+ gem "a-path-gem"
+ end
+ G
+ end
+
+ it "installs" do
+ bundle "install"
+
+ expect(out).to include("Bundle complete!")
+
+ expect(the_bundle).to include_gems("a-path-gem 1.0")
+ end
+
+ it "writes to lock file" do
+ bundle "install"
+
+ lockfile_should_be <<-G
+ PLUGIN SOURCE
+ remote: #{lib_path("a-path-gem-1.0")}
+ type: mpath
+ specs:
+ a-path-gem (1.0)
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+
+ PLATFORMS
+ #{generic_local_platform}
+
+ DEPENDENCIES
+ a-path-gem!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
+ it "provides correct #full_gem_path" do
+ bundle "install"
+ run <<-RUBY
+ puts Bundler.rubygems.find_name('a-path-gem').first.full_gem_path
+ RUBY
+ expect(out).to eq(bundle("show a-path-gem"))
+ end
+
+ it "installs the gem executables" do
+ 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"
+ end
+ G
+
+ bundle "exec foo"
+ expect(out).to eq("1.0")
+ end
+
+ describe "bundle cache/package" 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 --all"
+
+ 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")
+ 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 --path vendor/bundle"
+ bundle "cache --all"
+
+ expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
+
+ FileUtils.rm_rf 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 --path vendor/bundle"
+ bundle "package --all"
+
+ expect(bundled_app("vendor/cache/a-path-gem-1.0-#{uri_hash}")).to exist
+
+ FileUtils.rm_rf lib_path("a-path-gem-1.0")
+ expect(the_bundle).to include_gems("a-path-gem 1.0")
+ end
+ end
+
+ context "with lockfile" do
+ before do
+ lockfile <<-G
+ PLUGIN SOURCE
+ remote: #{lib_path("a-path-gem-1.0")}
+ type: mpath
+ specs:
+ a-path-gem (1.0)
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+
+ PLATFORMS
+ #{generic_local_platform}
+
+ DEPENDENCIES
+ a-path-gem!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
+ it "installs" do
+ bundle "install"
+
+ expect(the_bundle).to include_gems("a-path-gem 1.0")
+ end
+ end
+ end
+
+ context "with a more elaborate source plugin" do
+ before do
+ build_repo2 do
+ build_plugin "bundler-source-gitp" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class SPlugin < Bundler::Plugin::API
+ source "gitp"
+
+ attr_reader :ref
+
+ def initialize(opts)
+ super
+
+ @ref = options["ref"] || options["branch"] || options["tag"] || "master"
+ @unlocked = false
+ end
+
+ def eql?(other)
+ other.is_a?(self.class) && uri == other.uri && ref == other.ref
+ end
+
+ alias_method :==, :eql?
+
+ def fetch_gemspec_files
+ @spec_files ||= begin
+ glob = "{,*,*/*}.gemspec"
+ if !cached?
+ cache_repo
+ end
+
+ if installed? && !@unlocked
+ path = install_path
+ else
+ path = cache_path
+ end
+
+ Dir["\#{path}/\#{glob}"]
+ end
+ end
+
+ def install(spec, opts)
+ 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
+
+ post_install(spec)
+
+ nil
+ end
+
+ def options_to_lock
+ opts = {"revision" => revision}
+ opts["ref"] = ref if ref != "master"
+ opts
+ end
+
+ def unlock!
+ @unlocked = true
+ @revision = latest_revision
+ end
+
+ def app_cache_dirname
+ "\#{base_name}-\#{shortref_for_path(revision)}"
+ end
+
+ private
+
+ def cache_path
+ @cache_path ||= cache_dir.join("gitp", base_name)
+ end
+
+ def cache_repo
+ `git clone --quiet \#{@options["uri"]} \#{cache_path}`
+ end
+
+ def cached?
+ File.directory?(cache_path)
+ end
+
+ def locked_revision
+ options["revision"]
+ end
+
+ def revision
+ @revision ||= locked_revision || latest_revision
+ end
+
+ def latest_revision
+ if !cached? || @unlocked
+ rm_rf(cache_path)
+ cache_repo
+ end
+
+ Dir.chdir cache_path do
+ `git rev-parse --verify \#{@ref}`.strip
+ end
+ end
+
+ def base_name
+ File.basename(uri.sub(%r{^(\w+://)?([^/:]+:)?(//\w*/)?(\w*/)*}, ""), ".git")
+ end
+
+ def shortref_for_path(ref)
+ ref[0..11]
+ end
+
+ def install_path
+ @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
+ end
+ end
+
+ def installed?
+ File.directory?(install_path)
+ end
+ end
+ RUBY
+ end
+ end
+
+ 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
+ gem "ma-gitp-gem"
+ end
+ G
+ end
+
+ it "handles the source option" do
+ bundle "install"
+ expect(out).to include("Bundle complete!")
+ expect(the_bundle).to include_gems("ma-gitp-gem 1.0")
+ end
+
+ it "writes to lock file" do
+ revision = revision_for(lib_path("ma-gitp-gem-1.0"))
+ bundle "install"
+
+ lockfile_should_be <<-G
+ PLUGIN SOURCE
+ remote: file://#{lib_path("ma-gitp-gem-1.0")}
+ type: gitp
+ revision: #{revision}
+ specs:
+ ma-gitp-gem (1.0)
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+
+ PLATFORMS
+ #{generic_local_platform}
+
+ DEPENDENCIES
+ ma-gitp-gem!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
+ context "with lockfile" do
+ before do
+ revision = revision_for(lib_path("ma-gitp-gem-1.0"))
+ lockfile <<-G
+ PLUGIN SOURCE
+ remote: file://#{lib_path("ma-gitp-gem-1.0")}
+ type: gitp
+ revision: #{revision}
+ specs:
+ ma-gitp-gem (1.0)
+
+ GEM
+ remote: file:#{gem_repo2}/
+ specs:
+
+ PLATFORMS
+ #{generic_local_platform}
+
+ DEPENDENCIES
+ ma-gitp-gem!
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ G
+ end
+
+ it "installs" do
+ bundle "install"
+ expect(the_bundle).to include_gems("ma-gitp-gem 1.0")
+ end
+
+ it "uses the locked ref" do
+ update_git "ma-gitp-gem"
+ bundle "install"
+
+ run <<-RUBY
+ require 'ma-gitp-gem'
+ puts "WIN" unless defined?(MAGITPGEM_PREV_REF)
+ RUBY
+ expect(out).to eq("WIN")
+ end
+
+ it "updates the deps on bundler update" do
+ update_git "ma-gitp-gem"
+ bundle "update ma-gitp-gem"
+
+ run <<-RUBY
+ 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
+ gemfile <<-G
+ source "file://#{gem_repo2}" # plugin source
+ source "file://#{lib_path("ma-gitp-gem-1.0")}", :type => :gitp do
+ gem "ma-gitp-gem", "1.1"
+ end
+ G
+ bundle "install"
+
+ expect(the_bundle).to include_gems("ma-gitp-gem 1.1")
+ end
+ end
+
+ 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)
+
+ install_gemfile <<-G
+ source "file://#{gem_repo2}" # plugin source
+ source '#{lib_path("foo-1.0")}', :type => :gitp do
+ gem "foo"
+ end
+ G
+
+ bundle "cache --all"
+ 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")
+ expect(the_bundle).to include_gems "foo 1.0"
+ end
+ end
+ end
+end
diff --git a/spec/bundler/plugins/source_spec.rb b/spec/bundler/plugins/source_spec.rb
new file mode 100644
index 0000000000..0448bc409a
--- /dev/null
+++ b/spec/bundler/plugins/source_spec.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe "bundler source plugin" do
+ describe "plugins dsl eval for #source with :type option" do
+ before do
+ update_repo2 do
+ build_plugin "bundler-source-psource" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class OPSource < Bundler::Plugin::API
+ source "psource"
+ end
+ RUBY
+ end
+ end
+ end
+
+ 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
+ end
+ G
+
+ plugin_should_be_installed("bundler-source-psource")
+ end
+
+ it "enables the plugin to require a lib path" do
+ update_repo2 do
+ build_plugin "bundler-source-psource" do |s|
+ s.write "plugins.rb", <<-RUBY
+ require "bundler-source-psource"
+ class PSource < Bundler::Plugin::API
+ source "psource"
+ end
+ RUBY
+ end
+ end
+
+ install_gemfile <<-G
+ source "file://#{gem_repo2}"
+ source "file://#{lib_path("gitp")}", :type => :psource do
+ end
+ G
+
+ expect(out).to include("Bundle complete!")
+ end
+
+ context "with an explicit handler" do
+ before do
+ update_repo2 do
+ build_plugin "another-psource" do |s|
+ s.write "plugins.rb", <<-RUBY
+ class Cheater < Bundler::Plugin::API
+ source "psource"
+ end
+ RUBY
+ end
+ end
+ end
+
+ context "explicit presence in gemfile" do
+ before do
+ install_gemfile <<-G
+ source "file://#{gem_repo2}"
+
+ plugin "another-psource"
+
+ source "file://#{lib_path("gitp")}", :type => :psource do
+ end
+ G
+ end
+
+ it "completes successfully" do
+ expect(out).to include("Bundle complete!")
+ end
+
+ it "installs the explicit one" do
+ plugin_should_be_installed("another-psource")
+ end
+
+ it "doesn't install the default one" do
+ plugin_should_not_be_installed("bundler-source-psource")
+ end
+ end
+
+ context "explicit default source" do
+ before do
+ install_gemfile <<-G
+ source "file://#{gem_repo2}"
+
+ plugin "bundler-source-psource"
+
+ source "file://#{lib_path("gitp")}", :type => :psource do
+ end
+ G
+ end
+
+ it "completes successfully" do
+ expect(out).to include("Bundle complete!")
+ end
+
+ it "installs the default one" do
+ plugin_should_be_installed("bundler-source-psource")
+ end
+ end
+ end
+ end
+end