Archive

Posts Tagged ‘Phing’

Built In Properties In Phing

January 9th, 2009 No comments

Aside from assigning and using your own properties Phing also comes with a set of built in properties that can be used to find out all sorts of information regarding the system that Phing is run on.

As an example, lets say you wanted to found out the operating system that phing is being run on. In this case you would use the variable host.os, which on a Windows XP system would print out WINNT.

There are a lot of different properties available, so I have included the table from the phing website at the bottom of this post as a reference. However, there is one special variable called env that needs further explanation. The env variable references any environment variables that have been set. For example, if you set an environment variable using the following shell command (on UNIX based systems only).

export TESTVAR=mytestvar

You can now reference this in your build.xml file by using the following.

${env.TESTVAR}

Here is a table of the built in properties available.

Property Contents
application.startdir Current work directory
env.* Environment variables, extracted from $_SERVER.
host.arch System architecture, i.e. i586. Not available on Windows machines.
host.domain DNS domain name, i.e. php.net. Not available on Windows machines.
host.fstype The type of the filesystem. Possible values are UNIX, WINNT and WIN32
host.name Operating System hostname as returned by posix_uname(). Not available on Windows machines.
host.os Operating System description as set in PHP_OS variable (see PHP Manual).
host.os.release Operating version release, i.e. 2.2.10. Not available on Windows machines.
host.os.version Operating system version, i.e. #4 Tue Jul 20 17:01:36 MEST 1999. Not available on Windows machines.
line.separator Character(s) that signal the end of a line, "\n" for Linux, "\r\n" for Windows system, "\r" for Macintosh.
os.name Operating System description as set in PHP_OS variable.
phing.file Full path to current buildfile.
phing.home Phing installation directory, not set in PEAR installations.
phing.version Current Phing version.
phing.project.name Name of the currently processed project.
php.classpath The value of the environment variable PHP_CLASSPATH.
php.version Version of the PHP interpreter. Same as PHP constant PHP_VERSION (see PHP Manual).
project.basedir The current project basedir.
user.home Value of the environment variable HOME.

This list can also be found on the Phing website.

I have found that even though some of variables specifically say "not available on Windows" most of them will produce some sort of output, even on Windows machines. Here is a test build.xml file that you can use to see what the different variables print out on your system.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
 
 <target name="main">
  <echo>application.startdir ${application.startdir}</echo>
  <echo>host.arch ${host.arch}</echo>
  <echo>host.domain ${host.domain}</echo>
  <echo>host.fstype ${host.fstype}</echo>
  <echo>host.name ${host.name}</echo>
  <echo>host.os ${host.os}</echo>
  <echo>host.os.release ${host.os.release}</echo>
  <echo>host.os.version ${host.os.version}</echo>
  <echo>line.separator ${line.separator}</echo>
  <echo>os.name ${os.name}</echo>
  <echo>phing.file ${phing.file}</echo>
  <echo>phing.home ${phing.home}</echo>
  <echo>phing.version ${phing.version}</echo>
  <echo>phing.project.name ${phing.project.name}</echo>
  <echo>php.classpath${php.classpath}</echo>
  <echo>php.version ${php.version}</echo>
  <echo>project.basedir ${project.basedir}</echo>
  <echo>user.home ${user.home}</echo>
 </target>
</project>

This file misses out the env property as this is a custom property.

Categories: PHP Tags: , , , ,

Using Custom Properties In Phing

January 8th, 2009 No comments

Phing allows you to set up certain parameters that can be used throughout the rest of the script. These might be used to define a non standard build directory, or to store database connection details that can be written to the connection file during the build.

Properties are defined using the property element, which you should place at the top of your build.xml file in order to make it easy for other developers to see what is going on. The following example defines a property and the uses the main target to print the property out.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
 <property name="property1" value="value1" />
 
 <target name="main">
  <echo>property1: ${property1}</echo>
 </target>
</project>

Running this build.xml file will product the following result.

C:\myProject>phing
Buildfile: C:\myProject\build.xml
 
myProject > main:
    [echo] property1: value1
 
BUILD FINISHED
 
Total time: 0.2119 seconds

It is possible to define properties using the command line. The following build.xml file is similar to the first but it tries to print out a second property that is not defined. The main target now has an attribute called if, which is used to see if a property is defined. If the property2 property is not defined then the target will not run, but it will also not product any errors.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
 <property name="property1" value="value1" />
 
 <target name="main" if="property2">
  <echo>property1: ${property1}</echo>
  <echo>property2: ${property2}</echo>
 </target>
</project>

To run this script with property2 present use the -D flag along with phing.

phing -Dpropertyq2 value2

This can also be written as:

phing -Dpropertyq2=value2

The opposite of the if attribute is the unless attribute. If the property in the unless attribute is defined then the target element is not run. This provides a convenient way of turning on and off targets.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
 <property name="property1" value="value1" />
 
 <target name="main" unless="property2">
  <echo>property1: ${property1}</echo>
 </target>
</project>

The main target can be turned off in by using the following command.

phing -Dproperty2 value2

When a property is set on the command line it overrides any value that has been set for that property within the build.xml file.

You can also override properties from within the same build.xml file by using the override attribute of a second property element.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
 <property name="property1" value="value1" />
 
 <target name="main">
  <property name="property1" value="wibble" override="yes" />
  <echo>property1: ${property1}</echo>
 </target>
</project>

The value of the property1 property will now be wibble.

Using Patternset With Fileset In Phing

January 7th, 2009 No comments

When a project gets complicated then so to can the build.xml file associated with it. You might find it necessary to have multiple different filesets, each of which do something different, but all of which have the same core files that they use. Multiple filesets are useful if you want to create a version of your project with all of the testing files in place so that it can be tested by external developers.

Creating multiple filesets can create problems, one of which is maintenance. Confusion can also occur even if you have a single large fileset where lots of different rules for including and excluding files are defined.

This is where the patternset element comes in. You can create a set of reusable file lists that can be used by more than one fileset, but which also makes maintenance a little easier.

The following snippet shows two patternset elements that show include files and exclude files.

<patternset id="inc_files">
 <include name="**/*.php" />
 <include name="something/**" />
</patternset>
 
<patternset id="exc_files">
 <exclude name="**/*_test.php" />
 <exclude name="myProject_build/**" />
</patternset>

This is then used by the fileset element in the following way.

<fileset dir="./" id="myProjectFiles">
 <patternset refid="inc_files" />
 <patternset refid="exc_files" />
</fileset>

Notice that the pattern set definition contains the id attribute, whereas the patternset within the fileset contains a refid attribute. The refid attribute must contain the name of a patternset, defined by using the id attribute.

You can also add in exclude and include elements into the fileset, along with any patternset elements.

<fileset dir="./" id="myProjectFiles">
 <patternset refid="inc_files" />
 <patternset refid="exc_files" />
 <include name="**/bla*.php" />
</fileset>

Categories: PHP Tags: , , ,

Copying Files Using Phing

January 6th, 2009 No comments

One of the main reasons to use Phing is to create a copy of your project in another directory that you can then use as your distribution copy. Your working directory might contain lots of testing code that is not needed in the final build.

To copy a file from one directory to another using Phing you need to use the copy element. Here is a simple example where a single file is copied from one directory to another.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
<target name="main">
<copy file="index.php" tofile="myProject_build/index.php" />
</target>
</project>

This isn’t entirely useful as you will need to create a rule for every file you want transfered, which might be a few. To copy a directory you need to set up a fileset element. This will contain a list of files and directories that you want to be copied. A fileset element can contain include and exclude rules that govern which files will be used. Here is an example of a fileset, which would normally be on the root of the project element.

<fileset dir="./" id="myProjectFiles">
 <exclude name="**/*_test.php" />
 <include name="**/*.php" />
</fileset>

In this example we are excluding any file in this and any sub directory that has a filename ending in _test.php as these will be our test files that we don’t want copied. We then include any file that contains the .php extension. Because any exclude rules override any include rules this will work as expected and only copy across .php files without a _test at the end of the file name.

You can also specify a directory and everything in it by using the following include rule.

<include name="something/**" />

The previous fileset example can also be written as the following, although I don’t recommend this as it can get complicated!

<fileset dir="./" id="myProjectFiles" includes="**/*.php something/**" excludes="**/*_test.php" /&gtl

To do something useful with this fileset we can use the copy element again. The main difference here is that we are using the todir attribute of the copy element to designate the destination of the copy.

<?xml version="1.0"?>
<!-- build xml -->
<project name="myProject" default="main">
 
 <fileset dir="./" id="myProjectFiles">
  <exclude name="**/*_test.php" />
  <include name="**/*.php" />
 </fileset>
 
 <target name="main">
  <copy todir="./myProject_build">
   <fileset refid="myProjectFiles" />
  </copy>
 </target>
</project>

If you run this it will copy all the files (without the exceptions) and directories from the current directory to a directory called myProject_build. If the destination directory doesn’t exist then phing will create it. This works well, but if you run this code a second time it will copy the myProject_build into itself and you will get a recursive directory structure, which is quite messy and probably not what you want. There are two ways to prevent this. The first is to store your project in a subdirectory from your build.xml file and change your fileset rule accordingly. The second way is to add on an exclude rule to your fileset to specifically ignore the build directory and all of its contents.

<exclude name="myProject_build/**" />

Using the fileset and copy elements in this manner allows you to perform operations on the files as you copy them. This might be, for example, adding in a version number to the top of each file using a token replace.

Categories: PHP Tags: , , , , ,

Introduction To The Phing build.xml File

January 5th, 2009 No comments

By default, Phing will look for a file in the current working directory called build.xml when you run it. This document tells Phing what it will be doing during the build. You can change this by using the -f or the -buildfile property of phing and giving the build file as the parameter. The following code makes phing look for a build file called wibble.xml.

phing -f wibble.xml

Assuming that the project is called myProject, then a minimal buildfile would be look like the following:

<?xml version="1.0"?>
<-- This is a comment -->
 
<project name="myProject" default="main">
  <target name="main" />
<project>

Of course, this doesn’t actually do anything at all, so it is utterly useless.

Every build file should consist of at a root project level, with one or more targets. Targets act as functions, they will copy your code to another directory, create a zip file, create documentation or do anything you want the build to do. You can run multiple targets, one after the other, by using the depends attribute. The following build file will run the first target before running the main target.

<?xml version="1.0"?>
<-- This is a comment -->
 
<project name="myProject" default="main">
  <target name="first" />
  <target name="main" depends="first" />
<project>

When run this will output the following:

C:\myProject>phing
Buildfile: C:\myProject\build.xml
 
myProject > first:
 
myProject > main:
 
BUILD FINISHED
 
Total time: 0.2197 seconds

You can call the targets whatever you want, but it is a good idea to call them by their functional name. You can also run single targets by running phing with an argument of the target in question. For example, if you want to run only the first target you would use the following command.

phing first

The target also supports the description attribute, which allows you to add a small description of that the target does. This is useful from a maintenance point of view, but also from a documentation point of view.

<?xml version="1.0"?>
<-- This is a comment -->
 
<project name="myProject" default="main">
  <target name="first" description="The first target." />
  <target name="main" description="The main and final target." depends="first" />
<project>

You can get phing to print out a list of the targets and their description by using the projecthelp flag like this.

phing -projecthelp

This will print out the following.

C:\myProject>phing -projecthelp
Buildfile: C:\myProject\build.xml
Default target:
-------------------------------------------------------------------------------
 main The main and final target
 
Main targets:
-------------------------------------------------------------------------------
 first The first target
 main The main and final target

To actually do anything in a target you need to add in other xml tags. As a quick example you can echo text to the screen by using the echo tag. The following build file will print out a message to the screen when run.

<?xml version="1.0"?>
<-- This is a comment -->
 
<project name="myProject" default="main">
 <target name="main">
  <echo>Have I built anything yet?</echo>
 </target>
<project>

Categories: PHP Tags: , , , , , ,