Cli parsing in FlexyFramework, PEAR Console_GetArg

Published 2011-08-11 00:00:00
 And another rare article get's published, I've been slacking off posting recently. As I've been busy getting some interesting sites online. The biggest being a rather fun viral advertising campaign on facebook Which I ended up project managing, after originally only committing to do the facebook integration.

Anyway back to the open source stuff. One of the tasks I've had on my todo list for a while is revamping the CLI handling of my framework, Which probably has a tiny following, but is one of those increadably simple, yet powerfull backbones to all my projects.

While this article focuses on the changes to the framework, it should also be of interest to others developing frameworks, and anyone interested in using PEAR's Console_GetArg.

The Problem.

FlexyFramework, for quite some time has been able to run the bootstrapper in both a 'web view' and on the command line, basically the 'index.php' that is the simple configuration file and start point to every piece of code that runs the framework can be run both form apache, and from the command line called as
#php index.php Path/To/Class
Just like the apache requests that map http://yoursite/index.php/Path/To/Class to PROJECTNAME_Path_To_Class, in the same way, the previous command maps to the the same class, and calls the get() method just like a standard web GET request.

This mainly enables you to run code in both scenarios  sharing all the same base configuration information, which is normally set in the index.php. The framework includes support for things like 'single instance', so if you run cron jobs you can ensure that the script is only being run by one instance at a time, so long running jobs do not overlap and duplicate the same task.

The only remaining problems with the previous code was that it had a very messy method to deal with 'help' and listing the available classes that could be run on a project. It used to look for a 'Cli.php' class and call that to display some help text. This meant that adding a new cli feature, also meant updating the Cli.php file (which usually just got forgotten about as development pace rarely left time for such niceties). The other issue was that while most classes just provided a simple task when run, a few more complex Cli applications where in need of parameter passing, to debug or test, previously each time argument parsing was done, I either just parsed $_SERVER[argv] or had used one of the PEAR libraries to do argument parsing. 

So the bug tracker had an open task to move the 'help' information into the class that actually supplied the code for the Cli, and integrate PEAR's Console_GetArg into the core framework, so that there was a standard way to define what arguments a class would accept, and what it would do.

List of available commands

The Framework in Cli mode, run without arguments, now will actually attempt to load all the .php files inside the Project directory, and test to see if there is a static property $cli_desc is set for the class. 
static $cli_desc = "some description"
If this is available it will output a line with the class path, and that description. For the Pman project it outputs something like this.

#php admin.php 
FlexyFramework Cli Application Usage:
#php -d include_path=.:/var/www/pear admin.php [COMMAND] --help
#php  admin.php [COMMAND] --help
Available commands:
Builder/RunGenerator                    Creates Database Tables for modules
Core/JsCompile                          Wrapper around Javascript compression tools
Core/Notify                             Send out notification emails (usually from cron)
Core/NotifySend                         Send out single notification email (usually called from  Core/Notify)

Detailed help and command parsing.

Now that I could find the classes with Cli support, the next step was making the documentation available inside the class, a similar method was done for this, each class that has Cli support, can now support a $cli_opts property, which is just the configuration from Console_GetArg

For example, the code in Core/Notify looks like this.

 static $cli_opts = array(
        'debug' => array(
            'desc' => 'Turn on debugging (see DataObjects debugLevel)',
            'default' => 0,
            'short' => 'v',
            'min' => 1,
            'max' => 1,
        'list' => array(
            'desc' => 'List message to send, do not send them..',
            'default' => 0,
            'short' => 'l',
            'min' => 0,
            'max' => 0,
        'old' => array(
            'desc' => 'Show old messages..',
            'default' => 0,
            'short' => 'o',
            'min' => 0,
            'max' => 0,

and you can now see the help on any Cli applicaiton by simply adding --help to the call, eg.

#php admin.php Core/Notify --help
Usage: php admin.php Core/Notify [-olv]  
    -v --debug=<value>  Turn on debugging (see DataObjects debugLevel ) (0)
    -l --list           List message to send, do not send them.. (0)
    -o --old            Show old messages.. (0)
The code that handles the hard work is inside this file (it's only loaded and used when running Cli.


Add a comment (requires javascript!)
Comment Title
I am a link spammer?