Module: Bundler::Plugin
- Defined in:
- lib/bundler/plugin/api.rb,
lib/bundler/plugin.rb,
lib/bundler/plugin/dsl.rb,
lib/bundler/plugin/index.rb,
lib/bundler/plugin/events.rb,
lib/bundler/plugin/installer.rb,
lib/bundler/plugin/api/source.rb,
lib/bundler/plugin/source_list.rb,
lib/bundler/plugin/installer/git.rb,
lib/bundler/plugin/installer/rubygems.rb
Overview
SourceList object to be used while parsing the Gemfile, setting the approptiate options to be used with Source classes for plugin installation
Defined Under Namespace
Modules: Events Classes: API, DSL, Index, Installer, MalformattedPlugin, SourceList, UndefinedCommandError, UnknownSourceError
Constant Summary collapse
- PLUGIN_FILE_NAME =
"plugins.rb".freeze
Class Method Summary collapse
-
.add_command(command, cls) ⇒ Object
To be called via the API to register to handle a command.
-
.add_hook(event, &block) ⇒ Object
To be called via the API to register a hooks and corresponding block that will be called to handle the hook.
-
.add_source(source, cls) ⇒ Object
To be called via the API to register to handle a source plugin.
- .add_to_load_path(load_paths) ⇒ Object
-
.cache ⇒ Object
The cache directory for plugin stuffs.
-
.command?(command) ⇒ Boolean
Checks if any plugin handles the command.
-
.exec_command(command, args) ⇒ Object
To be called from Cli class to pass the command and argument to approriate plugin class.
-
.gemfile_install(gemfile = nil, &inline) ⇒ Object
Evaluates the Gemfile with a limited DSL and installs the plugins specified by plugin method.
-
.global_root ⇒ Object
The global directory root for all plugin related data.
-
.hook(event, *args, &arg_blk) ⇒ Object
Runs all the hooks that are registered for the passed event.
-
.index ⇒ Object
The index object used to store the details about the plugin.
-
.install(names, options) ⇒ Object
Installs a new plugin by the given name.
-
.installed?(plugin) ⇒ String?
currently only intended for specs.
-
.load_plugin(name) ⇒ Object
Executes the plugins.rb file.
- .local_root ⇒ Object
-
.register_plugin(name, spec, optional_plugin = false) ⇒ Object
Runs the plugins.rb file in an isolated namespace, records the plugin actions it registers for and then passes the data to index to be stored.
- .reset! ⇒ Object
-
.root ⇒ Object
The directory root for all plugin related data.
-
.save_plugins(plugins, specs, optional_plugins = []) ⇒ Object
Post installation processing and registering with index.
-
.source(name) ⇒ Class
That handles the source.
-
.source?(name) ⇒ Boolean
Checks if any plugin declares the source.
-
.source_from_lock(locked_opts) ⇒ API::Source
The instance of the class that handles the source type passed in locked_opts.
-
.validate_plugin!(plugin_path) ⇒ Object
Checks if the gem is good to be a plugin.
Class Method Details
.add_command(command, cls) ⇒ Object
To be called via the API to register to handle a command
109 110 111 |
# File 'lib/bundler/plugin.rb', line 109 def add_command(command, cls) @commands[command] = cls end |
.add_hook(event, &block) ⇒ Object
To be called via the API to register a hooks and corresponding block that will be called to handle the hook
158 159 160 161 162 163 |
# File 'lib/bundler/plugin.rb', line 158 def add_hook(event, &block) unless Events.defined_event?(event) raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events" end @hooks_by_event[event.to_s] << block end |
.add_source(source, cls) ⇒ Object
To be called via the API to register to handle a source plugin
129 130 131 |
# File 'lib/bundler/plugin.rb', line 129 def add_source(source, cls) @sources[source] = cls end |
.add_to_load_path(load_paths) ⇒ Object
279 280 281 282 283 284 285 |
# File 'lib/bundler/plugin.rb', line 279 def add_to_load_path(load_paths) if insert_index = Bundler.rubygems.load_path_insert_index $LOAD_PATH.insert(insert_index, *load_paths) else $LOAD_PATH.unshift(*load_paths) end end |
.cache ⇒ Object
The cache directory for plugin stuffs
104 105 106 |
# File 'lib/bundler/plugin.rb', line 104 def cache @cache ||= root.join("cache") end |
.command?(command) ⇒ Boolean
Checks if any plugin handles the command
114 115 116 |
# File 'lib/bundler/plugin.rb', line 114 def command?(command) !index.command_plugin(command).nil? end |
.exec_command(command, args) ⇒ Object
To be called from Cli class to pass the command and argument to approriate plugin class
120 121 122 123 124 125 126 |
# File 'lib/bundler/plugin.rb', line 120 def exec_command(command, args) raise UndefinedCommandError, "Command `#{command}` not found" unless command? command load_plugin index.command_plugin(command) unless @commands.key? command @commands[command].new.exec(command, args) end |
.gemfile_install(gemfile = nil, &inline) ⇒ Object
Evaluates the Gemfile with a limited DSL and installs the plugins specified by plugin method
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/bundler/plugin.rb', line 55 def gemfile_install(gemfile = nil, &inline) builder = DSL.new if block_given? builder.instance_eval(&inline) else builder.eval_gemfile(gemfile) end definition = builder.to_definition(nil, true) return if definition.dependencies.empty? plugins = definition.dependencies.map(&:name).reject {|p| index.installed? p } installed_specs = Installer.new.install_definition(definition) save_plugins plugins, installed_specs, builder.inferred_plugins rescue RuntimeError => e unless e.is_a?(GemfileError) Bundler.ui.error "Failed to install plugin: #{e.}\n #{e.backtrace[0]}" end raise end |
.global_root ⇒ Object
The global directory root for all plugin related data
99 100 101 |
# File 'lib/bundler/plugin.rb', line 99 def global_root Bundler.user_bundle_path("plugin") end |
.hook(event, *args, &arg_blk) ⇒ Object
Runs all the hooks that are registered for the passed event
It passes the passed arguments and block to the block registered with the api.
171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/bundler/plugin.rb', line 171 def hook(event, *args, &arg_blk) return unless Bundler.feature_flag.plugins? unless Events.defined_event?(event) raise ArgumentError, "Event '#{event}' not defined in Bundler::Plugin::Events" end plugins = index.hook_plugins(event) return unless plugins.any? (plugins - @loaded_plugin_names).each {|name| load_plugin(name) } @hooks_by_event[event].each {|blk| blk.call(*args, &arg_blk) } end |
.index ⇒ Object
The index object used to store the details about the plugin
78 79 80 |
# File 'lib/bundler/plugin.rb', line 78 def index @index ||= Index.new end |
.install(names, options) ⇒ Object
Installs a new plugin by the given name
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/bundler/plugin.rb', line 37 def install(names, ) specs = Installer.new.install(names, ) save_plugins names, specs rescue PluginError => e if specs specs_to_delete = Hash[specs.select {|k, _v| names.include?(k) && !index.commands.values.include?(k) }] specs_to_delete.values.each {|spec| Bundler.rm_rf(spec.full_gem_path) } end Bundler.ui.error "Failed to install plugin #{name}: #{e.}\n #{e.backtrace.join("\n ")}" end |
.installed?(plugin) ⇒ String?
currently only intended for specs
188 189 190 |
# File 'lib/bundler/plugin.rb', line 188 def installed?(plugin) Index.new.installed?(plugin) end |
.load_plugin(name) ⇒ Object
Executes the plugins.rb file
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/bundler/plugin.rb', line 263 def load_plugin(name) # Need to ensure before this that plugin root where the rest of gems # are installed to be on load path to support plugin deps. Currently not # done to avoid conflicts path = index.plugin_path(name) add_to_load_path(index.load_paths(name)) load path.join(PLUGIN_FILE_NAME) @loaded_plugin_names << name rescue RuntimeError => e Bundler.ui.error "Failed loading plugin #{name}: #{e.}" raise end |
.local_root ⇒ Object
94 95 96 |
# File 'lib/bundler/plugin.rb', line 94 def local_root Bundler.app_config_path.join("plugin") end |
.register_plugin(name, spec, optional_plugin = false) ⇒ Object
Runs the plugins.rb file in an isolated namespace, records the plugin actions it registers for and then passes the data to index to be stored.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/bundler/plugin.rb', line 227 def register_plugin(name, spec, optional_plugin = false) commands = @commands sources = @sources hooks = @hooks_by_event @commands = {} @sources = {} @hooks_by_event = Hash.new {|h, k| h[k] = [] } load_paths = spec.load_paths add_to_load_path(load_paths) path = Pathname.new spec.full_gem_path begin load path.join(PLUGIN_FILE_NAME), true rescue StandardError => e raise MalformattedPlugin, "#{e.class}: #{e.}" end if optional_plugin && @sources.keys.any? {|s| source? s } Bundler.rm_rf(path) false else index.register_plugin(name, path.to_s, load_paths, @commands.keys, @sources.keys, @hooks_by_event.keys) true end ensure @commands = commands @sources = sources @hooks_by_event = hooks end |
.reset! ⇒ Object
21 22 23 24 25 26 27 28 |
# File 'lib/bundler/plugin.rb', line 21 def reset! instance_variables.each {|i| remove_instance_variable(i) } @sources = {} @commands = {} @hooks_by_event = Hash.new {|h, k| h[k] = [] } @loaded_plugin_names = [] end |
.root ⇒ Object
The directory root for all plugin related data
If run in an app, points to local root, in app_config_path Otherwise, points to global root, in Bundler.user_bundle_path(“plugin”)
86 87 88 89 90 91 92 |
# File 'lib/bundler/plugin.rb', line 86 def root @root ||= if SharedHelpers.in_bundle? local_root else global_root end end |
.save_plugins(plugins, specs, optional_plugins = []) ⇒ Object
Post installation processing and registering with index
198 199 200 201 202 203 204 205 |
# File 'lib/bundler/plugin.rb', line 198 def save_plugins(plugins, specs, optional_plugins = []) plugins.each do |name| spec = specs[name] validate_plugin! Pathname.new(spec.full_gem_path) installed = register_plugin(name, spec, optional_plugins.include?(name)) Bundler.ui.info "Installed plugin #{name}" if installed end end |
.source(name) ⇒ Class
Returns that handles the source. The calss includes API::Source.
139 140 141 142 143 144 145 |
# File 'lib/bundler/plugin.rb', line 139 def source(name) raise UnknownSourceError, "Source #{name} not found" unless source? name load_plugin(index.source_plugin(name)) unless @sources.key? name @sources[name] end |
.source?(name) ⇒ Boolean
Checks if any plugin declares the source
134 135 136 |
# File 'lib/bundler/plugin.rb', line 134 def source?(name) !index.source_plugin(name.to_s).nil? end |
.source_from_lock(locked_opts) ⇒ API::Source
Returns the instance of the class that handles the source type passed in locked_opts.
150 151 152 153 154 |
# File 'lib/bundler/plugin.rb', line 150 def source_from_lock(locked_opts) src = source(locked_opts["type"]) src.new(locked_opts.merge("uri" => locked_opts["remote"])) end |
.validate_plugin!(plugin_path) ⇒ Object
Checks if the gem is good to be a plugin
At present it only checks whether it contains plugins.rb file
213 214 215 216 |
# File 'lib/bundler/plugin.rb', line 213 def validate_plugin!(plugin_path) plugin_file = plugin_path.join(PLUGIN_FILE_NAME) raise MalformattedPlugin, "#{PLUGIN_FILE_NAME} was not found in the plugin." unless plugin_file.file? end |