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/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
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
108 109 110 |
# File 'lib/bundler/plugin.rb', line 108 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
157 158 159 |
# File 'lib/bundler/plugin.rb', line 157 def add_hook(event, &block) @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
128 129 130 |
# File 'lib/bundler/plugin.rb', line 128 def add_source(source, cls) @sources[source] = cls end |
.add_to_load_path(load_paths) ⇒ Object
272 273 274 275 276 277 278 |
# File 'lib/bundler/plugin.rb', line 272 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
103 104 105 |
# File 'lib/bundler/plugin.rb', line 103 def cache @cache ||= root.join("cache") end |
.command?(command) ⇒ Boolean
Checks if any plugin handles the command
113 114 115 |
# File 'lib/bundler/plugin.rb', line 113 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
119 120 121 122 123 124 125 |
# File 'lib/bundler/plugin.rb', line 119 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
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/bundler/plugin.rb', line 54 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 => 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
98 99 100 |
# File 'lib/bundler/plugin.rb', line 98 def global_root Bundler.user_bundle_path.join("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.
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/bundler/plugin.rb', line 167 def hook(event, *args, &arg_blk) return unless Bundler.feature_flag.plugins? 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
77 78 79 |
# File 'lib/bundler/plugin.rb', line 77 def index @index ||= Index.new end |
.install(names, options) ⇒ Object
Installs a new plugin by the given name
36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/bundler/plugin.rb', line 36 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
181 182 183 |
# File 'lib/bundler/plugin.rb', line 181 def installed?(plugin) Index.new.installed?(plugin) end |
.load_plugin(name) ⇒ Object
Executes the plugins.rb file
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/bundler/plugin.rb', line 256 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 => e Bundler.ui.error "Failed loading plugin #{name}: #{e.}" raise end |
.local_root ⇒ Object
93 94 95 |
# File 'lib/bundler/plugin.rb', line 93 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.
220 221 222 223 224 225 226 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 |
# File 'lib/bundler/plugin.rb', line 220 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
20 21 22 23 24 25 26 27 |
# File 'lib/bundler/plugin.rb', line 20 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
Points to root in app_config_path if ran in an app else points to the one in user_bundle_path
85 86 87 88 89 90 91 |
# File 'lib/bundler/plugin.rb', line 85 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
191 192 193 194 195 196 197 198 |
# File 'lib/bundler/plugin.rb', line 191 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.
138 139 140 141 142 143 144 |
# File 'lib/bundler/plugin.rb', line 138 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
133 134 135 |
# File 'lib/bundler/plugin.rb', line 133 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.
149 150 151 152 153 |
# File 'lib/bundler/plugin.rb', line 149 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
206 207 208 209 |
# File 'lib/bundler/plugin.rb', line 206 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 |