[Checkins] SVN: GenericSetup/branches/wichert-zcml-steps/ More work on this branch. Trains and planes do help productivity

Wichert Akkerman wichert at wiggy.net
Tue Oct 23 05:42:04 EDT 2007


Log message for revision 80956:
  More work on this branch. Trains and planes do help productivity

Changed:
  U   GenericSetup/branches/wichert-zcml-steps/meta.zcml
  U   GenericSetup/branches/wichert-zcml-steps/registry.py
  U   GenericSetup/branches/wichert-zcml-steps/tests/test_zcml.py
  U   GenericSetup/branches/wichert-zcml-steps/tool.py
  U   GenericSetup/branches/wichert-zcml-steps/utils.py
  U   GenericSetup/branches/wichert-zcml-steps/zcml.py

-=-
Modified: GenericSetup/branches/wichert-zcml-steps/meta.zcml
===================================================================
--- GenericSetup/branches/wichert-zcml-steps/meta.zcml	2007-10-22 22:47:05 UTC (rev 80955)
+++ GenericSetup/branches/wichert-zcml-steps/meta.zcml	2007-10-23 09:42:03 UTC (rev 80956)
@@ -10,12 +10,19 @@
         handler=".zcml.registerProfile"
         />
 
-    <meta:directive
+    <meta:complexDirective
         name="importStep"
         schema=".zcml.IImportStepDirective"
         handler=".zcml.importStep"
-        />
+        >
 
+      <meta:subdirective
+          name="depends"
+          schema=".zcml.IImportStepDependsDirective"
+          />
+
+    </meta:complexDirective>
+
     <meta:directive
         name="upgradeStep"
         schema=".zcml.IUpgradeStepDirective"

Modified: GenericSetup/branches/wichert-zcml-steps/registry.py
===================================================================
--- GenericSetup/branches/wichert-zcml-steps/registry.py	2007-10-22 22:47:05 UTC (rev 80955)
+++ GenericSetup/branches/wichert-zcml-steps/registry.py	2007-10-23 09:42:03 UTC (rev 80956)
@@ -36,6 +36,7 @@
 from utils import _getDottedName
 from utils import _resolveDottedName
 from utils import _extractDocstring
+from utils import _computeTopologicalSort
 
 
 class BaseStepRegistry( Implicit ):
@@ -253,45 +254,9 @@
     #
     security.declarePrivate( '_computeTopologicalSort' )
     def _computeTopologicalSort( self ):
+        return _computeTopologicalSort(self._registered.values())
 
-        result = []
 
-        graph = [ ( x[ 'id' ], x[ 'dependencies' ] )
-                    for x in self._registered.values() ]
-
-        unresolved = []
-
-        while 1:
-            for node, edges in graph:
-    
-                after = -1
-                resolved = 0
-    
-                for edge in edges:
-    
-                    if edge in result:
-                        resolved += 1
-                        after = max( after, result.index( edge ) )
-                
-                if len(edges) > resolved:
-                    unresolved.append((node, edges))
-                else:
-                    result.insert( after + 1, node )
-
-            if not unresolved:
-                break
-            if len(unresolved) == len(graph):
-                # Nothing was resolved in this loop. There must be circular or
-                # missing dependencies. Just add them to the end. We can't
-                # raise an error, because checkComplete relies on this method.
-                for node, edges in unresolved:
-                    result.append(node)
-                break
-            graph = unresolved
-            unresolved = []
-        
-        return result
-
     security.declarePrivate( '_exportTemplate' )
     _exportTemplate = PageTemplateFile( 'isrExport.xml', _xmldir )
 

Modified: GenericSetup/branches/wichert-zcml-steps/tests/test_zcml.py
===================================================================
--- GenericSetup/branches/wichert-zcml-steps/tests/test_zcml.py	2007-10-22 22:47:05 UTC (rev 80955)
+++ GenericSetup/branches/wichert-zcml-steps/tests/test_zcml.py	2007-10-23 09:42:03 UTC (rev 80956)
@@ -1,6 +1,6 @@
 ##############################################################################
 #
-# Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2006-2007 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
@@ -20,6 +20,14 @@
 from zope.testing import doctest
 from zope.testing.doctest import ELLIPSIS
 
+from Products.GenericSetup.testing import ExportImportZCMLLayer
+from Products.GenericSetup.zcml import cleanUpImportSteps
+from Products.GenericSetup.registry import _import_step_registry
+from Products.Five import zcml
+
+def dummy_importstep_handler(context):
+    pass
+
 def dummy_upgrade_handler(context):
     pass
 
@@ -230,10 +238,65 @@
       >>> cleanUp()
     """
 
+
+class ImportStepTests(unittest.TestCase):
+    layer = ExportImportZCMLLayer
+
+    def tearDown(self):
+        cleanUpImportSteps()
+
+    def testNoDependencies(self):
+        zcml.load_string("""<configure
+                              xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
+                              i18n_domain="genericsetup">
+                             <genericsetup:importStep
+                                 name="name"
+                                 title="title"
+                                 description="description"
+                                 handler="Products.GenericSetup.tests.test_zcml.dummy_importstep_handler"
+                                 version="version">
+                              </genericsetup:importStep>
+                              </configure>
+                              """)
+        from Products.GenericSetup.zcml import _import_step_regs
+        self.assertEqual(_import_step_regs, [u'name'])
+        self.assertEqual( _import_step_registry.listSteps(), [u'name'])
+        data=_import_step_registry.getStepMetadata(u'name')
+        self.assertEqual(data["handler"],
+                'Products.GenericSetup.tests.test_zcml.dummy_importstep_handler')
+        self.assertEqual(data["description"], u"description")
+        self.assertEqual(data["version"], u"version")
+        self.assertEqual(data["title"], u"title")
+        self.assertEqual(data["dependencies"], ())
+        self.assertEqual(data["id"], u"name")
+
+
+    def testWithDependency(self):
+        zcml.load_string("""<configure
+                              xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
+                              i18n_domain="genericsetup">
+                             <genericsetup:importStep
+                                 name="name"
+                                 title="title"
+                                 description="description"
+                                 handler="Products.GenericSetup.tests.test_zcml.dummy_importstep_handler"
+                                 version="version">
+                                <depends name="something.else"/>
+                              </genericsetup:importStep>
+                              </configure>
+                              """)
+        data=_import_step_registry.getStepMetadata(u'name')
+        self.assertEqual(data["dependencies"], (u"something.else",))
+
+
+
 def test_suite():
-    return unittest.TestSuite((
-        doctest.DocTestSuite(optionflags=ELLIPSIS),
-        ))
+    suite = unittest.TestSuite()
+    suite.addTest(doctest.DocTestSuite(optionflags=ELLIPSIS))
+    suite.addTest(unittest.makeSuite(ImportStepTests))
+    return suite
 
+    return suite
+
 if __name__ == '__main__':
     unittest.main(defaultTest='test_suite')

Modified: GenericSetup/branches/wichert-zcml-steps/tool.py
===================================================================
--- GenericSetup/branches/wichert-zcml-steps/tool.py	2007-10-22 22:47:05 UTC (rev 80955)
+++ GenericSetup/branches/wichert-zcml-steps/tool.py	2007-10-23 09:42:03 UTC (rev 80956)
@@ -45,6 +45,7 @@
 from registry import ExportStepRegistry
 from registry import ToolsetRegistry
 from registry import _profile_registry
+from registry import _import_step_registry
 
 from upgrade import listUpgradeSteps
 from upgrade import listProfilesWithUpgrades
@@ -53,6 +54,7 @@
 from utils import _getDottedName
 from utils import _resolveDottedName
 from utils import _wwwdir
+from utils import _computeTopologicalSort
 
 IMPORT_STEPS_XML = 'import_steps.xml'
 EXPORT_STEPS_XML = 'export_steps.xml'
@@ -247,6 +249,31 @@
         """
         return self._export_registry
 
+
+    security.declareProtected(ManagePortal, 'getImportStep')
+    def getImportStep(self, step, default=None):
+        """Simple wrapper to query both the global and local step registry."""
+        res=_import_step_registry.getStep(step, default)
+        if res is not default:
+            return res
+        return self._import_registry.getStep(step, default)
+
+
+    security.declareProtected(ManagePortal, 'getSortedImportSteps')
+    def getSortedImportSteps(self):
+        steps = _import_step_registry._registered.values() + \
+                self._import_registry._registered.values()
+        return _computeTopologicalSort(steps)
+    
+    security.declareProtected(ManagePortal, 'getImportStep')
+    def getImportStepMetadata(self, step, default=None):
+        """Simple wrapper to query both the global and local step registry."""
+        res=_import_step_registry.getStepMetadata(step, default)
+        if res is not default:
+            return res
+        return self._import_registry.getStepMetadata(step, default)
+
+
     security.declareProtected(ManagePortal, 'getToolsetRegistry')
     def getToolsetRegistry(self):
 
@@ -264,7 +291,7 @@
 
         self.applyContext(context)
 
-        info = self._import_registry.getStepMetadata(step_id)
+        info = self.getImportStepMetadata(step_id)
 
         if info is None:
             self._import_context_id = old_context
@@ -968,7 +995,7 @@
         __traceback_info__ = step_id
         marker = object()
 
-        handler = self._import_registry.getStep(step_id)
+        handler = self.getImportStep(step_id)
 
         if handler is marker:
             raise ValueError('Invalid import step: %s' % step_id)
@@ -1016,7 +1043,7 @@
         self.applyContext(context)
 
         if steps is None:
-            steps = self._import_registry.sortSteps()
+            steps = self.getSortedImportSteps()
         messages = {}
 
         for step in steps:

Modified: GenericSetup/branches/wichert-zcml-steps/utils.py
===================================================================
--- GenericSetup/branches/wichert-zcml-steps/utils.py	2007-10-22 22:47:05 UTC (rev 80955)
+++ GenericSetup/branches/wichert-zcml-steps/utils.py	2007-10-23 09:42:03 UTC (rev 80956)
@@ -788,3 +788,41 @@
     if getattr(obj, 'objectValues', False):
         for sub in obj.objectValues():
             importObjects(sub, path+'/', context)
+
+
+def _computeTopologicalSort( steps ):
+    result = []
+    graph = [ ( x[ 'id' ], x[ 'dependencies' ] ) for x in steps ]
+
+    unresolved = []
+
+    while 1:
+        for node, edges in graph:
+
+            after = -1
+            resolved = 0
+
+            for edge in edges:
+
+                if edge in result:
+                    resolved += 1
+                    after = max( after, result.index( edge ) )
+            
+            if len(edges) > resolved:
+                unresolved.append((node, edges))
+            else:
+                result.insert( after + 1, node )
+
+        if not unresolved:
+            break
+        if len(unresolved) == len(graph):
+            # Nothing was resolved in this loop. There must be circular or
+            # missing dependencies. Just add them to the end. We can't
+            # raise an error, because checkComplete relies on this method.
+            for node, edges in unresolved:
+                result.append(node)
+            break
+        graph = unresolved
+        unresolved = []
+    
+    return result

Modified: GenericSetup/branches/wichert-zcml-steps/zcml.py
===================================================================
--- GenericSetup/branches/wichert-zcml-steps/zcml.py	2007-10-22 22:47:05 UTC (rev 80955)
+++ GenericSetup/branches/wichert-zcml-steps/zcml.py	2007-10-23 09:42:03 UTC (rev 80956)
@@ -1,6 +1,6 @@
 
 #
-# Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
+# Copyright (c) 2006-2007 Zope Corporation and Contributors. All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
@@ -117,21 +117,43 @@
         description=u'',
         required=True)
 
+class IImportStepDependsDirective(Interface):
+    name = PythonIdentifier(
+        title=u'Name',
+        description=u'Name of another import step that has to be run first',
+        required=True)
+
 _import_step_regs = []
 
-def importStep(_context, name, version, title, description, handler):
-    """ Add a new import step to the registry.
-    """
-    global _import_step_regs
-    _import_step_regs.append(name)
+class importStep:
+    def __init__(self, context, name, version, title, description, handler):
+        """ Add a new import step to the registry.
+        """
+        self.context=context
+        self.discriminator = ('importStep', name),
+        self.name=name
+        self.version=version
+        self.handler=handler
+        self.title=title
+        self.description=description
+        self.dependencies=()
 
-    _context.action(
-        discriminator = ('importStep', name),
-        callable = _import_step_registry.registerStep,
-        args = (name, version, handler, (), title, description)
-        )
 
+    def depends(self, context, name):
+        self.dependencies+=(name,)
 
+
+    def __call__(self):
+        global _import_step_regs
+        _import_step_regs.append(self.name)
+
+        self.context.action(
+            discriminator = self.discriminator,
+            callable = _import_step_registry.registerStep,
+            args = (self.name, self.version, self.handler, self.dependencies,
+                        self.title, self.description),
+            )
+
 #### genericsetup:upgradeStep
 
 import zope.schema
@@ -243,6 +265,8 @@
         except KeyError:
             pass
 
+    _import_step_regs=[]
+
 from zope.testing.cleanup import addCleanUp
 addCleanUp(cleanUpProfiles)
 addCleanUp(cleanUpImportSteps)



More information about the Checkins mailing list