[Checkins] SVN: Products.GenericSetup/branches/wichert-sane-contextid/ Cut a branch for this change. This fixes problems where the very common scenario of wrapping a runAllImportSteps call in getImportContextID/setImportContext calls will destroy the base profile.

Wichert Akkerman wichert at wiggy.net
Mon Nov 19 11:12:00 EST 2007


Log message for revision 81933:
  Cut a branch for this change. This fixes problems where the very common scenario of wrapping a runAllImportSteps call in getImportContextID/setImportContext calls will destroy the base profile.
  

Changed:
  A   Products.GenericSetup/branches/wichert-sane-contextid/
  U   Products.GenericSetup/branches/wichert-sane-contextid/CHANGES.txt
  U   Products.GenericSetup/branches/wichert-sane-contextid/tests/test_tool.py
  U   Products.GenericSetup/branches/wichert-sane-contextid/tool.py
  D   Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt
  A   Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt

-=-
Copied: Products.GenericSetup/branches/wichert-sane-contextid (from rev 81908, Products.GenericSetup/trunk/Products/GenericSetup)

Modified: Products.GenericSetup/branches/wichert-sane-contextid/CHANGES.txt
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/CHANGES.txt	2007-11-18 03:07:27 UTC (rev 81908)
+++ Products.GenericSetup/branches/wichert-sane-contextid/CHANGES.txt	2007-11-19 16:11:59 UTC (rev 81933)
@@ -2,6 +2,8 @@
 
   GenericSetup 1.4 (unreleased)
   
+    - Be more careful in checking context id validity.
+
     - Fire events before and after importing.
 
     - Use zcml to register import and export steps.

Modified: Products.GenericSetup/branches/wichert-sane-contextid/tests/test_tool.py
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/tests/test_tool.py	2007-11-18 03:07:27 UTC (rev 81908)
+++ Products.GenericSetup/branches/wichert-sane-contextid/tests/test_tool.py	2007-11-19 16:11:59 UTC (rev 81933)
@@ -141,6 +141,15 @@
                          , 'profile-foo'
                          )
 
+    def test_setBaselineContext_empty_string( self ):
+
+        tool = self._makeOne('setup_tool')
+
+        self.assertRaises( KeyError
+                         , tool.setBaselineContext
+                         , ''
+                         )
+
     def test_setBaselineContext( self ):
 
         from Products.GenericSetup.tool import IMPORT_STEPS_XML
@@ -194,7 +203,7 @@
 
         tool = self._makeOne('setup_tool').__of__( site )
 
-        self.assertRaises( ValueError, tool.runImportStepFromProfile,
+        self.assertRaises( KeyError, tool.runImportStepFromProfile,
                            '', 'nonesuch' )
 
     def test_runImportStep_simple( self ):
@@ -207,7 +216,7 @@
         registry = tool.getImportStepRegistry()
         registry.registerStep( 'simple', '1', _uppercaseSiteTitle )
 
-        result = tool.runImportStepFromProfile( '', 'simple' )
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'simple' )
 
         self.assertEqual( len( result[ 'steps' ] ), 1 )
 
@@ -219,13 +228,13 @@
 
         global _before_import_events
         self.assertEqual( len(_before_import_events), 1)
-        self.assertEqual(_before_import_events[0].profile_id, '')
+        self.assertEqual(_before_import_events[0].profile_id, 'snapshot-dummy')
         self.assertEqual(_before_import_events[0].steps, ['simple'])
         self.assertEqual(_before_import_events[0].full_import, True)
 
         global _after_import_events
         self.assertEqual( len(_after_import_events), 1)
-        self.assertEqual(_after_import_events[0].profile_id, '')
+        self.assertEqual(_after_import_events[0].profile_id, 'snapshot-dummy')
         self.assertEqual(_after_import_events[0].steps, ['simple'])
         self.assertEqual(_after_import_events[0].full_import, True)
 
@@ -241,7 +250,7 @@
         registry.registerStep( 'dependent', '1'
                              , _uppercaseSiteTitle, ( 'dependable', ) )
 
-        result = tool.runImportStepFromProfile( '', 'dependent' )
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'dependent' )
 
         self.assertEqual( len( result[ 'steps' ] ), 2 )
 
@@ -256,13 +265,13 @@
 
         global _before_import_events
         self.assertEqual( len(_before_import_events), 1)
-        self.assertEqual(_before_import_events[0].profile_id, '')
+        self.assertEqual(_before_import_events[0].profile_id, 'snapshot-dummy')
         self.assertEqual(_before_import_events[0].steps, ['dependable', 'dependent'])
         self.assertEqual(_before_import_events[0].full_import, True)
 
         global _after_import_events
         self.assertEqual( len(_after_import_events), 1)
-        self.assertEqual(_after_import_events[0].profile_id, '')
+        self.assertEqual(_after_import_events[0].profile_id, 'snapshot-dummy')
         self.assertEqual(_after_import_events[0].steps, ['dependable', 'dependent'])
         self.assertEqual(_after_import_events[0].full_import, True)
 
@@ -279,7 +288,7 @@
         registry.registerStep( 'dependent', '1'
                              , _uppercaseSiteTitle, ( 'dependable', ) )
 
-        result = tool.runImportStepFromProfile( '', 'dependent',
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'dependent',
                                                 run_dependencies=False )
 
         self.assertEqual( len( result[ 'steps' ] ), 1 )
@@ -292,13 +301,13 @@
 
         global _before_import_events
         self.assertEqual( len(_before_import_events), 1)
-        self.assertEqual(_before_import_events[0].profile_id, '')
+        self.assertEqual(_before_import_events[0].profile_id, 'snapshot-dummy')
         self.assertEqual(_before_import_events[0].steps, ['dependent'])
         self.assertEqual(_before_import_events[0].full_import, False)
 
         global _after_import_events
         self.assertEqual( len(_after_import_events), 1)
-        self.assertEqual(_after_import_events[0].profile_id, '')
+        self.assertEqual(_after_import_events[0].profile_id, 'snapshot-dummy')
         self.assertEqual(_after_import_events[0].steps, ['dependent'])
         self.assertEqual(_after_import_events[0].full_import, False)
 
@@ -310,7 +319,7 @@
         registry = tool.getImportStepRegistry()
         registry.registerStep( 'purging', '1', _purgeIfRequired )
 
-        result = tool.runImportStepFromProfile( '', 'purging' )
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'purging' )
 
         self.assertEqual( len( result[ 'steps' ] ), 1 )
         self.assertEqual( result[ 'steps' ][ 0 ], 'purging' )
@@ -325,7 +334,7 @@
         registry = tool.getImportStepRegistry()
         registry.registerStep( 'purging', '1', _purgeIfRequired )
 
-        result = tool.runImportStepFromProfile( '', 'purging',
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'purging',
                                                 purge_old=True )
 
         self.assertEqual( len( result[ 'steps' ] ), 1 )
@@ -341,7 +350,7 @@
         registry = tool.getImportStepRegistry()
         registry.registerStep( 'purging', '1', _purgeIfRequired )
 
-        result = tool.runImportStepFromProfile( '', 'purging',
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'purging',
                                                 purge_old=False )
 
         self.assertEqual( len( result[ 'steps' ] ), 1 )
@@ -360,7 +369,7 @@
         registry.registerStep( 'dependent', '1'
                              , _uppercaseSiteTitle, ( 'purging', ) )
 
-        result = tool.runImportStepFromProfile( '', 'dependent',
+        result = tool.runImportStepFromProfile( 'snapshot-dummy', 'dependent',
                                                 purge_old=False )
         self.failIf( site.purged )
 
@@ -369,14 +378,14 @@
         site = self._makeSite()
         tool = self._makeOne('setup_tool').__of__( site )
 
-        result = tool.runAllImportStepsFromProfile('')
+        result = tool.runAllImportStepsFromProfile('snapshot-dummy')
 
         self.assertEqual( len( result[ 'steps' ] ), 0 )
 
     def test_runAllImportSteps_sorted_default_purge( self ):
 
         TITLE = 'original title'
-        PROFILE_ID = 'testing'
+        PROFILE_ID = 'snapshot-testing'
         site = self._makeSite( TITLE )
         tool = self._makeOne('setup_tool').__of__( site )
 
@@ -414,7 +423,7 @@
     def test_runAllImportSteps_unicode_profile_id_creates_reports( self ):
 
         TITLE = 'original title'
-        PROFILE_ID = u'testing'
+        PROFILE_ID = u'snapshot-testing'
         site = self._makeSite( TITLE )
         tool = self._makeOne('setup_tool').__of__( site )
 
@@ -445,7 +454,7 @@
         registry.registerStep( 'purging', '1'
                              , _purgeIfRequired )
 
-        result = tool.runAllImportStepsFromProfile( '', purge_old=True )
+        result = tool.runAllImportStepsFromProfile( 'snapshot-dummy', purge_old=True )
 
         self.assertEqual( len( result[ 'steps' ] ), 3 )
 
@@ -470,7 +479,7 @@
         registry.registerStep( 'purging', '1'
                              , _purgeIfRequired )
 
-        result = tool.runAllImportStepsFromProfile( '', purge_old=False )
+        result = tool.runAllImportStepsFromProfile( 'snapshot-dummy', purge_old=False )
 
         self.assertEqual( len( result[ 'steps' ] ), 3 )
 

Modified: Products.GenericSetup/branches/wichert-sane-contextid/tool.py
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/tool.py	2007-11-18 03:07:27 UTC (rev 81908)
+++ Products.GenericSetup/branches/wichert-sane-contextid/tool.py	2007-11-19 16:11:59 UTC (rev 81933)
@@ -954,11 +954,13 @@
                 should_purge = (info.get('type') != EXTENSION)
             return DirectoryImportContext(self, path, should_purge, encoding)
 
-        # else snapshot
-        context_id = context_id[len('snapshot-'):]
-        if should_purge is None:
-            should_purge = True
-        return SnapshotImportContext(self, context_id, should_purge, encoding)
+        elif context_id.startswith('snapshot-'):
+            context_id = context_id[len('snapshot-'):]
+            if should_purge is None:
+                should_purge = True
+            return SnapshotImportContext(self, context_id, should_purge, encoding)
+        else:
+            raise KeyError, 'Unknown context %s' % context_id
 
     security.declarePrivate('_updateImportStepsRegistry')
     def _updateImportStepsRegistry(self, context, encoding):

Deleted: Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt
===================================================================
--- Products.GenericSetup/trunk/Products/GenericSetup/www/sutImportSteps.zpt	2007-11-18 03:07:27 UTC (rev 81908)
+++ Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt	2007-11-19 16:11:59 UTC (rev 81933)
@@ -1,134 +0,0 @@
-<tal:block define="base_context_id context/getBaselineContextID;
-                   context_id request/context_id|base_context_id;
-                   contexts context/listContextInfos;
-                   context_title python:[c['title'] for c in contexts if c['id']==context_id][0];
-                   extension_contexts python:[c for c in contexts if c['type'] in ['extension','snapshot']];
-                   ">
-<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
-<h2 tal:define="manage_tabs_message options/manage_tabs_message | nothing"
-    tal:replace="structure context/manage_tabs">TABS</h2>
-
-<h2> Site Configuration Import Steps </h2>
-
-<p class="form-help">
-This tool allows one to re-run individual steps of the site setup
-procedure, in order to pick up changes since the site was created.
-</p>
-
-<h3>Select Profile or Snapshot</h3>
-
-<form action="." method="POST" id="profileform" tal:attributes="action string:${context/absolute_url}/manage_importSteps">
-<select name="context_id"
-        onchange="document.getElementById('profileform').submit();">
- <option value=""
-         tal:attributes="value base_context_id;
-                         selected python:context_id==base_context_id">
-   Current base profile</option>
- <option value="context-CONTEXT_ID"
-    tal:repeat="context extension_contexts"
-    tal:attributes="value context/id; selected python:context_id==context['id']"
-    tal:content="context/title">CONTEXT_TITLE</option>
-</select>
-  <noscript>
-    <input class="form-element" type="submit"
-           name="manage_importSteps:method"
-           value="Switch profile" />
-  </noscript>
-</form>
-
-
-<h3>Available Import Steps for "<span tal:replace="context_title">Base profile</span>"</h3>
-
-<form action="." method="POST" enctype="multipart/form-data"
-      tal:attributes="action context/absolute_url" >
-<tal:dummy define="dummy python:context.applyContextById(context_id)"/>
-<input type="hidden" name="ids:default:tokens" value="" />
-
-<table cellspacing="0" cellpadding="4">
-
- <thead>
-  <tr class="list-header">
-   <td class="list-item">Sel.</td>
-   <td class="list-item">#</td>
-   <td class="list-item">Title / Description</td>
-   <td class="list-item">Handler</td>
-  </tr>
- </thead>
-
- <tbody tal:define="step_ids context/getSortedImportSteps;
-                   ">
-  <tal:loop tal:repeat="step_id step_ids">
-  <tr valign="top"
-      tal:define="info python: context.getImportStepMetadata( step_id );"
-      tal:attributes="class python:
-                     repeat[ 'step_id' ].odd and 'row-normal' or 'row-hilite';
-                     style python:info['invalid'] and 'background: red' or None" >
-   <td class="list-item" width="16">
-    <input type="checkbox" name="ids:list" value="STEP_ID"
-           tal:attributes="value step_id" />
-   </td>
-   <td align="right" class="list-item"
-       tal:content="repeat/step_id/number">1</td>
-   <td class="list-item">
-    <span tal:content="info/title">STEP TITLE</span><br />
-    <em tal:content="info/description">STEP DESCRIPTION</em>
-   </td>
-   <td class="list-item"
-       tal:content="info/handler">DOTTED.NAME</td>
-  </tr>
-  </tal:loop>
-
-  <tr valign="top" class="list-header">
-   <td colspan="4">&nbsp;</td>
-  </tr>
-
-  <tr valign="top">
-   <td />
-   <td colspan="3">
-
-    <input type="hidden" name="context_id" value="" tal:attributes="value context_id"/>
-    <input type="hidden" name="run_dependencies:int:default" value="0" />
-    <input class="form-element" type="checkbox" id="run_dependencies"
-           name="run_dependencies:boolean" value="1" checked="checked" />
-    <label for="run_dependencies">Include dependencies?</label>
-    &nbsp; &nbsp;
-
-    <input class="form-element" type="submit"
-           name="manage_importSelectedSteps:method"
-           value=" Import selected steps " />
-      
-    <input class="form-element" type="submit"
-           name="manage_importAllSteps:method"
-           value=" Import all steps " />
-      
-    <input class="form-element" type="file"
-           name="tarball" />
-    <input class="form-element" type="submit"
-           name="manage_importTarball:method"
-           value=" Import uploaded tarball " />
-   </td>
-  </tr>
- </tbody>
-</table>
-
-<table cellspacing="0" cellpadding="4"
-       tal:condition="options/messages | nothing">
-
-  <tr class="list-header">
-   <td colspan="4">Message Log</td>
-  </tr>
-
-  <tr valign="top"
-      tal:repeat="item options/messages/items">
-   <td tal:content="python: item[0]">STEP</td>
-   <td colspan="3"
-       tal:content="structure python: item[1].replace('\n', '<br />')"
-       >MESSAGE</td>
-  </tr>
-
-</table>
-</form>
-
-<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>
-</tal:block>
-

Copied: Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt (from rev 81931, Products.GenericSetup/trunk/Products/GenericSetup/www/sutImportSteps.zpt)
===================================================================
--- Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt	                        (rev 0)
+++ Products.GenericSetup/branches/wichert-sane-contextid/www/sutImportSteps.zpt	2007-11-19 16:11:59 UTC (rev 81933)
@@ -0,0 +1,135 @@
+<tal:block define="base_context_id context/getBaselineContextID;
+                   context_id request/context_id|base_context_id;
+                   contexts context/listContextInfos;
+                   context_title python:[c['title'] for c in contexts if c['id']==context_id];
+                   context_title python:context_title and context_title[0] or 'UNKNOWN';
+                   extension_contexts python:[c for c in contexts if c['type'] in ['extension','snapshot']];
+                   ">
+<h1 tal:replace="structure context/manage_page_header">PAGE HEADER</h1>
+<h2 tal:define="manage_tabs_message options/manage_tabs_message | nothing"
+    tal:replace="structure context/manage_tabs">TABS</h2>
+
+<h2> Site Configuration Import Steps </h2>
+
+<p class="form-help">
+This tool allows one to re-run individual steps of the site setup
+procedure, in order to pick up changes since the site was created.
+</p>
+
+<h3>Select Profile or Snapshot</h3>
+
+<form action="." method="POST" id="profileform" tal:attributes="action string:${context/absolute_url}/manage_importSteps">
+<select name="context_id"
+        onchange="document.getElementById('profileform').submit();">
+ <option value=""
+         tal:attributes="value base_context_id;
+                         selected python:context_id==base_context_id">
+   Current base profile</option>
+ <option value="context-CONTEXT_ID"
+    tal:repeat="context extension_contexts"
+    tal:attributes="value context/id; selected python:context_id==context['id']"
+    tal:content="context/title">CONTEXT_TITLE</option>
+</select>
+  <noscript>
+    <input class="form-element" type="submit"
+           name="manage_importSteps:method"
+           value="Switch profile" />
+  </noscript>
+</form>
+
+
+<h3>Available Import Steps for "<span tal:replace="context_title">Base profile</span>"</h3>
+
+<form action="." method="POST" enctype="multipart/form-data"
+      tal:attributes="action context/absolute_url" >
+<tal:dummy define="dummy python:context.applyContextById(context_id)"/>
+<input type="hidden" name="ids:default:tokens" value="" />
+
+<table cellspacing="0" cellpadding="4">
+
+ <thead>
+  <tr class="list-header">
+   <td class="list-item">Sel.</td>
+   <td class="list-item">#</td>
+   <td class="list-item">Title / Description</td>
+   <td class="list-item">Handler</td>
+  </tr>
+ </thead>
+
+ <tbody tal:define="step_ids context/getSortedImportSteps;
+                   ">
+  <tal:loop tal:repeat="step_id step_ids">
+  <tr valign="top"
+      tal:define="info python: context.getImportStepMetadata( step_id );"
+      tal:attributes="class python:
+                     repeat[ 'step_id' ].odd and 'row-normal' or 'row-hilite';
+                     style python:info['invalid'] and 'background: red' or None" >
+   <td class="list-item" width="16">
+    <input type="checkbox" name="ids:list" value="STEP_ID"
+           tal:attributes="value step_id" />
+   </td>
+   <td align="right" class="list-item"
+       tal:content="repeat/step_id/number">1</td>
+   <td class="list-item">
+    <span tal:content="info/title">STEP TITLE</span><br />
+    <em tal:content="info/description">STEP DESCRIPTION</em>
+   </td>
+   <td class="list-item"
+       tal:content="info/handler">DOTTED.NAME</td>
+  </tr>
+  </tal:loop>
+
+  <tr valign="top" class="list-header">
+   <td colspan="4">&nbsp;</td>
+  </tr>
+
+  <tr valign="top">
+   <td />
+   <td colspan="3">
+
+    <input type="hidden" name="context_id" value="" tal:attributes="value context_id"/>
+    <input type="hidden" name="run_dependencies:int:default" value="0" />
+    <input class="form-element" type="checkbox" id="run_dependencies"
+           name="run_dependencies:boolean" value="1" checked="checked" />
+    <label for="run_dependencies">Include dependencies?</label>
+    &nbsp; &nbsp;
+
+    <input class="form-element" type="submit"
+           name="manage_importSelectedSteps:method"
+           value=" Import selected steps " />
+      
+    <input class="form-element" type="submit"
+           name="manage_importAllSteps:method"
+           value=" Import all steps " />
+      
+    <input class="form-element" type="file"
+           name="tarball" />
+    <input class="form-element" type="submit"
+           name="manage_importTarball:method"
+           value=" Import uploaded tarball " />
+   </td>
+  </tr>
+ </tbody>
+</table>
+
+<table cellspacing="0" cellpadding="4"
+       tal:condition="options/messages | nothing">
+
+  <tr class="list-header">
+   <td colspan="4">Message Log</td>
+  </tr>
+
+  <tr valign="top"
+      tal:repeat="item options/messages/items">
+   <td tal:content="python: item[0]">STEP</td>
+   <td colspan="3"
+       tal:content="structure python: item[1].replace('\n', '<br />')"
+       >MESSAGE</td>
+  </tr>
+
+</table>
+</form>
+
+<h1 tal:replace="structure context/manage_page_footer">PAGE FOOTER</h1>
+</tal:block>
+



More information about the Checkins mailing list