My favorites | Sign in
Project Logo
    
Search
for
Updated Feb 05, 2008 by izimobil
Labels: Featured
UserManual  

This is the Console_CommandLine user manual (work in progress).

Disclaimer

Since Console_CommandLine was highly inspired from the python optparse module and thus is very similar to it, some parts of this document were shamelessly stolen from optparse manual ;)

Introduction

Console_CommandLine is a convenient, flexible, and powerful library for parsing command-line options and arguments. Console_CommandLine uses a declarative style of command-line parsing: you create an instance of Console_CommandLine, populate it with options, arguments and even sub-commands and parse the command line. Console_CommandLine allows users to specify options in the conventional GNU/POSIX syntax, and additionally generates usage and help messages for you.

Here's an example of using Console_CommandLine in a simple script:

<?php
require_once 'Console/CommandLine.php';

$parser = new Console_CommandLine();
$parser->description = 'A fantastic command line program that does nothing.';
$parser->version = '1.5.0';
$parser->addOption('filename', array(
    'short_name'  => '-f',
    'long_name'   => '--file',
    'description' => 'write report to FILE',
    'help_name'   => 'FILE',
    'action'      => 'StoreString'
));
$parser->addOption('quiet', array(
    'short_name'  => '-q',
    'long_name'   => '--quiet',
    'description' => "don't print status messages to stdout",
    'action'      => 'StoreTrue'
));
$result = $parser->parse();
?>

With these few lines of code, users of your script can now do the "usual thing" on the command-line, for example:

<yourscript> --file=outfile -q

As it parses the command line, Console_CommandLine sets attributes of the result object returned by parse() method based on user-supplied command-line values. When parse() returns from parsing this command line, $result->options['filename'] will be outfile and $result->options['quiet'] will be true.

Console_CommandLine supports both long and short options, allows short options to be merged together, and allows options to be associated with their arguments in a variety of ways. Thus, the following command lines are all equivalent to the above example:

<yourscript> -f outfile --quiet
<yourscript> --quiet --file outfile
<yourscript> -q -foutfile
<yourscript> -qfoutfile

Additionally, users can run one of

<yourscript> -h
<yourscript> --help

and Console_CommandLine will print out a brief summary of your script's options:

Usage: <yourscript> [options]

Options:
  -h, --help            show this help message and exit
  -f file, --file=file  write report to FILE
  -q, --quiet           don't print status messages to stdout

or

<yourscript> --version

and the program version will be printed to stdout:

<yourscript> version 1.0.0

where the value of yourscript is determined at runtime (normally from $argv0, except if you specified explicitely a name for your parser).

Creating the parser

There are two differents ways to create parsers, you can create a parser using php code or by loading an xml definition file or string.

Using php code

<?php
require_once 'Console/CommandLine.php';
$parser = new Console_CommandLine(array(
    'description' => 'A useful description for your program.',
    'version'     => '0.0.1', // the version of your program
));
?>

Alternatively you could have done:

<?php
require_once 'Console/CommandLine.php';
$parser = new Console_CommandLine();
$parser->description = 'A useful description for your program.';
$parser->version = '0.0.1'; // the version of your program
?>

Both method are strictly equivalent.

Using an xml file

The xml file (we'll name it "example.xml")

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<command>
    <description>A useful description for your program.</description>
    <version>0.0.1</version>
</command>

The PHP file

<?php
require_once 'Console/CommandLine.php';
$parser = Console_CommandLine::fromXmlFile('example.xml');
?>

Note: Using and xml string you would have called Console_CommandLine::fromXmlString instead of Console_CommandLine::fromXmlFile of course.

Populating the parser

Now that you know how to create parsers we will see how to add to it:

If you are using an xml file, you will not have to do all these tasks, but it is useful that you read this section in order to understand how Console_CommandLine works.

Adding options

Some background

Options are used to provide extra information to tune or customize the execution of a program. In case it wasn't clear, options are usually optional. A program should be able to run just fine with no options whatsoever. (Pick a random program from the Unix or GNU toolsets. Can it run without any options at all and still make sense? The main exceptions are find, tar, and dd--all of which are mutant oddballs that have been rightly criticized for their non-standard syntax and confusing interfaces.)

Lots of people want their programs to have "required options". Think about it. If it's required, then it's not optional! If there is a piece of information that your program absolutely requires in order to run successfully, that's what arguments are for.

As an example of good command-line interface design, consider the humble cp utility, for copying files. It doesn't make much sense to try to copy files without supplying a destination and at least one source. Hence, cp fails if you run it with no arguments. However, it has a flexible, useful syntax that does not require any options at all:

cp SOURCE DEST
cp SOURCE ... DEST-DIR

You can get pretty far with just that. Most cp implementations provide a bunch of options to tweak exactly how the files are copied: you can preserve mode and modification time, avoid following symlinks, ask before clobbering existing files, etc. But none of this distracts from the core mission of cp, which is to copy either one file to another, or several files to another directory.

Adding options with Console_CommandLine

To add options to your parser, just create the parser as explained in the previous section and use the Console_CommandLine::addOption() method.

The Console_CommandLine::addOption() takes two arguments:

key description example
short_name the option short name -o
long_name the option long name --orientation
description description of the option orientation of the page, ltr (default) or rtl
action this is explained in the next section StoreString
default the option default value ltr
choices an array of possible values for a given option array('ltr', 'rtl')
help_name a string containing the name to display in the option help line page_orientation (the option line will be: --orientation=page_orientation description...)

Here are some usage examples of the addOption() method:

<?php

require_once 'Console/CommandLine.php';
$parser = new Console_CommandLine(array(
    'description' => 'A useful description for your program.',
    'version'     => '0.0.1', // the version of your program
));

// Adding a simple option that takes no argument and that tell our program to 
// turn on verbose output:
$parser->addOption(
    'verbose',
    array(
        'short_name'  => '-v',
        'long_name'   => '--verbose',
        'description' => 'turn on verbose output',
        'action'      => 'StoreTrue'
   )
);

// Adding an option that will store a string
$parser->addOption(
    'orientation',
    array(
        'short_name'  => '-o',
        'long_name'   => '--orientation',
        'description' => 'orientation of the page, "ltr" (default) or "rtl"',
        'action'      => 'StoreString',
        'default'     => 'ltr',
        'help_name'   => 'page_orientation'
   )
);

try {
    $result = $parser->parse();
    print_r($result->options);
} catch (Exception $exc) {
    $parser->displayError($exc->getMessage());
}

// if the user type:
// <yourprogram> -vo rtl
// or (equivalent):
// <yourprogram> --verbose --orientation=rtl
// this will print
// array(
//     'verbose' => true,
//     'orientation' => "rtl"
// )

?>

Understanding option actions

Actions tell the parser how to handle option values, among other things they tell the parser if the option expects a value or not and how to store this value in the result object. Possible actions are explained in the following tables:

Store actions:

action description example
StoreTrue This action tells the parser to store the value true in the result object if the option is present in the command line <yourprogram> -v will store true in $result->options['verbose'] assuming the option was defined like this: $parser->addOption('verbose', array('short_name'=>'-v', 'action'=>'StoreTrue'));
StoreFalse This action tells the parser to store the value false in the result object if the option is present in the command line <yourprogram> --fake will store fake in $result->options['for_real'] assuming the option was defined like this: $parser->addOption('for_real', array('long_name'=>'--fake', 'action'=>'StoreFalse'));
StoreString This action tells the parser that the option expects a value and to store this value as a string in the result object <yourprogram> -o /tmp/out.txt will store /tmp/out.txt in $result->options['outfile'] assuming the option was defined like this: $parser->addOption('outfile', array('short_name'=>'-o', 'action'=>'StoreString'));
StoreInt This action tells the parser that the option expects a value and to store this value as an integer in the result object <yourprogram> --width=500 will store 500 in $result->options['width'] assuming the option was defined like this: $parser->addOption('width', array('long_name'=>'--width', 'action'=>'StoreInt'));
StoreFloat This action tells the parser that the option expects a value and to store this value as a float in the result object <yourprogram> -l 0.3 will store 0.3 in $result->options['level'] assuming the option was defined like this: $parser->addOption('level', array('short_name'=>'-l', 'action'=>'StoreFloat'));
StoreArray This action tells the parser that the option expects one or more values and to store these values as an array in the result object <yourprogram> --input_files=foo bar baz will store array('foo', 'bar', 'baz') in $result->options['input_files'] assuming the option was defined like this: $parser->addOption('input_files', array('long_name'=>'--input_files', 'action'=>'StoreArray'));

Special actions:

Counter This action tells the parser to increment the value in the result object each time it encounters the option in the command line <yourprogram> -vvvv or <yourprogram> -v -v -v -v will store 4 in $result->options['verbose_level'] assuming the option was defined like this: $parser->addOption('verbose_level', array('short_name'=>'-v', 'action'=>'StoreCounter'));
Help This action tells the parser to display the help message if it encounters the option in the command line, most of the time you won't need this since it is handled by Console_CommandLine internally <yourprogram> -h or <yourprogram> --help will display the help message if you didn't set the property add_help_option to false in the parser object
Version This action tells the parser to display the program version if it encounters the option in the command line, most of the time you won't need this since it is handled by Console_CommandLine internally <yourprogram> --version will display the version string if you didn't set the property add_version_option to false and if you set the version property in the parser object
Password This action allows the user to either type the password on the commandline or to be prompted for it (will not echo on unix systems) <yourprogram> -p will prompt the user for a password assuming the option was defined like this: $parser->addOption('password', array('short_name'=>'-p', 'action'=>'Password'));
Callback This action is explained in details in the new section

The callback action

TODO

Adding arguments

Some background

Arguments are for those pieces of information that your program absolutely, positively requires to run.

A good user interface should have as few absolute requirements as possible. If your program requires 17 distinct pieces of information in order to run successfully, it doesn't much matter how you get that information from the user, most people will give up and walk away before they successfully run the program. This applies whether the user interface is a command-line, a configuration file, or a GUI: if you make that many demands on your users, most of them will simply give up.

In short, try to minimize the amount of information that users are absolutely required to supply and use sensible defaults whenever possible. Of course, you also want to make your programs reasonably flexible. That's what options are for.

How Console_CommandLine handles arguments

To add arguments to your parser, just create the parser as explained in the previous section and use the Console_CommandLine::addArgument() method.

The Console_CommandLine::addArgument() takes two arguments:

key description example
description description of the argument list of input files separated by spaces
multiple boolean that tells the parser that the argument can store multiples values true
help_name a string containing the name to display in the argument help line files (the argument line will be: files description...)

Here are some usage examples of the addArgument() method:

<?php

require_once 'Console/CommandLine.php';
$parser = new Console_CommandLine();

// add an array argument
$parser->addArgument('input_files', array('multiple'=>true));

// add a simple argument
$parser->addArgument('output_file');

try {
    $result = $parser->parse();
    print_r($result->options);
} catch (Exception $exc) {
    $parser->displayError($exc->getMessage());
}

// if the user type:
// <yourprogram> file1 file2 file3
// this will print
// array(
//     'input_files' => array('file1', 'file2'),
//     'output_file' => 'file3'
// )

?>

Adding sub-commands

What the hell are "sub-commands" ?

Well some programs are very complex, you can't do anything about that but you need to provide the best user interface possible in order to have happy users. In some cases, sub-commands can be very useful, take the PEAR installer for example, it is much more clearer to separate the installer functionalities than to mix all functionalities in the same interface, that's why you have an interface like:

$ pear install <options> <pkgname>
$ pear upgrade <options> <pkgname>
and so on...

As an example, sub-commands can be considered as the equivalent of tabbed graphical user interfaces. In short, when your program can do a lot of different and unrelated tasks, chances are you will need "sub-commands" in you command line interface.

How Console_CommandLine handles sub-commands ?

TODO

Extending Console_CommandLine

TODO

Adding new actions

TODO

Customizing the renderer

TODO

I18n support

TODO

Examples


Sign in to add a comment
Hosted by Google Code