Class: Usmu::Plugin

Inherits:
Object
  • Object
show all
Defined in:
lib/usmu/plugin.rb,
lib/usmu/plugin/core.rb,
lib/usmu/plugin/core_hooks.rb

Overview

Singletonish class to load plugins and act as an interface to them. Shouldn't be created directly.

See Also:

Defined Under Namespace

Classes: Core, CoreHooks

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePlugin

Constructor for the plugin interface.



7
8
9
# File 'lib/usmu/plugin.rb', line 7

def initialize
  @log = Logging.logger['Usmu::Plugin']
end

Instance Attribute Details

#pluginsArray (readonly)

Returns a list of all plugins discovered and loaded.

Returns:

  • (Array)

    a list of all plugins discovered and loaded.



26
27
28
# File 'lib/usmu/plugin.rb', line 26

def plugins
  @plugins ||= []
end

Instance Method Details

#[](klass) ⇒ void



30
31
32
# File 'lib/usmu/plugin.rb', line 30

def [](klass)
  plugins.select {|s| s.class == klass }.first
end

#alter(method, value, *context) ⇒ Object

Call all plugins and allow for altering a value.

The return value of each hook is passed into the next alter function, hence all implementations must always return a value. If the hook doesn't wish to modify data this call then it should return the original value.

Parameters:

  • method (Symbol)

    The name of the method to call. This should be namespaced somehow. For example, a plugin called usmu-s3 could use the method namespace s3 and have a hook called :s3_upload

  • value (Object)

    The value to modify.

  • context (Array)

    Optional extra parameters to provide.

Returns:

  • (Object)

    The modified value.



64
65
66
67
68
69
70
71
72
73
# File 'lib/usmu/plugin.rb', line 64

def alter(method, value, *context)
  @log.debug("Invoking plugin alter API #{method}")
  plugins.each do |p|
    if p.respond_to? "#{method}_alter"
      @log.debug("Sending message to #{p.class.name}")
      value = p.public_send "#{method}_alter", value, *context
    end
  end
  value
end

#invoke(method, *args) ⇒ Array

Call all plugins and collate any data returned.

nil can be returned explicitly to say this plugin has nothing to return.

Parameters:

  • method (Symbol)

    The name of the method to call. This should be namespaced somehow. For example, a plugin called usmu-s3 could use the method namespace s3 and have a hook called :s3_upload

  • args (Array)

    The arguments to pass through to plugins. Can be empty.

Returns:

  • (Array)

    An array of non-nil values returned from plugins



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/usmu/plugin.rb', line 42

def invoke(method, *args)
  @log.debug("Invoking plugin API #{method}")
  plugins.map do |p|
    if p.respond_to? method
      @log.debug("Sending message to #{p.class.name}")
      p.public_send method, *args
    else
      nil
    end
  end.select {|i| i}
end

#load_gem(spec) ⇒ void (private)

Helper function to load a plugin from a gem specification

Parameters:

  • spec (Gem::Specification)


88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/usmu/plugin.rb', line 88

def load_gem(spec)
  load_path = spec.name.gsub('-', '/')
  require load_path

  unless @loaded.include? load_path
    @loaded << load_path
    klass = path_to_class(load_path)
    @log.debug("Loading plugin #{klass} from '#{load_path}'")
    plugins.push plugin_get(klass)
  end
  nil
end

#load_pluginsvoid

Loads all plugins that are available as gems. This is determined by looking at the gem's name. Anything prefixed with the string 'usmu-' will be recognised as a plugin. This will load the gem according to the RubyGems recommendations for naming schemes. A gem named usmu-s3_uploader will be loaded by requiring the path 'usmu/s3_uploader' and then then the class Usmu::S3Uploader will be instantiated as the plugins interface.



15
16
17
18
19
20
21
22
# File 'lib/usmu/plugin.rb', line 15

def load_plugins
  @loaded = []
  @log.debug('Loading plugins')
  @log.debug('Loaded Usmu::Plugin::Core')
  plugins.push Usmu::Plugin::Core.new
  Gem::Specification.find_all { |s| s.name =~ /^usmu-/ }.each &method(:load_gem)
  @log.debug("Loaded: #{plugins.inspect}")
end

#path_to_class(load_path) ⇒ void (private)



101
102
103
# File 'lib/usmu/plugin.rb', line 101

def path_to_class(load_path)
  load_path.split('/').map { |s| s.split('_').map(&:capitalize).join }.join('::')
end

#plugin_get(klass) ⇒ Object (private)

Helper function to load and instantiate plugin classes

Parameters:

  • klass (String)

    The name of the class to load

Returns:

  • (Object)

    A plugin object



81
82
83
# File 'lib/usmu/plugin.rb', line 81

def plugin_get(klass)
  Object.const_get(klass).new
end