Option Parsers

  • class Cake\Console\ConsoleOptionParser
  • Console applications typically take options and arguments as the primary way toget information from the terminal into your commands.

Defining an OptionParser

Commands and Shells provide a buildOptionParser($parser) hook method thatyou can use to define the options and arguments for your commands:

  1. protected function buildOptionParser($parser)
  2. {
  3. // Define your options and arguments.
  4.  
  5. // Return the completed parser
  6. return $parser;
  7. }

Shell classes use the getOptionParser() hook method to define their optionparser:

  1. public function getOptionParser()
  2. {
  3. // Get an empty parser from the framework.
  4. $parser = parent::getOptionParser();
  5.  
  6. // Define your options and arguments.
  7.  
  8. // Return the completed parser
  9. return $parser;
  10. }

Using Arguments

  • Cake\Console\ConsoleOptionParser::addArgument($name, $params = [])
  • Positional arguments are frequently used in command line tools,and ConsoleOptionParser allows you to define positionalarguments as well as make them required. You can add argumentsone at a time with $parser->addArgument(); or multiple at oncewith $parser->addArguments();:
  1. $parser->addArgument('model', ['help' => 'The model to bake']);

You can use the following options when creating an argument:

  • help The help text to display for this argument.
  • required Whether this parameter is required.
  • index The index for the arg, if left undefined the argument will be putonto the end of the arguments. If you define the same index twice thefirst option will be overwritten.
  • choices An array of valid choices for this argument. If left empty allvalues are valid. An exception will be raised when parse() encounters aninvalid value.
    Arguments that have been marked as required will throw an exception whenparsing the command if they have been omitted. So you don’t have tohandle that in your shell.

Adding Multiple Arguments

  • Cake\Console\ConsoleOptionParser::addArguments(array $args)
  • If you have an array with multiple arguments you can use$parser->addArguments() to add multiple arguments at once.
  1. $parser->addArguments([
  2. 'node' => ['help' => 'The node to create', 'required' => true],
  3. 'parent' => ['help' => 'The parent node', 'required' => true]
  4. ]);

As with all the builder methods on ConsoleOptionParser, addArgumentscan be used as part of a fluent method chain.

Validating Arguments

When creating positional arguments, you can use the required flag, toindicate that an argument must be present when a shell is called.Additionally you can use choices to force an argument to be from a list ofvalid choices:

  1. $parser->addArgument('type', [
  2. 'help' => 'The type of node to interact with.',
  3. 'required' => true,
  4. 'choices' => ['aro', 'aco']
  5. ]);

The above will create an argument that is required and has validation on theinput. If the argument is either missing, or has an incorrect value an exceptionwill be raised and the shell will be stopped.

Using Options

  • Cake\Console\ConsoleOptionParser::addOption($name, $options = [])
  • Options or flags are used in command line tools to provide unordered key/valuearguments for your commands. Options can define both verbose and short aliases.They can accept a value (e.g —connection=default) or be boolean options(e.g —verbose). Options are defined with the addOption() method:
  1. $parser->addOption('connection', [
  2. 'short' => 'c',
  3. 'help' => 'connection',
  4. 'default' => 'default',
  5. ]);

The above would allow you to use either cake myshell —connection=other,cake myshell —connection other, or cake myshell -c otherwhen invoking the shell.

Boolean switches do not accept or consume values, and their presence justenables them in the parsed parameters:

  1. $parser->addOption('no-commit', ['boolean' => true]);

This option when used like cake mycommand —no-commit something would havea value of true, and ‘something’ would be a treated as a positionalargument.

When creating options you can use the following options to define the behaviorof the option:

    • short - The single letter variant for this option, leave undefined for
    • none.
    • help - Help text for this option. Used when generating help for the
    • option.
    • default - The default value for this option. If not defined the default
    • will be true.
  • boolean - The option uses no value, it’s just a boolean switch.Defaults to false.
  • choices - An array of valid choices for this option. If left empty allvalues are valid. An exception will be raised when parse() encounters aninvalid value.

Adding Multiple Options

  • Cake\Console\ConsoleOptionParser::addOptions(array $options)
  • If you have an array with multiple options you can use $parser->addOptions()to add multiple options at once.
  1. $parser->addOptions([
  2. 'node' => ['short' => 'n', 'help' => 'The node to create'],
  3. 'parent' => ['short' => 'p', 'help' => 'The parent node']
  4. ]);

As with all the builder methods on ConsoleOptionParser, addOptions can be usedas part of a fluent method chain.

Option values are stored in the $this->params array. You can also use theconvenience method $this->param() to avoid errors when trying to accessnon-present options.

Validating Options

Options can be provided with a set of choices much like positional argumentscan be. When an option has defined choices, those are the only valid choicesfor an option. All other values will raise an InvalidArgumentException:

  1. $parser->addOption('accept', [
  2. 'help' => 'What version to accept.',
  3. 'choices' => ['working', 'theirs', 'mine']
  4. ]);

Using Boolean Options

Options can be defined as boolean options, which are useful when you need tocreate some flag options. Like options with defaults, boolean options alwaysinclude themselves into the parsed parameters. When the flags are present theyare set to true, when they are absent they are set to false:

  1. $parser->addOption('verbose', [
  2. 'help' => 'Enable verbose output.',
  3. 'boolean' => true
  4. ]);

The following option would always have a value in the parsed parameter. When notincluded its default value would be false, and when defined it will betrue.

Building a ConsoleOptionParser from an Array

  • Cake\Console\ConsoleOptionParser::buildFromArray($spec)
  • As previously mentioned, when creating subcommand option parsers, you can definethe parser spec as an array for that method. This can help make buildingsubcommand parsers easier, as everything is an array:
  1. $parser->addSubcommand('check', [
  2. 'help' => __('Check the permissions between an ACO and ARO.'),
  3. 'parser' => [
  4. 'description' => [
  5. __("Use this command to grant ACL permissions. Once executed, the "),
  6. __("ARO specified (and its children, if any) will have ALLOW access "),
  7. __("to the specified ACO action (and the ACO's children, if any).")
  8. ],
  9. 'arguments' => [
  10. 'aro' => ['help' => __('ARO to check.'), 'required' => true],
  11. 'aco' => ['help' => __('ACO to check.'), 'required' => true],
  12. 'action' => ['help' => __('Action to check')]
  13. ]
  14. ]
  15. ]);

Inside the parser spec, you can define keys for arguments, options,description and epilog. You cannot define subcommands inside anarray style builder. The values for arguments, and options, should follow theformat that Cake\Console\ConsoleOptionParser::addArguments() andCake\Console\ConsoleOptionParser::addOptions() use. You can alsouse buildFromArray on its own, to build an option parser:

  1. public function getOptionParser()
  2. {
  3. return ConsoleOptionParser::buildFromArray([
  4. 'description' => [
  5. __("Use this command to grant ACL permissions. Once executed, the "),
  6. __("ARO specified (and its children, if any) will have ALLOW access "),
  7. __("to the specified ACO action (and the ACO's children, if any).")
  8. ],
  9. 'arguments' => [
  10. 'aro' => ['help' => __('ARO to check.'), 'required' => true],
  11. 'aco' => ['help' => __('ACO to check.'), 'required' => true],
  12. 'action' => ['help' => __('Action to check')]
  13. ]
  14. ]);
  15. }

Merging Option Parsers

  • Cake\Console\ConsoleOptionParser::merge($spec)
  • When building a group command, you maybe want to combine several parsers forthis:
  1. $parser->merge($anotherParser);

Note that the order of arguments for each parser must be the same, and thatoptions must also be compatible for it work. So do not use keys for differentthings.

Getting Help from Shells

By defining your options and arguments with the option parser CakePHP canautomatically generate rudimentary help information and add a —help and-h to each of your commands. Using one of these options will allow you tosee the generated help content:

  1. bin/cake bake --help
  2. bin/cake bake -h

Would both generate the help for bake. You can also get help for nestedcommands:

  1. bin/cake bake model --help
  2. bin/cake bake model -h

The above would get you the help specific to bake’s model command.

Getting Help as XML

When building automated tools or development tools that need to interact withCakePHP shells, it’s nice to have help available in a machine parse-able format.By providing the xml option when requesting help you can have help contentreturned as XML:

  1. cake bake --help xml
  2. cake bake -h xml

The above would return an XML document with the generated help, options,arguments and subcommands for the selected shell. A sample XML document wouldlook like:

  1. <?xml version="1.0"?>
  2. <shell>
  3. <command>bake fixture</command>
  4. <description>Generate fixtures for use with the test suite. You can use
  5. `bake fixture all` to bake all fixtures.</description>
  6. <epilog>
  7. Omitting all arguments and options will enter into an interactive
  8. mode.
  9. </epilog>
  10. <options>
  11. <option name="--help" short="-h" boolean="1">
  12. <default/>
  13. <choices/>
  14. </option>
  15. <option name="--verbose" short="-v" boolean="1">
  16. <default/>
  17. <choices/>
  18. </option>
  19. <option name="--quiet" short="-q" boolean="1">
  20. <default/>
  21. <choices/>
  22. </option>
  23. <option name="--count" short="-n" boolean="">
  24. <default>10</default>
  25. <choices/>
  26. </option>
  27. <option name="--connection" short="-c" boolean="">
  28. <default>default</default>
  29. <choices/>
  30. </option>
  31. <option name="--plugin" short="-p" boolean="">
  32. <default/>
  33. <choices/>
  34. </option>
  35. <option name="--records" short="-r" boolean="1">
  36. <default/>
  37. <choices/>
  38. </option>
  39. </options>
  40. <arguments>
  41. <argument name="name" help="Name of the fixture to bake.
  42. Can use Plugin.name to bake plugin fixtures." required="">
  43. <choices/>
  44. </argument>
  45. </arguments>
  46. </shell>

Customizing Help Output

You can further enrich the generated help content by adding a description, andepilog.

Set the Description

  • Cake\Console\ConsoleOptionParser::setDescription($text)
  • The description displays above the argument and option information. By passingin either an array or a string, you can set the value of the description:
  1. // Set multiple lines at once
  2. $parser->setDescription(['line one', 'line two']);
  3. // Prior to 3.4
  4. $parser->description(['line one', 'line two']);
  5.  
  6. // Read the current value
  7. $parser->getDescription();

Set the Epilog

  • Cake\Console\ConsoleOptionParser::setEpilog($text)
  • Gets or sets the epilog for the option parser. The epilog is displayed after theargument and option information. By passing in either an array or a string, youcan set the value of the epilog:
  1. // Set multiple lines at once
  2. $parser->setEpilog(['line one', 'line two']);
  3. // Prior to 3.4
  4. $parser->epilog(['line one', 'line two']);
  5.  
  6. // Read the current value
  7. $parser->getEpilog();

Adding Subcommands

  • Cake\Console\ConsoleOptionParser::addSubcommand($name, $options = [])
  • Console applications are often made of subcommands, and these subcommands mayrequire special option parsing and have their own help. A perfect example ofthis is bake. Bake is made of many separate tasks that all have their ownhelp and options. ConsoleOptionParser allows you to define subcommands andprovide command specific option parsers so the shell knows how to parse commandsfor its tasks:
  1. $parser->addSubcommand('model', [
  2. 'help' => 'Bake a model',
  3. 'parser' => $this->Model->getOptionParser()
  4. ]);

The above is an example of how you could provide help and a specialized optionparser for a shell’s task. By calling the Task’s getOptionParser() we don’thave to duplicate the option parser generation, or mix concerns in our shell.Adding subcommands in this way has two advantages. First, it lets your shelldocument its subcommands in the generated help. It also gives easy access to thesubcommand help. With the above subcommand created you could callcake myshell —help and see the list of subcommands, and also runcake myshell model —help to view the help for just the model task.

Note

Once your Shell defines subcommands, all subcommands must be explicitlydefined.

When defining a subcommand you can use the following options:

  • help - Help text for the subcommand.
  • parser - A ConsoleOptionParser for the subcommand. This allows you tocreate method specific option parsers. When help is generated for asubcommand, if a parser is present it will be used. You can also supply theparser as an array that is compatible withCake\Console\ConsoleOptionParser::buildFromArray()
    Adding subcommands can be done as part of a fluent method chain.

Changed in version 3.5.0: When adding multi-word subcommands you can now invoke those commands usingsnake_case in addition to the camelBacked form.

Deprecated since version 3.6.0: Subcommands are deprecated. Instead use nested commands.