feature #16906 [Console] Better support for one command app (lyrixx)

This PR was merged into the 3.2-dev branch.

Discussion
----------

[Console] Better support for one command app

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #9564
| License       | MIT

Hello;

I write many CLI application, and "single command" in cli application is not so easy to write.
This is why I propose this patch. IMHO, this PR could replaces #9609.

See it in application:
```php
#!/usr/bin/env php
<?php

require __DIR__.'/vendor/autoload.php';

use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

(new Application('echo', '1.0.0'))
    ->register('echo')
        ->addArgument('foo', InputArgument::OPTIONAL, 'The directory', 'foo')
        ->addOption('bar', null, InputOption::VALUE_REQUIRED, 'Foobar', 'bar')
        ->setCode(function(InputInterface $input, OutputInterface $output) {
            $output->writeln('start');
            $output->writeln($input->getArgument('foo'));
            $output->writeln($input->getOption('bar'));
        })
    ->getApplication()
    ->setSingleCommand('echo')
    ->run();
```

Some usage:
```
>(3)[{..}eg/dev/github.com/symfony/symfony](console-one-app) php test.php
start
foo
bar
```
```
>(3)[{..}eg/dev/github.com/symfony/symfony](console-one-app) php test.php  "first argument"
start
first argument
bar
```
```
>(3)[{..}eg/dev/github.com/symfony/symfony](console-one-app) php test.php  "first argument" --bar="first option"
start
first argument
first option
```
```
>(3)[{..}eg/dev/github.com/symfony/symfony](console-one-app) php test.php  "first argument" --bar="first option" --help
Usage:
  echo [options] [--] [<foo>]

Arguments:
  foo                   The directory [default: "foo"]

Options:
      --bar=BAR         Foobar [default: "bar"]
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
```

Commits
-------

4a9bb1d [Console] Better support for one command app
This commit is contained in:
Fabien Potencier 2016-06-15 18:17:41 +02:00
commit 1ab32c5642
3 changed files with 55 additions and 21 deletions

View File

@ -66,6 +66,7 @@ class Application
private $dispatcher;
private $terminalDimensions;
private $defaultCommand;
private $singleCommand;
/**
* Constructor.
@ -168,7 +169,7 @@ class Application
if (true === $input->hasParameterOption(array('--help', '-h'), true)) {
if (!$name) {
$name = 'help';
$input = new ArrayInput(array('command' => 'help'));
$input = new ArrayInput(array('command_name' => $this->defaultCommand));
} else {
$this->wantHelps = true;
}
@ -226,6 +227,13 @@ class Application
*/
public function getDefinition()
{
if ($this->singleCommand) {
$inputDefinition = $this->definition;
$inputDefinition->setArguments();
return $inputDefinition;
}
return $this->definition;
}
@ -859,7 +867,7 @@ class Application
*/
protected function getCommandName(InputInterface $input)
{
return $input->getFirstArgument();
return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument();
}
/**
@ -1039,11 +1047,21 @@ class Application
/**
* Sets the default Command name.
*
* @param string $commandName The Command name
* @param string $commandName The Command name
* @param bool $isSingleCommand Set to true if there is only one command in this application
*/
public function setDefaultCommand($commandName)
public function setDefaultCommand($commandName, $isSingleCommand = false)
{
$this->defaultCommand = $commandName;
if ($isSingleCommand) {
// Ensure the command exist
$this->find($commandName);
$this->singleCommand = true;
}
return $this;
}
private function stringWidth($string)

View File

@ -1086,6 +1086,24 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('interact called'.PHP_EOL.'called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command');
}
public function testSetRunCustomSingleCommand()
{
$command = new \FooCommand();
$application = new Application();
$application->setAutoExit(false);
$application->add($command);
$application->setDefaultCommand($command->getName(), true);
$tester = new ApplicationTester($application);
$tester->run(array());
$this->assertContains('called', $tester->getDisplay());
$tester->run(array('--help' => true));
$this->assertContains('The foo:bar command', $tester->getDisplay());
}
/**
* @requires function posix_isatty
*/

View File

@ -1,28 +1,26 @@
Usage:
help [options] [--] [<command_name>]
list [options] [--] [<namespace>]
Arguments:
command The command to execute
command_name The command name [default: "help"]
namespace The namespace name
Options:
--format=FORMAT The output format (txt, xml, json, or md) [default: "txt"]
--raw To output raw command help
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
--raw To output raw command list
--format=FORMAT The output format (txt, xml, json, or md) [default: "txt"]
Help:
The help command displays help for a given command:
The list command lists all commands:
php app/console help list
php app/console list
You can also output the help in other formats by using the --format option:
You can also display the commands for a specific namespace:
php app/console help --format=xml list
php app/console list test
To display the list of available commands, please use the list command.
You can also output the information in other formats by using the --format option:
php app/console list --format=xml
It's also possible to get raw list of commands (useful for embedding command runner):
php app/console list --raw