103 lines
3.3 KiB
Python
103 lines
3.3 KiB
Python
# koji plugin module
|
|
# Copyright (c) 2008 Red Hat
|
|
#
|
|
# Koji is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation;
|
|
# version 2.1 of the License.
|
|
#
|
|
# This software is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this software; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
#
|
|
# Authors:
|
|
# Mike McLean <mikem@redhat.com>
|
|
|
|
import imp
|
|
import koji
|
|
import sys
|
|
|
|
|
|
class PluginTracker(object):
|
|
|
|
def __init__(self, path=None, prefix='_koji_plugin__'):
|
|
self.searchpath = path
|
|
#prefix should not have a '.' in it, this can cause problems.
|
|
self.prefix = prefix
|
|
self.plugins = {}
|
|
|
|
def load(self, name, path=None, reload=False):
|
|
if self.plugins.has_key(name) and not reload:
|
|
return self.plugins[name]
|
|
mod_name = name
|
|
if self.prefix:
|
|
#mod_name determines how the module is named in sys.modules
|
|
#Using a prefix helps prevent overlap with other modules
|
|
#(no '.' -- it causes problems)
|
|
mod_name = self.prefix + name
|
|
if sys.modules.has_key(mod_name) and not reload:
|
|
raise koji.GenericError, 'module name conflict: %s' % mod_name
|
|
if path is None:
|
|
path = self.searchpath
|
|
if path is None:
|
|
raise koji.GenericError, "empty module search path"
|
|
file, pathname, description = imp.find_module(name, self.pathlist(path))
|
|
try:
|
|
plugin = imp.load_module(mod_name, file, pathname, description)
|
|
finally:
|
|
file.close()
|
|
self.plugins[name] = plugin
|
|
return plugin
|
|
|
|
def get(self, name):
|
|
return self.plugins.get(name)
|
|
|
|
def pathlist(self, path):
|
|
if isinstance(path, basestring):
|
|
return [path]
|
|
else:
|
|
return path
|
|
|
|
|
|
# some decorators used by plugins
|
|
def export(f):
|
|
"""a decorator that marks a function as exported
|
|
|
|
intended to be used by plugins
|
|
the HandlerRegistry will export the function under its own name
|
|
"""
|
|
setattr(f, 'exported', True)
|
|
return f
|
|
|
|
def export_as(alias):
|
|
"""returns a decorator that marks a function as exported and gives it an alias
|
|
|
|
indended to be used by plugins
|
|
"""
|
|
def dec(f):
|
|
setattr(f, 'exported', True)
|
|
setattr(f, 'export_alias', alias)
|
|
return f
|
|
return dec
|
|
|
|
def export_in(module, alias=None):
|
|
"""returns a decorator that marks a function as exported with a module prepended
|
|
|
|
optionally, can also alias the function within the module
|
|
indended to be used by plugins
|
|
"""
|
|
def dec(f):
|
|
if alias is None:
|
|
alias = "%s.%s" % (module, f.__name__)
|
|
else:
|
|
alias = "%s.%s" % (module, alias)
|
|
setattr(f, 'exported', True)
|
|
setattr(f, 'export_module', module)
|
|
setattr(f, 'export_alias', alias)
|
|
return f
|
|
return dec
|