[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"> </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>
-
-
- <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"> </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>
+
+
+ <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