Posts Tagged ‘ant’

An alternative method to build eZ Publish configuration files with ANT and the C Preprocessor

October 18th, 2009

eZ Publish configuration files have a major problem : they are not context aware.
This means that you can not build them especially for production or development servers.

I thought about a solution to sort of workaround this problem by using the C preprocessor and macros in configuration files.

Let’s take a simple example. When you work with override.ini directives, you have to write a few configuration directives in order to load the correct template for the correct context, for example, a nodeID. But if this nodeID change between servers, you could have for example this on your development machine :

[foo_bar]
....
Match[node]=123

this on your staging machine :

[foo_bar]
....
Match[node]=456

this on your production machine :

[foo_bar]
....
Match[node]=789

When it comes to industrialize the process of creating correct configuration files with correct nodeIDs (or any other configuration directives) things become more and more complex.

It would be interesting to be able to include the correct values depending on the context in which you want to use your configuration files.

This is where the C preprocessor comes into play, by using specific macros like #include or #ifdef we can generate context aware configuration files without any problem, simply by including the correct configuration file and integrate it into the real eZ Publish one.

For example for override.ini.append.php, this gives the following override.ini.append.php file :

<?php /* #?ini charset="utf-8"?

[full_folder]
Source=node/view/full.tpl
MatchFile=full/folder.tpl
Subdir=templates
Match[class_identifier]=folder

[line_folder]
Source=node/view/line.tpl
MatchFile=line/folder.tpl
Subdir=templates
Match[class_identifier]=folder

// some comments
// in the ini file
// they will automatically
// transformed into correct
// eZINI comments

#ifdef CONTEXT_DEV
#include "override.ini.dev"
#endif

#ifdef CONTEXT_STAGING
#include "override.ini.staging"
#endif

#ifdef CONTEXT_PROD
#include "override.ini.prod"
#endif

*/ ?>

With the following included files

override.ini.dev

// global overrides
[my_dev_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=11111

override.ini.staging

// global overrides
[my_staging_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=22222

override.ini.prod

// global overrides
[my_prod_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=33333

So when we run (note this is not that simple, but I took a few shortcuts in order to be quick)

 cpp -P -DCONTEXT_PROD=1 override.ini.append.php

We get the following result :

<?php /* #?ini charset="utf-8"?

[full_folder]
Source=node/view/full.tpl
MatchFile=full/folder.tpl
Subdir=templates
Match[class_identifier]=folder

[line_folder]
Source=node/view/line.tpl
MatchFile=line/folder.tpl
Subdir=templates
Match[class_identifier]=folder

# some comments
# in the ini file
# they will automatically
# transformed into correct
# eZINI comments
# global overrides

[my_prod_override]
Source=path/to/template.tpl
MatchFile=path/to/matchfile.tpl
Subdir=templates
Match[node]=33333

*/ ?>

As we can see, override.ini.append.php has been created with the correct production nodeID.

Since calling cpp is quite annoying with this ini syntax (mostly due to the presence of PHP comments) I decided to automate the process by wrapping everything into an Ant build script. With the script, building all configuration files should be as easy as running :

 ant clean && ant dev

or

 ant clean && ant staging

or

 ant clean && ant prod

You will find attached a tarball with a fake eZ Publish instance plus settings and context files.
By running of of the commands above, you can generate your configuration files in no time.

Here is an explanation of the ant script’s behaviour. First you have to have the following directory structure :

.
|-- build.xml
|-- common.xml
`-- fakeezinstance
    |-- build.xml
    |-- extension
    |   `-- myextension
    |       |-- build.xml
    |       `-- settings.orig
    |           |-- dbsettings.dev
    |           |-- dbsettings.prod
    |           |-- dbsettings.staging
    |           |-- site.ini.append.php
    |           `-- siteaccess
    |               `-- site.com
    |                   |-- override.ini.append.php
    |                   |-- override.ini.dev
    |                   |-- override.ini.prod
    |                   `-- override.ini.staging
    `-- settings.orig
        |-- override
        |   |-- override.ini.append.php
        |   |-- override.ini.dev
        |   |-- override.ini.prod
        |   `-- override.ini.staging
        `-- siteaccess
            `-- site.com
                |-- override.ini.append.php
                |-- override.ini.dev
                |-- override.ini.prod
                `-- override.ini.staging

As you can see any original settings are located into settings.orig directories. Each of them contains configuration files, I just created an example with override.ini and site.ini. But you can use any configuration file. For each .ini file I created a context file, dbsettings.dev/staging/prod for site.ini for example.

Once the configuration files are ready, we can simply run :

 ant clean && ant prod

And you will see that all settings folder will be created with the correct values.

If you want to add another extension in the build, the only thing you have to do is to copy the build.xml file available in extension/myextension and create a settings.orig directory structure. If you do not want your extension(s) to be processed by the build script, just do not copy the build.xml file and create the settings directory structure as you would normally do.

So one can say that there is a lot of blank lines in the files onces they have been preprocessed. That is true, but remember that those files are supposed to be read by eZ Publish only. If fakeezproject.taryou need to change anything, just update the file you want in settings.orig and rerun the build process, it takes less than 2 seconds.

Download the fakeezproject.tar archive, go in fakeproject ant run ant prod for example.

‘Hope that helps.

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Creating private targets with Ant

July 30th, 2009

I have been using Ant for quite a few weeks now, trying to get rid of the eZ Publish’ 6000 lines shell script build system and then using Ant almost exclusively.

I was looking for a way to create privet targets, i.e targets which could not be called by the user.

I finally found the solution, and it is quite trivial, just prefix your target’s name with a dash.

Let’s do a quick “before/after” comparison.

Before : no private targets

<?xml version="1.0"?>

<project name=”MyProject” basedir=”.” default=”build”>

<target name=”public”>
<echo message=”Calling public target”/>
</target>

<target name=”private”>
<echo message=”Calling private target”/>
</target>

</project>

and calling

ant public private

returns :

public:
[echo] Calling public target

private:
[echo] Calling private target

After : converting the “private” target into a “real” private one :

<?xml version="1.0"?>

<project name=”MyProject” basedir=”.” default=”build”>

<target name=”public”>
<echo message=”Calling public target”/>
</target>

<target name=”-private”>
<echo message=”Calling private target”/>
</target>

</project>

and then call the build file again, which returns :

public:
[echo] Calling public target

BUILD FAILED
Target “private” does not exist in the project “MyProject”.

By prefixing the “private” target with a “-” I made it private, well invisible would be more appropriate because there is no real concept of private targets in Ant.

But at least it is not callable from the end-user which is exactly what I was looking for.

‘Hope that helps :)

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)