summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHomu <homu@barosl.com>2016-08-16 08:42:50 +0900
committerHomu <homu@barosl.com>2016-08-16 08:42:50 +0900
commitf81446d095c60a162ec57c18fd62c29e9567a0a2 (patch)
tree9fc6e04a3405f99b7855f99dece62e4c96791dc6
parent7c38144e84b48cc932756932ad4679c4f71400c0 (diff)
parent888041af40a9e7a9a173439c41f2961de152b39c (diff)
downloadbundler-f81446d095c60a162ec57c18fd62c29e9567a0a2.tar.gz
Auto merge of #4788 - asutoshpalai:plugin-project-level, r=segiddins
Project local plugins If the user is in an app directory the plugin is installed in `.bundle/` inside the app root. If the user is in not in any app directory the plugin is installed in the `.bundle/` in the user's home.
-rw-r--r--lib/bundler.rb3
-rw-r--r--lib/bundler/plugin.rb28
-rw-r--r--lib/bundler/plugin/index.rb31
-rw-r--r--spec/bundler/plugin/index_spec.rb18
-rw-r--r--spec/bundler/plugin/installer_spec.rb6
-rw-r--r--spec/bundler/plugin_spec.rb19
-rw-r--r--spec/plugins/install_spec.rb68
-rw-r--r--spec/plugins/source_spec.rb20
-rw-r--r--spec/support/path.rb8
9 files changed, 163 insertions, 38 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index f5fdcf87d7..8b3f60d36a 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -398,6 +398,9 @@ EOF
@locked_gems = nil
@bundle_path = nil
@bin_path = nil
+
+ Plugin.reset!
+
return unless defined?(@rubygems) && @rubygems
rubygems.undo_replacements
rubygems.reset
diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb
index f5366d2a13..cd3843fc0d 100644
--- a/lib/bundler/plugin.rb
+++ b/lib/bundler/plugin.rb
@@ -63,9 +63,25 @@ module Bundler
@index ||= Index.new
end
- # The directory root to all plugin related data
+ # The directory root for all plugin related data
+ #
+ # Points to root in app_config_path if ran in an app else points to the one
+ # in user_bundle_path
def root
- @root ||= Bundler.user_bundle_path.join("plugin")
+ @root ||= if SharedHelpers.in_bundle?
+ local_root
+ else
+ global_root
+ end
+ end
+
+ def local_root
+ Bundler.app_config_path.join("plugin")
+ end
+
+ # The global directory root for all plugin related data
+ def global_root
+ Bundler.user_bundle_path.join("plugin")
end
# The cache directory for plugin stuffs
@@ -128,6 +144,14 @@ module Bundler
Index.new.installed?(plugin)
end
+ # Used by specs
+ def reset!
+ instance_variables.each {|i| remove_instance_variable(i) }
+
+ @sources = {}
+ @commands = {}
+ end
+
# Post installation processing and registering with index
#
# @param [Array<String>] plugins list to be installed
diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb
index 4abf85fb02..918b3a4392 100644
--- a/lib/bundler/plugin/index.rb
+++ b/lib/bundler/plugin/index.rb
@@ -26,7 +26,8 @@ module Bundler
@sources = {}
@load_paths = {}
- load_index
+ load_index(global_index_file, true)
+ load_index(local_index_file) if SharedHelpers.in_bundle?
end
# This function is to be called when a new plugin is installed. This
@@ -57,11 +58,21 @@ module Bundler
raise
end
- # Path where the index file is stored
+ # Path of default index file
def index_file
Plugin.root.join("index")
end
+ # Path where the global index file is stored
+ def global_index_file
+ Plugin.global_root.join("index")
+ end
+
+ # Path where the local index file is stored
+ def local_index_file
+ Plugin.local_root.join("index")
+ end
+
def plugin_path(name)
Pathname.new @plugin_paths[name]
end
@@ -91,17 +102,23 @@ module Bundler
# Reads the index file from the directory and initializes the instance
# variables.
- def load_index
+ #
+ # It skips the sources if the second param is true
+ # @param [Pathname] index file path
+ # @param [Boolean] is the index file global index
+ def load_index(index_file, global = false)
SharedHelpers.filesystem_access(index_file, :read) do |index_f|
valid_file = index_f && index_f.exist? && !index_f.size.zero?
break unless valid_file
+
data = index_f.read
require "bundler/yaml_serializer"
index = YAMLSerializer.load(data)
- @plugin_paths = index["plugin_paths"] || {}
- @load_paths = index["load_paths"] || {}
- @commands = index["commands"] || {}
- @sources = index["sources"] || {}
+
+ @plugin_paths.merge!(index["plugin_paths"])
+ @load_paths.merge!(index["load_paths"])
+ @commands.merge!(index["commands"])
+ @sources.merge!(index["sources"]) unless global
end
end
diff --git a/spec/bundler/plugin/index_spec.rb b/spec/bundler/plugin/index_spec.rb
index 15db178966..337182abf1 100644
--- a/spec/bundler/plugin/index_spec.rb
+++ b/spec/bundler/plugin/index_spec.rb
@@ -6,6 +6,10 @@ describe Bundler::Plugin::Index do
subject(:index) { Index.new }
+ before do
+ gemfile ""
+ end
+
describe "#register plugin" do
before do
path = lib_path("new-plugin")
@@ -75,6 +79,20 @@ describe Bundler::Plugin::Index do
end
end
+ describe "global index" do
+ before do
+ Dir.chdir(tmp) do
+ path = lib_path("gplugin")
+ index.register_plugin("gplugin", path.to_s, [path.join("lib").to_s], [], ["glb_source"])
+ end
+ end
+
+ it "skips sources" do
+ new_index = Index.new
+ expect(new_index.source_plugin("glb_source")).to be_falsy
+ end
+ end
+
describe "after conflict" do
before do
path = lib_path("aplugin")
diff --git a/spec/bundler/plugin/installer_spec.rb b/spec/bundler/plugin/installer_spec.rb
index a914aabbf3..9d6eb1c55b 100644
--- a/spec/bundler/plugin/installer_spec.rb
+++ b/spec/bundler/plugin/installer_spec.rb
@@ -75,7 +75,7 @@ describe Bundler::Plugin::Installer do
it "has expected full_gem)path" do
expect(result["re-plugin"].full_gem_path).
- to eq(plugin_gems("re-plugin-1.0").to_s)
+ to eq(global_plugin_gem("re-plugin-1.0").to_s)
end
end
@@ -90,8 +90,8 @@ describe Bundler::Plugin::Installer do
end
it "has expected full_gem)path" do
- expect(result["re-plugin"].full_gem_path).to eq(plugin_gems("re-plugin-1.0").to_s)
- expect(result["ma-plugin"].full_gem_path).to eq(plugin_gems("ma-plugin-1.0").to_s)
+ expect(result["re-plugin"].full_gem_path).to eq(global_plugin_gem("re-plugin-1.0").to_s)
+ expect(result["ma-plugin"].full_gem_path).to eq(global_plugin_gem("ma-plugin-1.0").to_s)
end
end
end
diff --git a/spec/bundler/plugin_spec.rb b/spec/bundler/plugin_spec.rb
index 0c81df2232..f6f10201b3 100644
--- a/spec/bundler/plugin_spec.rb
+++ b/spec/bundler/plugin_spec.rb
@@ -209,4 +209,23 @@ describe Bundler::Plugin do
expect(subject.source_from_lock(opts)).to be(s_instance)
end
end
+
+ describe "#root" do
+ context "in app dir" do
+ before do
+ gemfile ""
+ end
+
+ it "returns plugin dir in app .bundle path" do
+ expect(subject.root).to eq(bundled_app.join(".bundle/plugin"))
+ end
+ end
+
+ context "outside app dir" do
+ it "returns plugin dir in global bundle path" do
+ Dir.chdir tmp
+ expect(subject.root).to eq(home.join(".bundle/plugin"))
+ end
+ end
+ end
end
diff --git a/spec/plugins/install_spec.rb b/spec/plugins/install_spec.rb
index c667ed0a68..a24f318156 100644
--- a/spec/plugins/install_spec.rb
+++ b/spec/plugins/install_spec.rb
@@ -78,7 +78,7 @@ describe "bundler plugin install" do
expect(out).to include("plugins.rb was not found")
- expect(plugin_gems("charlie-1.0")).not_to be_directory
+ expect(global_plugin_gem("charlie-1.0")).not_to be_directory
plugin_should_not_be_installed("charlie")
end
@@ -94,7 +94,7 @@ describe "bundler plugin install" do
bundle "plugin install chaplin --source file://#{gem_repo2}"
- expect(plugin_gems("chaplin-1.0")).not_to be_directory
+ expect(global_plugin_gem("chaplin-1.0")).not_to be_directory
plugin_should_not_be_installed("chaplin")
end
@@ -176,7 +176,71 @@ describe "bundler plugin install" do
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/plugins/source_spec.rb b/spec/plugins/source_spec.rb
index ea164e9811..92e948c190 100644
--- a/spec/plugins/source_spec.rb
+++ b/spec/plugins/source_spec.rb
@@ -59,26 +59,6 @@ describe "bundler source plugin" do
end
end
- context "installed though cli" do
- before do
- bundle "plugin install another-psource --source file://#{gem_repo2}"
-
- install_gemfile <<-G
- source "file://#{gem_repo2}"
- source "file://#{lib_path("gitp")}", :type => :psource do
- end
- G
- end
-
- it "completes successfully" do
- expect(out).to include("Bundle complete!")
- end
-
- it "doesn't install the default one" do
- plugin_should_not_be_installed("bundler-source-psource")
- end
- end
-
context "explicit presence in gemfile" do
before do
install_gemfile <<-G
diff --git a/spec/support/path.rb b/spec/support/path.rb
index 4aa99ee118..cf77adb509 100644
--- a/spec/support/path.rb
+++ b/spec/support/path.rb
@@ -81,12 +81,12 @@ module Spec
Pathname.new(File.expand_path("../../../lib", __FILE__))
end
- def plugin_root(*args)
- home ".bundle", "plugin", *args
+ def global_plugin_gem(*args)
+ home ".bundle", "plugin", "gems", *args
end
- def plugin_gems(*args)
- plugin_root "gems", *args
+ def local_plugin_gem(*args)
+ bundled_app ".bundle", "plugin", "gems", *args
end
extend self