Module: LittlePlugger

Defined in:
lib/bel/vendor/little-plugger.rb

Overview

Synopsis

LittlePlugger is a module that provides Gem based plugin management. By extending your own class or module with LittlePlugger you can easily manage the loading and initializing of plugins provided by other gems.

Details

Plugins are great! They allow other developers to add functionality to an application but relieve the application developer of the responsibility for mainting some other developer’s plugin code. LittlePlugger aims to make it dead simple to manage external plugins as gems.

Naming

Every plugin managed by LittlePlugger will have a name represented as a Symbol. This name is used to register the plugin, load the plugin file, and manage the plugin class/module. Here are the three rules for plugin names:

1) all lowercase with underscores 2) maps to a file of the same name with an ‘.rb’ extension 3) converting the name to camel case yields the plugin class / module

These rules are essentially the standard ruby practice of naming files after the class / module the file defines.

Finding & Loading

Plugins are found by searching through the lib folders of all installed gems; these gems are not necessarily loaded - just searched. If the lib folder has a subdirectory that matches the plugin_path, then all ruby files in the gem’s plugin_path are noted for later loading.

A file is only loaded if the basename of the file matches one of the registered plugin names. If no plugins are registered, then every file in the plugin_path is loaded.

The plugin classes / modules are all expected to live in the same namespace for a particular application. For example, all plugins for the “Foo” application should reside in a “Foo::Plugins” namespace. This allows the plugins to be automatically initialized by LittlePlugger.

Initializing

Optionally, plugins can provide an initialization method for running any setup code needed by the plugin. This initialize method should be named as follows: “initializer_#plugin_name” where the name of the plugin is appended to the end of the initializer method name.

If this method exists, it will be called automatically when plugins are loaded. The order of loading of initialization is not strictly defined, so do not rely on another plugin being initialized for your own plugin successfully initialize.

Usage

LittlePlugger is used by extending your own class or module with the LittlePlugger module.

module Logging
  extend LittlePlugger
end

This defines a plugin_path and a plugin_module for our Logging module. The plugin_path is set to “logging/plugins”, and therefore, the plugin_modlue is defined as Logging::Plugins. All plugins for the Logging module should be found underneath this plugin module.

The plugins for the Logging module are loaded and initialized by calling the initialize_plugins method.

Logging.initialize_plugins

If you only want to load the plugin files but not initialize the plugin classes / modules then you can call the load_plugins method.

Logging.load_plugins

Finally, you can get a hash of all the loaded plugins.

Logging.plugins

This returns a hash keyed by the plugin names with the plugin class / module as the value.

If you only want a certain set of plugins to be loaded, then pass the names to the plugin method.

Logging.plugin :foo, :bar, :baz

Now only three plugins for the Logging module will be loaded.

Customizing

LittlePlugger allows the use of a custom plugin path and module. These are specified when extending with LilttlePlugger by passing the specific path and module to LittlePlugger.

class Hoe
  extend LittlePlugger( :path => 'hoe', :module => Hoe )

  plugin(
      :clean, :debug, :deps, :flay, :flog, :package,
      :publish, :rcov, :signing, :test
  )
end

All ruby files found under the “hoe” directory will be treated as plugins, and the plugin classes / modules should reside directly under the Hoe namespace.

We also specify a list of plugins to be loaded. Only these plugins will be loaded and initialized by the LittlePlugger module. The plugin method can be called multiple times to add more plugins.

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

VERSION =

:nodoc:

'1.1.4'

Class Method Summary collapse

Class Method Details

.default_plugin_module(path) ⇒ Object

For a given path returns the class or module corresponding to the path. This method assumes a correspondence between directory names and Ruby namespaces.

default_plugin_module( "foo_bar/baz/plugins" )  #=> FooBar::Baz::Plugins

This method will fail if any of the namespaces have not yet been defined.



267
268
269
270
271
272
# File 'lib/bel/vendor/little-plugger.rb', line 267

def self.default_plugin_module( path )
  path.split(File::SEPARATOR).inject(Object) do |mod, const|
    const = const.split('_').map { |s| s.capitalize }.join
    mod.const_get const
  end
end

.default_plugin_path(obj) ⇒ Object

For a given object returns a default plugin path. The path is created by splitting the object’s class name on the namespace separator “::” and converting each part of the namespace into an underscored string (see the underscore method). The strings are then joined using the File#join method to give a filesystem path. Appended to this path is the ‘plugins’ directory.

default_plugin_path( FooBar::Baz )    #=> "foo_bar/baz/plugins"


253
254
255
256
# File 'lib/bel/vendor/little-plugger.rb', line 253

def self.default_plugin_path( obj )
  obj = obj.class unless obj.is_a? Module
  File.join(underscore(obj.name), 'plugins')
end

.extended(other) ⇒ Object

Called when another object extends itself with LittlePlugger.



226
227
228
# File 'lib/bel/vendor/little-plugger.rb', line 226

def self.extended( other )
  other.extend ClassMethods
end

.underscore(string) ⇒ Object

Convert the given string from camel case to snake case. Method liberally stolen from ActiveSupport.

underscore( "FooBar" )    #=> "foo_bar"


235
236
237
238
239
240
241
242
# File 'lib/bel/vendor/little-plugger.rb', line 235

def self.underscore( string )
  string.to_s.
      gsub(%r/::/, '/').
      gsub(%r/([A-Z]+)([A-Z][a-z])/,'\1_\2').
      gsub(%r/([a-z\d])([A-Z])/,'\1_\2').
      tr('-', '_').
      downcase
end

.versionObject

Returns the version string for the library.



117
118
119
# File 'lib/bel/vendor/little-plugger.rb', line 117

def self.version
  VERSION
end