[Plone-IT] CMFCore import content and .preserve

Riccardo Lemmi riccardo a reflab.it
Gio 15 Maggio 2008 11:14:35 UTC


On Wednesday 14 May 2008, you wrote:
> Questo e' quello che dice la docsting del metodo:
>
> Subobjects themselves are represented as individual files or
>     subdirectories within the parent's directory.
>     If the import step finds that any objects specified to be created by
> the 'structure' directory setup already exist, these objects will be
> deleted and then recreated by the profile.  The existence of a '.preserve'
> file within the 'structure' hierarchy allows specification of objects that
> should not be deleted.  '.preserve' files should contain one preserve rule
> per line, with shell-style globbing supported (i.e. 'b*' will match all
> objects w/ id starting w/ 'b'.
>
> Uno che capisce da qua?

A  me pare chiaro:

If the import step finds that any objects specified to be created by
the 'structure' directory setup already exist, these objects will be
deleted and then recreated by the profile.  

-> gli oggetti presenti nello ZODB e su file system vengono cancellati e 
ricreati

The existence of a '.preserve'  file within the 'structure' hierarchy allows 
specification of objects that should not be deleted.

-> .preserve permette di non far cancellare gli oggetti presenti nello ZODB

> Poi io mi chiedo: perchemmai un GS (che per definizione e' additivo)
> dovrebbe cancellare degli oggetti dallo ZODB (in fase di install) se
> nessuno glie lo dice? 

Chi ha sviluppato il codice pensava fosse lo use case migliore per questa 
situazione specifica.

> Tu forse intendi il .delete... ma a questo punto uno 
> dovrebbe specificare una lista di oggetti da cancellare nel .delete ed una
> lista di oggetti da preservare DA questo .delete in .preserve... tantovale
> non inserire tali oggetti nel .delete... non so, a me sembra ridondante.

.delete serve per cancellare gli oggetti che esistono solo nello ZODB

> In piu', se io installo il mio prodotto che crea contenuti di default,
> questi contenuti vengono aggiornati, le directory riempite di altri
> contenuti ecc ecc... poi rilascio una nuova release del mio prodotto... ho
> che tutta la contenutistica creata in esercizio va a farsi benedire. Il
> fatto che non ci sia un modo per prevenire cio' mi lascia un po' cosi...
>
> Poi ho provato ad indentare quelle due righe e tutto sembra funzionare
> correttamente: su un plone vergine i contenuti vengono generati; su un
> plone gia' istanziati i contenuti in .preserve vengono preservati.

sembra... hai provato a far girare i test con quella modifica?
./bin/zopectl test -m Products.CMFCore.exportimport.tests.test_content

Failure in test test_import_site_with_subfolders_and_preserve 
(Products.CMFCore.exportimport.tests.test_content.SiteStructureExporterTests)
Traceback (most recent call last):
  File "unittest.py", line 260, in run
    testMethod()
  
File "/tmp/kde-axa/Zope-2.9.8-final/Instance/Products/CMFCore/exportimport/tests/test_content.py", 
line 593, in test_import_site_with_subfolders_and_preserve
    self.assertEqual(len(site.foo.objectIds()), 2, site.foo.objectIds())
  File "unittest.py", line 333, in failUnlessEqual
    raise self.failureException, \
AssertionError: ['bar']

(dovrebbe essere ['bar', 'baz'] dove 'baz' è un contenuto da importare e non 
presente prima mentre 'bar' era presente prima dell'import)

Quello che succede indentando è che facendolo ri-girare l'import non entra nei 
subfolder esistenti e quindi non li aggiorna.

> Sara' che ho pure mal interpretato... ma piu' vado a fondo e meno trovo i
> vantaggi nell'utilizzare GS al posto di script imperativi di
> install/uninstall.

Ad ogni modo, dato che mi hai fatto venire il dubbio, ho provato a modificare 
i test: ho aggiunto un oggetto presente anche nell'import 'baz'  
(nota: .preserve contiene *)

    def test_import_site_with_subfolders_and_preserve(self):
        self._setUpAdapters()

        site = _makeFolder('site', site_folder=True)
        site._setObject('foo', _makeFolder('foo'))
        site.foo._setObject('bar', _makeFolder('bar'))

        context = DummyImportContext(site)
        # We want to add 'baz' to 'foo', without losing 'bar'
        context._files['structure/.objects'] = 'foo,%s' % TEST_FOLDER
        context._files['structure/.preserve'] = '*'
        context._files['structure/foo/.objects'] = 'baz,%s' % TEST_FOLDER
        context._files['structure/foo/.preserve'] = '*'
        context._files['structure/foo/baz/.objects'] = ''
        context._files['structure/foo/baz/.properties'] = """\
[DEFAULT]
title = %s
description = %s
"""%('baz_title', 'baz_descr')

	# primo import
        importer = self._getImporter()
        importer(context)
        self.assertEqual(site.foo.baz.title, 'baz_title')

	# secondo import: con 'baz' presente
        site.foo._delObject('baz')
        site.foo._setObject('baz', _makeFolder('baz'))    
        self.assertEqual(site.foo.baz.title, '')
        site.foo.baz.title = 'xxx'
        importer = self._getImporter()
        importer(context)
        self.assertEqual(site.foo.baz.title, 'xxx')
        
        self.assertEqual(len(site.objectIds()), 1)
        self.assertEqual(site.objectIds()[0], 'foo')

        self.assertEqual(len(site.foo.objectIds()), 2, site.foo.objectIds())
        self.assertEqual(site.foo.objectIds()[0], 'bar')
        self.assertEqual(site.foo.objectIds()[1], 'baz')


Il test passa quindi mi pare che correttamente .preserve non sovrascriva i 
file presenti. 
Il dubbio quindi potrebbe essere: non è che hai messo solo il file ma non hai 
messo dentro '*'?

Chiaramente potrei anche sbagliarmi: i test permettono di fare delle prove per 
verificare i comportamenti del codice ma possono anche essere scritti male.

(il test gira anche preservando solo baz:
    context._files['structure/foo/.preserve'] = 'baz'
quindi 'bar' non viene cancellato)
-- 
Riccardo Lemmi                           Email:   riccardo a reflab.it
Reflab S.r.l. - Plone Design, Development and Consulting
Phone: +39 349 4620820                         http://www.reflab.it
-------------- parte successiva --------------
Un allegato non testuale è stato rimosso....
Nome:        signature.asc
Tipo:        application/pgp-signature
Dimensione:  189 bytes
Descrizione: This is a digitally signed message part.
URL:         <http://lists.plone.org/pipermail/plone-plone-it/attachments/20080515/6034f28a/attachment.asc>


Maggiori informazioni sulla lista Plone-IT