changeset 287:2720536b5a22

core: added plugin dependency management
author Goffi <goffi@goffi.org>
date Sun, 06 Feb 2011 22:41:32 +0100
parents 3b382fa0ac28
children 76247af9917c
files src/sat.tac
diffstat 1 files changed, 33 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/sat.tac	Fri Feb 04 01:06:57 2011 +0100
+++ b/src/sat.tac	Sun Feb 06 22:41:32 2011 +0100
@@ -385,23 +385,43 @@
 
     def _import_plugins(self):
         """Import all plugins found in plugins directory"""
-        #TODO: manage dependencies
         import sat.plugins
         plugins_path = os.path.dirname(sat.plugins.__file__) 
         plug_lst = [os.path.splitext(plugin)[0] for plugin in map(os.path.basename,glob (os.path.join(plugins_path,"plugin*.py")))]
-
+        __plugins_to_import = {} #plugins will still have to import
         for plug in plug_lst:
-            plug_path = 'sat.plugins.'+plug
-            __import__(plug_path)
-            mod = sys.modules[plug_path]
-            plug_info = mod.PLUGIN_INFO
-            info (_("importing plugin: %s"), plug_info['name'])
-            self.plugins[plug_info['import_name']] = getattr(mod, plug_info['main'])(self)
-            if plug_info.has_key('handler') and plug_info['handler'] == 'yes':
-                self.plugins[plug_info['import_name']].is_handler = True
-            else:
-                self.plugins[plug_info['import_name']].is_handler = False
-            #TODO: test xmppclient presence and register handler parent
+            plugin_path = 'sat.plugins.'+plug
+            __import__(plugin_path)
+            mod = sys.modules[plugin_path]
+            plugin_info = mod.PLUGIN_INFO
+            __plugins_to_import[plugin_info['import_name']] = (plugin_path, mod, plugin_info)
+        while True:
+            self._import_plugins_from_dict(__plugins_to_import)
+            if not __plugins_to_import:
+                break
+
+    def _import_plugins_from_dict(self, plugins_to_import, import_name=None):
+        """Recursively import and their dependencies in the right order
+        @param plugins_to_import: dict where key=import_name and values= (plugin_path, module, plugin_info)"""
+        if self.plugins.has_key(import_name):
+            debug('Plugin [%s] already imported, passing' % import_name)
+            return
+        if not import_name:
+            import_name,(plugin_path, mod, plugin_info) = plugins_to_import.popitem()
+        else:
+            plugin_path, mod, plugin_info = plugins_to_import.pop(import_name)
+        dependencies = plugin_info.setdefault("dependencies",[])
+        for dependency in dependencies:
+            if not self.plugins.has_key(dependency):
+                debug('Recursively import dependency of [%s]: [%s]' % (import_name, dependency))
+                self._import_plugins_from_dict(plugins_to_import, dependency)
+        info (_("importing plugin: %s"), plugin_info['name'])
+        self.plugins[import_name] = getattr(mod, plugin_info['main'])(self)
+        if plugin_info.has_key('handler') and plugin_info['handler'] == 'yes':
+            self.plugins[import_name].is_handler = True
+        else:
+            self.plugins[import_name].is_handler = False
+        #TODO: test xmppclient presence and register handler parent
 
     def connect(self, profile_key = '@DEFAULT@'):
         """Connect to jabber server"""