First Phing Plugin

I’m a huge fan of Phing and use it regularly for build and deployment tasks. Often, I’ll ask about a plugin that I wish existed, and get a very courteous “patches welcome” from the nice people in the #phing channel on freenode. This has happened a few times, so I thought I should probably look at how to make a new phing plugin, this article shows you how to make the simplest thing I could think of: a simple “hello world” plugin.

Setting Up From Source

First of all, you’ll need a copy of phing you can edit, and the best way to do that is to fork their github repo https://github.com/phingofficial/phing to your own account, and clone that onto your development machine (if you’re new to github, I wrote an article about that too).

The program you want to run is in bin/phing in the project you cloned, I used an example config file called hello.xml (by default it looks for build.xml):

bin/phing -f hello.xml

Creating Your Plugin

To create a plugin for phing, you’ll need to add something in the classes/phing/tasks/ext/ directory. For a simple plugin, this will be a single file as you see in this example, but you can also add a directory to hold any additional classes or code that your plugin will need; just look at what’s already there for the best examples.

There are three things you need to know about your plugin:

  • You should check any dependencies in the init() method of your new class
  • The real work in your plugin is done in the main() method
  • To give output, use $this->log

With all that in mind, here’s my task class, named HelloTask and located in classes/phing/tasks/ext/HelloTask.php:

<?php

/**
 * Dummy task as proof of concept
 *
 * @author    Lorna Mitchell
 * @package   phing.tasks.ext
 */
class HelloTask extends Task {


    /**
     * do the work
     */
    public function main() {

        $this->log("Greetings, " . $this->name);

    }

    public function setName($name) {
        $this->name = $name;
    }
}

Before we can use this class as a new target though, we need to let Phing know it is there, by adding it to the defaults.properties file (full path: classes/phing/tasks/defaults.properties), like so:

hello=phing.tasks.ext.HelloTask

Using Your New Plugin

Regular users of Phing will know that to configure it, you specify a target, and add tasks to that target. What we have created here is a task. Here’s the configuration file I used to try out using my plugin, with a single project and defaulting to the only target:

<?xml version="1.0"?>
<project name="hello" default="hello">
    <target name="hello">
        <hello name="Orbit" />
    </target>
</project>

(Orbit is a cat, in case you are wondering! Photos are available)

If any of this is unfamiliar, then I recommend you take a diversion over to the Phing documentation as it is excellent, then come back to here.

When I run this, I get:

$ bin/phing -f hello.xml
Buildfile: /home/lorna/svndir/phing/hello.xml

hello > hello:

    [hello] Greetings, Orbit

BUILD FINISHED

Total time: 0.0428 seconds

Yay, the plugin is working! But we skated over some important stuff regarding the name parameter, so let’s look at that in more detail.

Parameters and Phing Plugins

The configuration file can hold any parameters you care to pass, but your class needs to know what to do with them! This example had a single parameter called “name”, and all you have to do is declare a setter method for that parameter – in this case a name attribute is handled by a setName() setter, called when the task is created.

Now you can create a phing plugin (or contribute additional features to an existing one) yourself, what are you waiting for? What will you build? Personally I’d like to see a Mercurial plugin for phing, so I’m helping out with the PEAR VersionControl_Hg project to work towards that goal … watch this space.

8 thoughts on “First Phing Plugin

  1. You can also ship your own tasks within your application sources. That`s the way I do prefer, just add an taskdef definition in your build file which points to the “local” task file and you are done. I use that a lot for application specific tasks (e.g. code generation).

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.