lib/bundler/plugin/index.rb in bundler-1.13.0.rc.1 vs lib/bundler/plugin/index.rb in bundler-1.13.0.rc.2

- old
+ new

@@ -11,71 +11,138 @@ msg = "Command(s) `#{commands.join("`, `")}` declared by #{plugin} are already registered." super msg end end + class SourceConflict < PluginError + def initialize(plugin, sources) + msg = "Source(s) `#{sources.join("`, `")}` declared by #{plugin} are already registered." + super msg + end + end + def initialize @plugin_paths = {} @commands = {} + @sources = {} + @hooks = {} + @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 function shall add - # the functions of the plugin to existing maps and also the name to source location. + # This function is to be called when a new plugin is installed. This + # function shall add the functions of the plugin to existing maps and also + # the name to source location. # # @param [String] name of the plugin to be registered # @param [String] path where the plugin is installed + # @param [Array<String>] load_paths for the plugin # @param [Array<String>] commands that are handled by the plugin - def register_plugin(name, path, commands) - @plugin_paths[name] = path + # @param [Array<String>] sources that are handled by the plugin + def register_plugin(name, path, load_paths, commands, sources, hooks) + old_commands = @commands.dup common = commands & @commands.keys raise CommandConflict.new(name, common) unless common.empty? commands.each {|c| @commands[c] = name } + common = sources & @sources.keys + 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 + rescue + @commands = old_commands + 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 + def load_paths(name) + @load_paths[name] + end + # Fetch the name of plugin handling the command def command_plugin(command) @commands[command] end def installed?(name) @plugin_paths[name] end + def source?(source) + @sources.key? source + end + + def source_plugin(name) + @sources[name] + end + + # Returns the list of plugin names handling the passed event + def hook_plugins(event) + @hooks[event] || [] + end + private - # Reads the index file from the directory and initializes the instance variables. - def load_index + # Reads the index file from the directory and initializes the instance + # variables. + # + # 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"] || {} - @commands = index["commands"] || {} + + @commands.merge!(index["commands"]) + @hooks.merge!(index["hooks"]) + @load_paths.merge!(index["load_paths"]) + @plugin_paths.merge!(index["plugin_paths"]) + @sources.merge!(index["sources"]) unless global end end - # Should be called when any of the instance variables change. Stores the instance - # variables in YAML format. (The instance variables are supposed to be only String key value pairs) + # Should be called when any of the instance variables change. Stores the + # instance variables in YAML format. (The instance variables are supposed + # to be only String key value pairs) def save_index index = { + "commands" => @commands, + "hooks" => @hooks, + "load_paths" => @load_paths, "plugin_paths" => @plugin_paths, - "commands" => @commands, + "sources" => @sources, } require "bundler/yaml_serializer" SharedHelpers.filesystem_access(index_file) do |index_f| FileUtils.mkdir_p(index_f.dirname)