To execute a target, you enter '
phing targetname
' on the command line. Importantly, one target can call other targets, so you can create complex routines that are run with just one command. I use just one command, 'phing ftp
' to do all of the follow:- Run my Unit tests - if any fail the build process stops - and generate a code coverage report
- Minify my JavaScript and CSS files
- Switch off any debugging code in my PHP and remove any comments
- Remove comments from my HTML
- Upload the whole project to the staging server
Powerful stuff but the whole process takes a few minutes from start to end. I usually issue the command and then get on with something else while I wait for the files to be FTPed. What I noticed though was that I'd often forget to keep an eye on the terminal window and I'd miss that the process was complete. I wanted a popup notice to tell me that the files had all been transferred.
This is where Growl comes in. Growl is a really neat notifications system for Mac OSX and Windows. It integrates with a large number of applications. I've integrated it with Mac Mail, so I get a nice big popup message in the middle of my primary screen whenever I get an email.
There are a couple of ways to integrate Growl into an application, but for a system like Phing, the most appropriate is to use the command line tool growlnotify. This is an Growl extra - when you download Growl for Mac OSX, for example, it comes with three extra applications including growlnotify.
You call growlnotify from the command line like this:
growlnotify -n "Phing" -m "My message" -t "Phing"The n parameter (for name) is the name that appears in your Growl preferences, so that you can specifically configure Growl for Phing. The m parameter is obviously the message that will appear in the popup notification and the t parameter sets the title in the popup. The only caveat is that the title parameter must be last.
You can also add a s switch to make the notification sticky.
Integrating this with Phing is actually quite straight forward. Phing already has a task that executes command line programs, so my solution was to extend that task's PHP class. That Phing task is called ExecTask and is located in phing/tasks/system/ExecTask.php. My task that extends this is called GrowlNotifyTask and is located in phing/tasks/mooduino/GrowlNotifyTask.php.
Lets start with your project's build file. Near the top, in side the <project> element, you need to tell Phing about the new task - this line declares the class, tells Phing where to find it, and allows use to start using a <grown> element inside any <target> elements.
<taskdef name="grown" classname="phing.tasks.mooduino.GrowlNotifyTask" />I wanted to use the new task as follows but have the option to override some of the defaults if I wanted.
<grown message="Copying deployment files into build directory." />The code for the task implementation is as follows. It's quite simple; it declares five private instance variables, with public setters and getters. These instance variables correspond to the attributes of the <grown> XML element. All but the $message variables have default values, so only the message attribute is required.
The class also has a main() method that pulls together the values into a command strings, and then uses parent methods in the ExecTask class to execute the command.
<?php require_once 'phing/tasks/system/ExecTask.php'; /** * A Task for calling the command line tool growlnotify as a phing task. * * @author Michael Hodgins */ class GrowlNotifyTask extends ExecTask { private $name = 'phing'; private $sticky = false; private $message = ''; private $identifier = 'phing'; private $title = 'Build'; public function __construct() { parent::__construct(); $this->setTaskName('grown'); } public function init() { parent::init(); } public function setName($name='phing') { $this->name = strval($name); return $this; } public function getName() { return $this->name; } public function setSticky($sticky=true) { $this->sticky = $sticky ? true : false; return $this; } public function isSticky() { return $this->sticky; } public function setMessage($message='') { $this->message = strval($message); return $this; } public function getMessage() { return $this->message; } public function setIdentifier($identifer='phing') { $this->identifier = strval($identifier); return $this; } public function getIdentifier() { return $this->identifier; } public function setTitle($title='Build') { $this->title = strval($title); return $this; } public function getTitle() { return $this->title; } public function main() { $cmd = sprintf( "growlnotify %s-n '%s' -d '%s' -m '%s' -t '%s'", $this->isSticky() ? '-s ' : '', $this->getName(), $this->getIdentifier(), $this->getMessage(), $this->getTitle() ); $this->setCommand($cmd); $this->setEscape(false); parent::main(); } }