|
This is the Console_CommandLine user manual (work in progress). DisclaimerSince 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 ;) IntroductionConsole_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 parserThere 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 fileThe 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 parserNow that you know how to create parsers we will see how to add to it: - options,
- arguments,
- sub-commands.
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 optionsSome backgroundOptions 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_CommandLineTo 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: - the option name: a string that will be used to access the option in the result object. For example if you name your option foo, you will access to the result object like this: $result->options['foo'],
- the options parameters: an array of various informations, here's a full description of the array:
| 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 actionsActions 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 actionTODO Adding argumentsSome backgroundArguments 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 argumentsTo 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: - the argument name: a string that will be used to access the argument in the result object. For example if you name your argument foo, you will access to the result object like this: $result->args['foo'],
- the arguments parameters: an array of various informations, here's a full description of the array:
| 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-commandsWhat 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_CommandLineTODO Adding new actionsTODO Customizing the rendererTODO I18n supportTODO Examples
|