summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/bundler/plugin/api/source.rb33
-rw-r--r--spec/plugins/source.rb116
2 files changed, 147 insertions, 2 deletions
diff --git a/lib/bundler/plugin/api/source.rb b/lib/bundler/plugin/api/source.rb
index dad2e59024..f7f80c1b28 100644
--- a/lib/bundler/plugin/api/source.rb
+++ b/lib/bundler/plugin/api/source.rb
@@ -1,4 +1,6 @@
# frozen_string_literal: true
+require "uri"
+require "digest/sha1"
module Bundler
module Plugin
@@ -50,7 +52,8 @@ module Bundler
out << " specs:\n"
end
- def install
+ def install(spec, opts)
+ raise MalformattedPlugin, "Source plugins need to override the install method."
end
def fetch_gemfiles
@@ -64,9 +67,37 @@ module Bundler
def remote!
end
+ def cache!
+ end
+
def include?(other)
other == self
end
+
+ def ==(other)
+ other.is_a?(self.class) && uri == other.uri
+ end
+
+ def uri_hash
+ Digest::SHA1.hexdigest(uri)
+ end
+
+ def gem_install_dir
+ Bundler.install_path
+ end
+
+ def install_path
+ @install_path ||=
+ begin
+ base_name = File.basename(URI.parse(uri).normalize.path)
+
+ gem_install_dir.join("#{base_name}-#{uri_hash[0..11]}")
+ end
+ end
+
+ def installed?
+ File.directory?(install_path)
+ end
end
end
end
diff --git a/spec/plugins/source.rb b/spec/plugins/source.rb
index 4d1b26f9ae..8285133ab9 100644
--- a/spec/plugins/source.rb
+++ b/spec/plugins/source.rb
@@ -48,7 +48,121 @@ describe "bundler source plugin" do
end
end
- context "with a real source plugin" 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"
+
+ class MPath < Bundler::Plugin::API
+ source "mpath"
+
+ attr_reader :path
+
+ def initialize(opts)
+ super
+
+ @path = Pathname.new options["uri"]
+ end
+
+ def fetch_gemfiles
+ @gemfiles ||= begin
+ glob = "{,*,*/*}.gemspec"
+ if installed?
+ search_path = install_path
+ else
+ search_path = path
+ end
+ Dir["\#{search_path.to_s}/\#{glob}"].sort_by {|p| -p.split(File::SEPARATOR).size }
+ end
+ end
+
+ def install(spec, opts)
+ mkdir_p(install_path.parent)
+ FileUtils.cp_r(path, install_path)
+
+ nil
+ end
+ end
+ RUBY
+ end # build_plugin
+ end # build_repo
+
+ 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"
+
+ should_be_installed("a-path-gem 1.0")
+ end
+
+ it "writes to lock file" do
+ bundle "install"
+
+ lockfile_should_be <<-G
+ PLUGIN
+ 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
+
+ context "with lockfile" do
+ before do
+ lockfile <<-G
+ PLUGIN
+ 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", :focused do
+ bundle "install"
+
+ should_be_installed("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|