diff options
author | Asutosh Palai <asupalai@gmail.com> | 2016-07-19 22:49:42 +0530 |
---|---|---|
committer | Asutosh Palai <asupalai@gmail.com> | 2016-08-16 09:41:15 +0530 |
commit | 5977342e7ac4600051e7a38977a4e7c7cb420cc1 (patch) | |
tree | 57966a0c907829e449a178d485021b8bd7e47554 | |
parent | f81446d095c60a162ec57c18fd62c29e9567a0a2 (diff) | |
download | bundler-5977342e7ac4600051e7a38977a4e7c7cb420cc1.tar.gz |
Hooks implementation
-rw-r--r-- | lib/bundler/cli/install.rb | 2 | ||||
-rw-r--r-- | lib/bundler/plugin.rb | 23 | ||||
-rw-r--r-- | lib/bundler/plugin/api.rb | 4 | ||||
-rw-r--r-- | lib/bundler/plugin/index.rb | 17 | ||||
-rw-r--r-- | spec/plugins/hook_spec.rb | 28 |
5 files changed, 69 insertions, 5 deletions
diff --git a/lib/bundler/cli/install.rb b/lib/bundler/cli/install.rb index 5c7b8c5b0b..f95b2779c2 100644 --- a/lib/bundler/cli/install.rb +++ b/lib/bundler/cli/install.rb @@ -68,6 +68,8 @@ module Bundler definition = Bundler.definition definition.validate_ruby! + Plugin.hook("before-install-all", definition.dependencies) + installer = Installer.install(Bundler.root, definition, options) Bundler.load.cache if Bundler.app_cache.exist? && !options["no-cache"] && !Bundler.settings[:frozen] diff --git a/lib/bundler/plugin.rb b/lib/bundler/plugin.rb index cd3843fc0d..e55f0fcf1b 100644 --- a/lib/bundler/plugin.rb +++ b/lib/bundler/plugin.rb @@ -18,6 +18,8 @@ module Bundler @commands = {} @sources = {} + @hooks = {} + @loaded = [] # Installs a new plugin by the given name # @@ -137,6 +139,19 @@ module Bundler src.new(locked_opts.merge("uri" => locked_opts["remote"])) end + def add_hook(event, &block) + (@hooks[event.to_s] ||= []) << block + end + + def hook(event, *args) + plugins = index.hook_plugins(event) + return unless plugins + + (plugins - @loaded).each {|name| load_plugin(name) } + + @hooks[event].each {|blk| blk.call(*args) } + end + # currently only intended for specs # # @return [String, nil] installed path @@ -190,9 +205,11 @@ module Bundler def register_plugin(name, spec, optional_plugin = false) commands = @commands sources = @sources + hooks = @hooks @commands = {} @sources = {} + @hooks = {} load_paths = spec.load_paths add_to_load_path(load_paths) @@ -208,12 +225,14 @@ module Bundler Bundler.rm_rf(path) false else - index.register_plugin name, path.to_s, load_paths, @commands.keys, @sources.keys + index.register_plugin name, path.to_s, load_paths, @commands.keys, + @sources.keys, @hooks.keys true end ensure @commands = commands @sources = sources + @hooks = hooks end # Executes the plugins.rb file @@ -228,6 +247,8 @@ module Bundler add_to_load_path(index.load_paths(name)) load path.join(PLUGIN_FILE_NAME) + + @loaded << name rescue => e Bundler.ui.error "Failed loading plugin #{name}: #{e.message}" raise diff --git a/lib/bundler/plugin/api.rb b/lib/bundler/plugin/api.rb index 9ff4b7385b..5bd8792e55 100644 --- a/lib/bundler/plugin/api.rb +++ b/lib/bundler/plugin/api.rb @@ -44,6 +44,10 @@ module Bundler Plugin.add_source source, cls end + def self.hook(event, &block) + Plugin.add_hook(event, &block) + end + # The cache dir to be used by the plugins for storage # # @return [Pathname] path of the cache dir diff --git a/lib/bundler/plugin/index.rb b/lib/bundler/plugin/index.rb index 918b3a4392..455fb7b775 100644 --- a/lib/bundler/plugin/index.rb +++ b/lib/bundler/plugin/index.rb @@ -24,6 +24,7 @@ module Bundler @plugin_paths = {} @commands = {} @sources = {} + @hooks = {} @load_paths = {} load_index(global_index_file, true) @@ -39,7 +40,7 @@ module Bundler # @param [Array<String>] load_paths for the plugin # @param [Array<String>] commands that are handled by the plugin # @param [Array<String>] sources that are handled by the plugin - def register_plugin(name, path, load_paths, commands, sources) + def register_plugin(name, path, load_paths, commands, sources, hooks) old_commands = @commands.dup common = commands & @commands.keys @@ -50,6 +51,8 @@ module Bundler raise SourceConflict.new(name, common) unless common.empty? sources.each {|k| @sources[k] = name } + hooks.each {|e| (@hooks[e] ||= []) << name } + @plugin_paths[name] = path @load_paths[name] = load_paths save_index @@ -98,6 +101,10 @@ module Bundler @sources[name] end + def hook_plugins(event) + @hooks[event] + end + private # Reads the index file from the directory and initializes the instance @@ -119,6 +126,7 @@ module Bundler @load_paths.merge!(index["load_paths"]) @commands.merge!(index["commands"]) @sources.merge!(index["sources"]) unless global + @hooks.merge!(index["hooks"]) end end @@ -128,9 +136,10 @@ module Bundler def save_index index = { "plugin_paths" => @plugin_paths, - "load_paths" => @load_paths, - "commands" => @commands, - "sources" => @sources, + "load_paths" => @load_paths, + "commands" => @commands, + "sources" => @sources, + "hooks" => @hooks, } require "bundler/yaml_serializer" diff --git a/spec/plugins/hook_spec.rb b/spec/plugins/hook_spec.rb new file mode 100644 index 0000000000..3622d2a6e9 --- /dev/null +++ b/spec/plugins/hook_spec.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +require "spec_helper" + +describe "hook plugins", :focused 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 "yaml_spec" + gem "rake" + G + + expect(out).to include "gems to be installed yaml_spec, rake" + end +end |