autoload()
click to toggle source
def autoload
logger.info("Autoloading registered plugins at #{Time.now}")
@load_info.keys.each do |type|
logger.debug("Autoloading type: #{type}")
@load_info[type].each do |provider, plugin|
logger.debug("Autoloading provider #{provider} at #{plugin[:directory]}")
nucleon_require(plugin[:directory], provider)
@load_info[type][provider][:class] = provider_class(plugin[:namespace], type, provider)
logger.debug("Updated #{type} #{provider} load info: #{@load_info[type][provider].inspect}")
load(:extension, provider, { :name => provider }) if type == :extension
end
end
end
check(method, options = {})
click to toggle source
def check(method, options = {})
config = Config.ensure(options)
logger.debug("Checking extension #{method} given: #{config.export.inspect}")
success = exec(method, config.import({ :extension_type => :check })) do |op, data|
if op == :reduce
! data.values.include?(false)
else
data ? true : false
end
end
success = success.nil? || success ? true : false
logger.debug("Extension #{method} check result: #{success.inspect}")
success
end
class_const(name, separator = '::')
click to toggle source
def class_const(name, separator = '::')
components = class_name(name, separator, TRUE)
constant = Object
components.each do |component|
constant = constant.const_defined?(component) ?
constant.const_get(component) :
constant.const_missing(component)
end
constant
end
class_name(name, separator = '::', want_array = FALSE)
click to toggle source
def class_name(name, separator = '::', want_array = FALSE)
components = []
case name
when String, Symbol
components = name.to_s.split(separator)
when Array
components = name
end
components.collect! do |value|
value = value.to_s.strip
value[0] = value.capitalize[0] if value =~ /^[a-z]/
value
end
if want_array
return components
end
components.join(separator)
end
collect(method, options = {})
click to toggle source
def collect(method, options = {})
config = Config.ensure(options)
values = []
logger.debug("Collecting extension #{method} values")
exec(method, config.import({ :extension_type => :collect })) do |op, data|
if op == :process
values << data unless data.nil?
end
end
values = values.flatten
logger.debug("Extension #{method} collected values: #{values.inspect}")
values
end
config(type, options = {})
click to toggle source
def config(type, options = {})
config = Config.ensure(options)
logger.debug("Generating #{type} extended configuration from: #{config.export.inspect}")
exec("#{type}_config", Config.new(config.export)) do |op, data|
if op == :reduce
data.each do |provider, result|
config.import(result)
end
nil
else
data
end
end
config.delete(:extension_type)
logger.debug("Final extended configuration: #{config.export.inspect}")
config
end
create(type, provider, options = {})
click to toggle source
def create(type, provider, options = {})
type = type.to_sym
provider = provider.to_sym
unless @types.has_key?(type)
logger.warn("Plugin type #{type} creation requested but it has not been registered yet")
return nil
end
info = @load_info[type][provider] if Util::Data.exists?(@load_info, [ type, provider ])
if info
logger.debug("Plugin information for #{provider} #{type} found.")
instance_name = "#{provider}_" + Nucleon.sha1(options)
options = translate(info[:namespace], type, provider, options)
@plugins[type] = {} unless @plugins.has_key?(type)
unless instance_name && @plugins[type].has_key?(instance_name)
info[:instance_name] = instance_name
options[:meta] = Config.new(info).import(Util::Data.hash(options[:meta]))
logger.info("Creating new plugin #{provider} #{type}")
plugin = info[:class].new(type, provider, options)
@plugins[type][instance_name] = plugin
end
return @plugins[type][instance_name]
end
logger.warn("Plugin information cannot be found for plugin #{type} #{provider}")
nil
end
define_namespace(*names)
click to toggle source
def define_namespace(*names)
names.each do |namespace|
@namespaces[namespace.to_sym] = true
end
end
define_type(type_info)
click to toggle source
def define_type(type_info)
if type_info.is_a?(Hash)
logger.info("Defining plugin types at #{Time.now}")
type_info.each do |type, default_provider|
logger.debug("Mapping plugin type #{type} to default provider #{default_provider}")
@types[type.to_sym] = default_provider
end
else
logger.warn("Defined types must be specified as a hash to be registered properly")
end
end
exec(method, options = {}) { |:process, result| ... }
click to toggle source
def exec(method, options = {})
results = nil
if Nucleon.log_level == :hook
logger.hook("Executing extension hook #{Nucleon.blue(method)} at #{Nucleon.green(Time.now.to_s)}")
end
extensions = plugins(:extension)
extensions.each do |name, plugin|
provider = plugin.plugin_provider
result = nil
logger.debug("Checking extension #{provider}")
if plugin.respond_to?(method)
results = {} if results.nil?
result = plugin.send(method, options)
logger.info("Completed hook #{method} at #{Time.now} with: #{result.inspect}")
if block_given?
results[provider] = yield(:process, result)
logger.debug("Processed extension result into: #{results[provider].inspect}")
end
if results[provider].nil?
logger.debug("Setting extension result to: #{result.inspect}")
results[provider] = result
end
end
end
if ! results.nil? && block_given?
results = yield(:reduce, results)
logger.debug("Reducing extension results to: #{results.inspect}")
else
logger.debug("Final extension results: #{results.inspect}")
end
results
end
get(type, name)
click to toggle source
def get(type, name)
logger.info("Fetching plugin #{type} #{name}")
if @plugins.has_key?(type)
@plugins[type].each do |instance_name, plugin|
if plugin.plugin_name.to_s == name.to_s
logger.debug("Plugin #{type} #{name} found")
return plugin
end
end
end
logger.debug("Plugin #{type} #{name} not found")
nil
end
load(type, provider = nil, options = {})
click to toggle source
def load(type, provider = nil, options = {})
default_provider = type_default(type)
config = Config.ensure(options)
provider = config.delete(:provider, provider)
provider = default_provider unless provider
load_base(type, provider, config)
end
load_base(type, provider, options = {})
click to toggle source
def load_base(type, provider, options = {})
logger.info("Fetching plugin #{type} provider #{provider} at #{Time.now}")
options = translate_type(type, options)
config = Config.ensure(options)
name = config.get(:name, nil)
ensure_new = config.delete(:new, false)
if name
logger.debug("Looking up existing instance of #{name}")
if existing_instance = get(type, name)
unless ensure_new
config.export.each do |property_name, value|
unless [ :name, :meta ].include?(property_name)
existing_instance[property_name] = value
end
end
existing_instance.normalize(true)
logger.debug("Using existing instance of #{type}, #{name}")
return existing_instance
end
end
end
create(type, provider, options)
end
load_multiple(type, data, build_hash = false, keep_array = false)
click to toggle source
def load_multiple(type, data, build_hash = false, keep_array = false)
logger.info("Fetching multiple plugins of #{type} at #{Time.now}")
group = ( build_hash ? {} : [] )
klass = plugin_class(type)
data = klass.build_info(type, data) if klass.respond_to?(:build_info)
data.each do |options|
if plugin = load(type, options[:provider], options)
if build_hash
group[plugin.plugin_name] = plugin
else
group << plugin
end
end
end
return group.shift if ! build_hash && group.length == 1 && ! keep_array
group
end
loaded_plugins(type = nil, provider = nil)
click to toggle source
def loaded_plugins(type = nil, provider = nil)
results = {}
type = type.to_sym if type
provider = provider.to_sym if provider
if type && @load_info.has_key?(type)
if provider && @load_info.has_key?(provider)
results = @load_info[type][provider]
else
results = @load_info[type]
end
elsif ! type
results = @load_info
end
results
end
myself()
click to toggle source
def myself
Nucleon.handle(self)
end
namespaces()
click to toggle source
def namespaces
@namespaces.keys
end
plugin_class(type)
click to toggle source
def plugin_class(type)
class_const([ :nucleon, :plugin, type ])
end
plugins(type = nil, provider = nil)
click to toggle source
def plugins(type = nil, provider = nil)
results = {}
type = type.to_sym if type
provider = provider.to_sym if provider
if type && @plugins.has_key?(type)
if provider && ! @plugins[type].keys.empty?
@plugins[type].each do |instance_name, plugin|
plugin = @plugins[type][instance_name]
results[instance_name] = plugin if plugin.plugin_provider == provider
end
else
results = @plugins[type]
end
elsif ! type
results = @plugins
end
results
end
provider_class(namespace, type, provider)
click to toggle source
def provider_class(namespace, type, provider)
class_const([ namespace, type, provider ])
end
register(base_path, &code)
click to toggle source
def register(base_path, &code)
namespaces.each do |namespace|
namespace_path = File.join(base_path, namespace.to_s)
register_namespace(namespace, namespace_path, &code)
end
end
reload(core = false, &code)
click to toggle source
def reload(core = false, &code)
logger.info("Loading Nucleon plugins at #{Time.now}")
if core
Celluloid.logger = logger if Nucleon.parallel?
define_namespace :nucleon
define_type :extension => nil,
:action => :update,
:project => :git,
:command => :bash,
:event => :regex,
:template => :json,
:translator => :json
end
code.call(:define, myself) if code
load_plugins(core, &code)
logger.info("Finished loading Nucleon plugins at #{Time.now}")
end
remove(plugin)
click to toggle source
def remove(plugin)
if plugin && plugin.respond_to?(:plugin_type) && @plugins.has_key?(plugin.plugin_type)
logger.debug("Removing #{plugin.plugin_type} #{plugin.plugin_name}")
@plugins[plugin.plugin_type].delete(plugin.plugin_instance_name)
plugin.remove_plugin
plugin.terminate if plugin.respond_to?(:terminate)
else
logger.warn("Cannot remove plugin: #{plugin.inspect}")
end
end
test_connection()
click to toggle source
def test_connection
true
end
translate(namespace, type, provider, options)
click to toggle source
def translate(namespace, type, provider, options)
klass = provider_class(namespace, type, provider)
logger.debug("Executing option translation for: #{klass.inspect}")
options = klass.send(:translate, options) if klass.respond_to?(:translate)
options
end
translate_type(type, options)
click to toggle source
def translate_type(type, options)
klass = plugin_class(type)
logger.debug("Executing option translation for: #{klass.inspect}")
options = klass.send(:translate, options) if klass.respond_to?(:translate)
options
end
type_default(type)
click to toggle source
def type_default(type)
@types[type.to_sym]
end
types()
click to toggle source
def types
@types.keys
end
value(method, value, options = {})
click to toggle source
def value(method, value, options = {})
config = Config.ensure(options)
logger.debug("Setting extension #{method} value given: #{value.inspect}")
exec(method, config.import({ :value => value, :extension_type => :value })) do |op, data|
if op == :process
value = data unless data.nil?
end
end
logger.debug("Extension #{method} retrieved value: #{value.inspect}")
value
end