# 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 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