[Checkins] SVN: GenericSetup/branches/tseaver-bbq_sprint/ Distinguish base from extension profiles on "Properties" tab:

Tres Seaver tseaver at palladion.com
Fri Mar 16 12:05:50 EDT 2007


Log message for revision 73222:
  Distinguish base from extension profiles on "Properties" tab:
  
  o Hide the "apply" form for sites with an existing base profile ID, with
    an escape hatch.
  
  o Allow importing multiple extensions without replacing the base profile.
  
  Added tests for 'listContextInfos'.
  

Changed:
  U   GenericSetup/branches/tseaver-bbq_sprint/interfaces.py
  U   GenericSetup/branches/tseaver-bbq_sprint/tests/test_tool.py
  U   GenericSetup/branches/tseaver-bbq_sprint/tool.py
  U   GenericSetup/branches/tseaver-bbq_sprint/www/sutProperties.zpt

-=-
Modified: GenericSetup/branches/tseaver-bbq_sprint/interfaces.py
===================================================================
--- GenericSetup/branches/tseaver-bbq_sprint/interfaces.py	2007-03-16 15:42:31 UTC (rev 73221)
+++ GenericSetup/branches/tseaver-bbq_sprint/interfaces.py	2007-03-16 16:05:50 UTC (rev 73222)
@@ -479,10 +479,14 @@
         """ Return the IToolsetRegistry for the tool.
         """
 
-    def runImportStep( step_id, run_dependencies=True, purge_old=None ):
+    def runImportStepFromProfile(profile_id, step_id,
+                                 run_dependencies=True, purge_old=None):
 
-        """ Execute a given setup step
+        """ Execute a given setup step from the given profile.
 
+        o 'profile_id' must be a valid ID of a registered profile;
+           otherwise, raise KeyError.
+
         o 'step_id' is the ID of the step to run.
 
         o If 'purge_old' is True, then run the step after purging any
@@ -500,10 +504,34 @@
             step
         """
 
-    def runAllImportSteps( purge_old=None ):
+    def runImportStep(step_id, run_dependencies=True, purge_old=None):
 
-        """ Run all setup steps in dependency order.
+        """ Execute a given setup step from the baseline profile.
 
+        o 'step_id' is the ID of the step to run.
+
+        o If 'purge_old' is True, then run the step after purging any
+          "old" setup first (this is the responsibility of the step,
+          which must check the context we supply).
+
+        o If 'run_dependencies' is True, then run any out-of-date
+          dependency steps first.
+
+        o Return a mapping, with keys:
+
+          'steps' -- a sequence of IDs of the steps run.
+
+          'messages' -- a dictionary holding messages returned from each
+            step
+        """
+
+    def runAllImportStepsFromProfile(profile_id, purge_old=None):
+
+        """ Run all setup steps for the given profile in dependency order.
+
+        o 'profile_id' must be a valid ID of a registered profile;
+           otherwise, raise KeyError.
+
         o If 'purge_old' is True, then run each step after purging any
           "old" setup first (this is the responsibility of the step,
           which must check the context we supply).
@@ -516,6 +544,22 @@
             step
         """
 
+    def runAllImportSteps(purge_old=None):
+
+        """ Run all setup steps for the baseline profile in dependency order.
+
+        o If 'purge_old' is True, then run each step after purging any
+          "old" setup first (this is the responsibility of the step,
+          which must check the context we supply).
+
+        o Return a mapping, with keys:
+
+          'steps' -- a sequence of IDs of the steps run.
+
+          'messages' -- a dictionary holding messages returned from each
+            step
+        """
+
     def runExportStep( step_id ):
 
         """ Generate a tarball containing artifacts from one export step.

Modified: GenericSetup/branches/tseaver-bbq_sprint/tests/test_tool.py
===================================================================
--- GenericSetup/branches/tseaver-bbq_sprint/tests/test_tool.py	2007-03-16 15:42:31 UTC (rev 73221)
+++ GenericSetup/branches/tseaver-bbq_sprint/tests/test_tool.py	2007-03-16 16:05:50 UTC (rev 73222)
@@ -589,7 +589,55 @@
 
         self.assertEqual( export_registry.getStep( 'one' ), ONE_FUNC )
 
+    def test_listContextInfos_empty(self):
+        site = self._makeSite()
+        site.setup_tool = self._makeOne('setup_tool')
+        tool = site.setup_tool
+        infos = tool.listContextInfos()
+        self.assertEqual(len(infos), 0)
 
+    def test_listContextInfos_with_snapshot(self):
+        site = self._makeSite()
+        site.setup_tool = self._makeOne('setup_tool')
+        tool = site.setup_tool
+        tool.createSnapshot('testing')
+        infos = tool.listContextInfos()
+        self.assertEqual(len(infos), 1)
+        info = infos[0]
+        self.assertEqual(info['id'], 'snapshot-testing')
+        self.assertEqual(info['title'], 'testing')
+        self.assertEqual(info['type'], 'snapshot')
+
+    def test_listContextInfos_with_registered_base_profile(self):
+        from Products.GenericSetup.interfaces import BASE
+        profile_registry.registerProfile('foo', 'Foo', '', self._PROFILE_PATH,
+                                         'Foo', BASE)
+        site = self._makeSite()
+        site.setup_tool = self._makeOne('setup_tool')
+        tool = site.setup_tool
+        infos = tool.listContextInfos()
+        self.assertEqual(len(infos), 1)
+        info = infos[0]
+        self.assertEqual(info['id'], 'profile-Foo:foo')
+        self.assertEqual(info['title'], 'Foo')
+        self.assertEqual(info['type'], 'base')
+
+    def test_listContextInfos_with_registered_extension_profile(self):
+        from Products.GenericSetup.interfaces import EXTENSION
+        profile_registry.registerProfile('foo', 'Foo', '', self._PROFILE_PATH,
+                                         'Foo', EXTENSION)
+        site = self._makeSite()
+        site.setup_tool = self._makeOne('setup_tool')
+        tool = site.setup_tool
+        infos = tool.listContextInfos()
+        self.assertEqual(len(infos), 1)
+        info = infos[0]
+        self.assertEqual(info['id'], 'profile-Foo:foo')
+        self.assertEqual(info['title'], 'Foo')
+        self.assertEqual(info['type'], 'extension')
+
+ 
+
 _DEFAULT_STEP_REGISTRIES_EXPORT_XML = """\
 <?xml version="1.0"?>
 <export-steps>

Modified: GenericSetup/branches/tseaver-bbq_sprint/tool.py
===================================================================
--- GenericSetup/branches/tseaver-bbq_sprint/tool.py	2007-03-16 15:42:31 UTC (rev 73221)
+++ GenericSetup/branches/tseaver-bbq_sprint/tool.py	2007-03-16 16:05:50 UTC (rev 73222)
@@ -28,6 +28,7 @@
 from zope.interface import implements
 from zope.interface import implementedBy
 
+from interfaces import BASE
 from interfaces import EXTENSION
 from interfaces import ISetupTool
 from interfaces import SKIPPED_FILES
@@ -208,12 +209,12 @@
         """
         return self._toolset_registry
 
-    security.declareProtected(ManagePortal, 'runImportStep')
-    def runImportStep(self, step_id, run_dependencies=True, purge_old=None):
-
+    security.declareProtected(ManagePortal, 'runImportStepFromProfile')
+    def runImportStepFromProfile(self, profile_id, step_id,
+                                 run_dependencies=True, purge_old=None):
         """ See ISetupTool.
         """
-        context = self._getImportContext(self._import_context_id, purge_old)
+        context = self._getImportContext(profile_id, purge_old)
 
         info = self._import_registry.getStepMetadata(step_id)
 
@@ -240,17 +241,36 @@
 
         return { 'steps' : steps, 'messages' : messages }
 
-    security.declareProtected(ManagePortal, 'runAllImportSteps')
-    def runAllImportSteps(self, purge_old=None):
+    security.declareProtected(ManagePortal, 'runImportStep')
+    def runImportStep(self, step_id, run_dependencies=True, purge_old=None):
 
         """ See ISetupTool.
         """
-        __traceback_info__ = self._import_context_id
+        return self.runImportStepFromProfile(self._import_context_id,
+                                             step_id,
+                                             run_dependencies,
+                                             purge_old,
+                                            )
 
-        context = self._getImportContext(self._import_context_id, purge_old)
+    security.declareProtected(ManagePortal, 'runAllImportStepsFromProfile')
+    def runAllImportStepsFromProfile(self, profile_id, purge_old=None):
 
+        """ See ISetupTool.
+        """
+        __traceback_info__ = profile_id
+
+        context = self._getImportContext(profile_id, purge_old)
+
         return self._runImportStepsFromContext(context, purge_old=purge_old)
 
+    security.declareProtected(ManagePortal, 'runAllImportSteps')
+    def runAllImportSteps(self, purge_old=None):
+
+        """ See ISetupTool.
+        """
+        return self.runAllImportStepsFromProfile(self._import_context_id,
+                                                 purge_old)
+
     security.declareProtected(ManagePortal, 'runExportStep')
     def runExportStep(self, step_id):
 
@@ -439,6 +459,29 @@
         return self.manage_importSteps(manage_tabs_message=steps_run,
                                        messages=result['messages'])
 
+    security.declareProtected(ManagePortal, 'manage_importExtensions')
+    def manage_importExtensions(self, profile_ids, RESPONSE,
+                                create_report=True):
+
+        """ Import all steps for the selected extension profiles.
+        """
+        if len(profile_ids) == 0:
+            message = 'Please select one or more extension profiles.'
+        else:
+            message = 'Imported profiles: %s' % ', '.join(profile_ids)
+        
+        for profile_id in profile_ids:
+
+            result = self.runAllImportStepsFromProfile(profile_id)
+
+            if create_report:
+                prefix = 'import-all-%s' % profile_id.replace(':', '_')
+                name = self._mangleTimestampName(prefix, 'log')
+                self._createReport(name, result['steps'], result['messages'])
+
+        return self.manage_importSteps(manage_tabs_message=message,
+                                       messages=result['messages'])
+
     security.declareProtected(ManagePortal, 'manage_importTarball')
     def manage_importTarball(self, tarball, RESPONSE, create_report=True):
         """ Import steps from the uploaded tarball.
@@ -544,13 +587,23 @@
 
         """ List registered profiles and snapshots.
         """
+        def readableType(x):
+            if x is BASE:
+                return 'base'
+            elif x is EXTENSION:
+                return 'extension'
+            return 'unknown'
 
-        s_infos = [{ 'id': 'snapshot-%s' % info['id'],
-                      'title': info['title'] }
+        s_infos = [{'id': 'snapshot-%s' % info['id'],
+                     'title': info['title'],
+                     'type': 'snapshot',
+                   }
                     for info in self.listSnapshotInfo()]
-        p_infos = [{ 'id': 'profile-%s' % info['id'],
-                      'title': info['title'] }
-                    for info in self.listProfileInfo()]
+        p_infos = [{'id': 'profile-%s' % info['id'],
+                    'title': info['title'],
+                    'type': readableType(info['type']),
+                   }
+                   for info in self.listProfileInfo()]
 
         return tuple(s_infos + p_infos)
 

Modified: GenericSetup/branches/tseaver-bbq_sprint/www/sutProperties.zpt
===================================================================
--- GenericSetup/branches/tseaver-bbq_sprint/www/sutProperties.zpt	2007-03-16 15:42:31 UTC (rev 73221)
+++ GenericSetup/branches/tseaver-bbq_sprint/www/sutProperties.zpt	2007-03-16 16:05:50 UTC (rev 73222)
@@ -1,37 +1,70 @@
 <h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
 <h2 tal:replace="structure context/manage_tabs">TABS</h2>
 
+<div tal:define="contexts context/listContextInfos;
+                 snaps python: [x for x in contexts if x['type'] == 'snapshot'];
+                 bases python: [x for x in contexts if x['type'] == 'base'];
+                 context_id context/getImportContextID;
+                 context_id_display python: context_id or '(none)';
+                 overwrite_style python: context_id != ''
+                                    and 'display: none' or 'display: block';
+                 exts python: [x for x in contexts if x['type'] == 'extension'];
+                ">
 <h3> Setup Tool Properties </h3>
 
-<form method="post" action="manage_updateToolProperties">
+<form method="post" action=".">
 
-<table>
+ <fieldset id="baseline_fs">
+   <legend>Baseline Profile</legend>
+   
+  <p>Active baseline: <span tal:content="context_id_display">(none)</span></p>
 
- <tr valign="top">
-  <td>
-   <div class="form-label">Active site configuration:</div>
-  </td>
-  <td>
-   <select name="context_id"
-      tal:define="context_id context/getImportContextID">
+  <div tal:condition="python: context_id != ''">
+  <script type="text/javascript" lang="JavaScript">
+  function showOverwrite(e) {
+      var overwrite = document.getElementById('overwrite');
+      overwrite.style.display = 'block';
+  }
+  </script>
+  <p style="color: red"> Changing the baseline profile is potentially a
+     dangerous operation.
+     <a href="#" onclick="showOverwrite(this); return False">Click here</a>
+     if you really need to do this.
+   </p>
+  </div>
+
+  <div id="overwrite"
+       tal:attributes="style overwrite_style">
+   <select name="context_id">
     <option value="context-CONTEXT_ID"
-       tal:repeat="context_info context/listContextInfos"
+       tal:repeat="context_info bases"
        tal:attributes="selected python:context_id == context_info['id'];
                        value context_info/id"
        tal:content="context_info/title"
     >CONTEXT_TITLE</option>
    </select>
-  </td>
- </tr>
+   <input class="form-element" type="submit"
+          name="manage_updateToolProperties:method"
+          value="Update Base Profile" />
+  </div>
+ </fieldset>
 
- <tr valign="top">
-  <td />
-  <td>
-   <input class="form-element" type="submit" value=" Update " />
-  </td>
- </tr>
+ <fieldset id="extesions_fs">
+  <legend>Extension Profiles</legend>
+  <p tal:repeat="extension exts">
+  <tal:x  tal:define="fid string:extension_${extension/id}">
+   <input type="checkbox" id="extension_0" name="profile_ids:list" value="waaa"
+          tal:attributes="id fid;
+                          value extension/id;
+                         "/>
+   <label tal:content="extension/title">TITLE</label>
+   </tal:x>
+  </p>
+  <p><input type="submit" name="manage_importExtensions:method"
+            value="Import Selected Extensions" /></p>
+ </fieldset>
 
-</table>
 </form>
+</div>
 
 <h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>



More information about the Checkins mailing list