plugable: replace API.import_plugins with new API.add_package

Replace API.import_plugins with a new method API.add_package which allows
loading plugin packages into an API object from a package object.

This makes loading of plugin packages loading consistent with loading of
plugin modules and classes.

Rename API.modules to API.packages and use package objects where
implemented to reflect the change.

https://fedorahosted.org/freeipa/ticket/4739

Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
Jan Cholasta
2016-03-16 11:22:00 +01:00
parent 3f5091b55a
commit 0d62968b6f
3 changed files with 33 additions and 34 deletions

View File

@@ -902,12 +902,18 @@ class API(plugable.API):
bases = (Command, Object, Method, Backend, Updater)
@property
def modules(self):
result = ('ipalib.plugins.*',)
def packages(self):
import ipalib.plugins
result = (ipalib.plugins,)
if self.env.in_server:
result += ('ipaserver.plugins.*',)
import ipaserver.plugins
result += (ipaserver.plugins,)
if self.env.context in ('installer', 'updates'):
result += ('ipaserver.install.plugins.*',)
import ipaserver.install.plugins
result += (ipaserver.install.plugins,)
return result

View File

@@ -306,7 +306,7 @@ class API(ReadOnly):
raise NotImplementedError
@property
def modules(self):
def packages(self):
raise NotImplementedError
def __len__(self):
@@ -532,41 +532,30 @@ class API(ReadOnly):
self.__do_if_not_done('bootstrap')
if self.env.mode in ('dummy', 'unit_test'):
return
for module in self.modules:
self.import_plugins(module)
for package in self.packages:
self.add_package(package)
# FIXME: This method has no unit test
def import_plugins(self, module):
def add_package(self, package):
"""
Import plugins from ``module``.
Add plugin modules from the ``package``.
:param module: Name of the module to import. This might be a wildcard
in the form ```package.*``` in which case all modules
from the given package are loaded.
:param package: A package from which to add modules.
"""
if module.endswith('.*'):
subpackage = module[:-2]
try:
plugins = importlib.import_module(subpackage)
except ImportError as e:
self.log.error("cannot import plugins sub-package %s: %s",
subpackage, e)
raise
package, dot, part = subpackage.rpartition('.')
parent = sys.modules[package]
package_name = package.__name__
package_file = package.__file__
package_dir = path.dirname(path.abspath(package_file))
parent_dir = path.dirname(path.abspath(parent.__file__))
plugins_dir = path.dirname(path.abspath(plugins.__file__))
if parent_dir == plugins_dir:
raise errors.PluginsPackageError(
name=subpackage, file=plugins.__file__
)
parent = sys.modules[package_name.rpartition('.')[0]]
parent_dir = path.dirname(path.abspath(parent.__file__))
if parent_dir == package_dir:
raise errors.PluginsPackageError(
name=package_name, file=package_file
)
self.log.debug("importing all plugin modules in %s...", subpackage)
modules = find_modules_in_dir(plugins_dir)
modules = ['.'.join((subpackage, name)) for name in modules]
else:
modules = [module]
self.log.debug("importing all plugin modules in %s...", package_name)
modules = find_modules_in_dir(package_dir)
modules = ['.'.join((package_name, name)) for name in modules]
for name in modules:
self.log.debug("importing plugin module %s", name)

View File

@@ -127,7 +127,11 @@ class Advice(Plugin):
class AdviseAPI(API):
bases = (Advice,)
modules = ('ipaserver.advise.plugins.*',)
@property
def packages(self):
import ipaserver.advise.plugins
return (ipaserver.advise.plugins,)
advise_api = AdviseAPI()