Diving into Phing I

Events happening in the community are now at Drupal community events on www.drupal.org.
allisterbeharry's picture

Like I said on the the DAST wiki page http://groups.drupal.org/node/3913 DAST is an implementation of a automated build process for Drupal sites. "Build process" is not a term you hear normally associates with websites, but any dynamic web page needs software which renders the final markup and script which gets delivered in the user's browser. A site running on Drupal is a complex piece of software. Building a Drupal site is complex enough to require a tool to automate the process, especially if you're a developer or tester. One important advantages of having a tool to automate the build process, in addition to lessening the toil of overworked Drupalites, is that it is a repeatable process - you can't forget to do something when building a site which leaves you cursing 1.5 hours later when you finally figure out what you forgot to do. DAST will build a Drupal site exactly the same way every time.

The process of creating a Drupal site can be viewed as a pipeline where code assets and configuration move through different stages until the final build output is successfully produced. The software which provides the framework for constructing this pipeline is Phing (PHng Is Not Gnu make) http://www.phing.info

Phing is basically Ant http://ant.apache.org for PHP - it's pretty amazing how the Phing developers managed to implement so much of Ant in PHP. If you know Ant you could be up and running with Phing without looking at the documentation (actually some places in the docs of Phing seem to have been taken verbatim from the Ant docs.) All of the core concepts from Ant are here - projects, targets, dependencies, tasks, properties, conditional execution, and of course the most important feature for DAST's purposes - extensibility. I'll just briefly explain these concepts and illustrate how they will be used in DAST.

  1. Project
    A project is just a container with a name and description for all the stuff in the build process - it's the root element in the build.xml file, and that's pretty much it, except for one critical attribute - default. The default attribute specifies the name of the target which will be run first when the build begins, if no other target is specified in the build command. e.g:

<?xml version="1.0"?>
<project name="Hello Drupal" description="Simple Phing test build file" default="init-directory" >
  <!-- Everything else here -->
<project>

2.Targets
A target is a container representing a part of the work to done in build process. Targets are the next-highest level element in the
XML build file hierarchy. Targets are atomic and self-contained and hence it is at this level that dependencies and conditional execution
operates. e.g.:
<?xml version="1.0"?>
<project name="Hello Drupal" description="Simple Phing test build file" default="get-foomodule">

<target="init-directory">
<!--Create site directory-->
  <mkdir dir="${sitedir}" />
</target>
 
<target name="get-foomodule" depends="init-directory">
<!-- Pull foomodule from CVS and untar into site directory -->
  <cvsget module="foomodule" version="0.9" dir="${builddir}" untar="${sitedir}"/>
</target>
</project>

In this build file we see that targets are containers for the work to be done, and are capable of having dependencies. The get-foomodule target can only execute if the site directory was created successfully - of course there will be many, many types of dependencies in a Drupal site - including the very interesting problem of module-dependencies. If module x requires module y should the build process be smart enough to get the dependent module, or should it leave it up to the user to make sure all dependencies are explicitly stated? Watch this space.

Note that the name of the target is important and key to the build process. The "default" attribute of specifies the name of the target to start executing first, if no target is specified when the build command is run. Note also that target execution is non-linear
and is determined by dependencies: if target get-foomodule is required to execute, it will first execute init-directory.

${sitedir} is a Phing property - basically a variable either passed to the build command or created from another task. I'll describe properties in part II.

(the formatting on this post is screwed up, I guess it doesn't like the xml tags. I'll try to figure out how to fix it)
3. Tasks
Tasks represent the code that runs in a target. You specify tasks using task names and you can pass parameters to the task through ordinary string attributes. Here's where Phing begins to shine - not only do you get a large library of predefined tasks for common operations like file management, you also get a lot of additional tasks which can be used in the Drupal site build process:
UntarTask
ReplaceRegexpTask
StripPHPCommentsTask
PhpEvalTask
TailFilterTask
TouchTask
PHPUnit2Task

Checkout the Phing documentation for the complete list of the powerful set of tasks Phing provides:
http://phing.info/docs/guide/2.2.0/chapters/appendixes/AppendixA-FactShe...
http://phing.info/docs/guide/2.2.0/chapters/appendixes/AppendixB-CoreTas...
http://phing.info/docs/guide/2.2.0/chapters/appendixes/AppendixC-Optiona...

Of course some tasks require parameter types more complex than simple name/value string pairs. And what about more complex conditionals - how about branching based on Boolean true or false, or equality, or Boolean AND, OR...stay tuned for part II where I'll cover types, conditional tasks, mappers, and other cool Phing stuff.

SoC 2007

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds: