diff options
author | Homu <homu@barosl.com> | 2016-08-16 08:42:50 +0900 |
---|---|---|
committer | Homu <homu@barosl.com> | 2016-08-16 08:42:50 +0900 |
commit | f81446d095c60a162ec57c18fd62c29e9567a0a2 (patch) | |
tree | 9fc6e04a3405f99b7855f99dece62e4c96791dc6 | |
parent | 7c38144e84b48cc932756932ad4679c4f71400c0 (diff) | |
parent | 888041af40a9e7a9a173439c41f2961de152b39c (diff) | |
download | bundler-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.rb | 3 | ||||
-rw-r--r-- | lib/bundler/plugin.rb | 28 | ||||
-rw-r--r-- | lib/bundler/plugin/index.rb | 31 | ||||
-rw-r--r-- | spec/bundler/plugin/index_spec.rb | 18 | ||||
-rw-r--r-- | spec/bundler/plugin/installer_spec.rb | 6 | ||||
-rw-r--r-- | spec/bundler/plugin_spec.rb | 19 | ||||
-rw-r--r-- | spec/plugins/install_spec.rb | 68 | ||||
-rw-r--r-- | spec/plugins/source_spec.rb | 20 | ||||
-rw-r--r-- | spec/support/path.rb | 8 |
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 |