Discovering GenericSetup

published Jun 25, 2007, last modified Jun 25, 2007

I looked at GenericSetup trunk recently and I discovered some things I was not yet aware of.

If you want to know more about the current state of the trunk of GenericSetup, this thread on the CMF list is a good start.

I had some things to say there too, including a patch.

Rob Miller gave me some helpful pointers, especially about import_various steps.

I learned some things from him and from rummaging around in the code myself.

Context

A GenericSetup handler gets passed a context when called. This context is not the Plone Site or some other content. It is a special GenericSetup context, as defined in GenericSetup/context.py. One of the things you can do with that context is passing it some text for its logger so you get some messages in your log files and in the GenericSetup log:

logger = context.getLogger('eXtremeManagement')
logger.info('eXtremeManagement_various step imported')

Various import steps

When you apply a GenericSetup profile (base or extension does not matter) all registered import steps are executed. So if you have an extension profile that only has a propertiestool.xml file, still all import steps (which can be a few dozen) are run. If all authors of those import steps have done their work correctly, all but one exit immediately as they realize they do not need to do anything.

I will quote Rob Miller here:

It is the responsibility of an import step's implementation to ensure that it is indeed appropriate to perform its actions during any given invocation of the step.

All of the XML-based import steps already do this; they check for the existence of a specific XML file, and if they find it they perform the action. If they do not find the file, no problem, they do nothing.

The so-called importVarious steps, i.e. any step that uses a plain old python function as its handler (as opposed to building on the existing XML parsing infrastructure), must perform this check explicitly. you could restrict it to only running when the intended profile is the one being imported, or you could check for the existence of a specific file within the profile. I like the latter choice.

The summary in my own words: if you want to be a good CMF citizen, you had better make sure that the importVarious step of your profile (or any other import step you define yourself) is only executed when your profile is applied and not when the profile of some unrelated product is applied.

So, taking some pointers from how CMFPlone and CMFEditions do it, I fixed eXtremeManagement. I added a file profiles/default/extrememanagement_various.txt. This can remain empty but it is clearer to add a comment, like this:

The eXtremeManagement_various step is run if this file is present in
the profile.

Then I changed setuphandlers.py:

def importVarious(context):
    # Only run step if a flag file is present
    if context.readDataFile('extrememanagement_various.txt') is None:
        return

For reference, this is the profiles/default/import_steps.xml file that tells GenericSetup about this handler:



  
    
    
    
    Import steps that couldn't be mapped to other handlers.
  

So if you have a CMF/Plone product which defines an own import step (like import various, but it can be a totally different step) please make sure that this step only runs when your own profile is applied.

Upgrade profiles

GenericSetup now has support for profiles that you can use to upgrade a product, instead of applying the complete profile again. I only looked at the code and have not actually tried this. But this is absolutely something I want to use in eXtremeManagement too. So I will probably write about that later.

Keywords
plone xm