8000 [Console] Add --markdown export to HelpCommand by zczapran · Pull Request #6339 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Console] Add --markdown export to HelpCommand #6339

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

There are no files selected for viewing

96 changes: 91 additions & 5 deletions src/Symfony/Component/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,34 @@ public function getHelp()
return implode(PHP_EOL, $messages);
}

/**
* Gets the help message in Markdown.
*
* @return string A help message in Markdown.
*/
public function getHelpInMarkdown()
{
$messages = array(
$this->getLongVersionInMarkdown(),
'',
'Usage',
'-----',
sprintf(" [options] command [arguments]\n"),
'Options',
'-------'
);

foreach ($this->getDefinition()->getOptions() as $option) {
$messages[] = sprintf(' %-16s %s %s',
'--'.$option->getName(),
$option->getShortcut() ? '(-'.$option->getShortcut().')' : ' ',
$option->getDescription()
);
}

return implode(PHP_EOL, $messages);
}

/**
* Sets whether to catch exceptions or not during commands execution.
*
Expand Down Expand Up @@ -356,6 +384,22 @@ public function getLongVersion()
return '<info>Console Tool</info>';
}

/**
* Returns the long version of the application in Markdown.
*
* @return string The long application version in Markdown
*
* @api
*/
public function getLongVersionInMarkdown()
{
if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {
return sprintf('%s version %s', $this->getName(), $this->getVersion());
}

return implode(PHP_EOL, array('Console Tool', '============'));
}

/**
* Registers a new command.
*
Expand Down Expand Up @@ -680,11 +724,7 @@ public function asText($namespace = null, $raw = false)
{
$commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;

$width = 0;
foreach ($commands as $command) {
$width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
}
$width += 2;
$width = $this->getMaximumCommandNameLength($commands) + 2;

if ($raw) {
$messages = array();
Expand Down Expand Up @@ -718,6 +758,43 @@ public function asText($namespace = null, $raw = false)
return implode(PHP_EOL, $messages);
}

/**
* Returns Markdown representation of the Application.
*
* @param string $namespace An optional namespace name
*
* @return string Markdown representing the Application
*/
public function asMarkdown($namespace = null)
{
$commands = $namespace ? $this->all($this->findNamespace($namespace)) : $this->commands;

$width = $this->getMaximumCommandNameLength($commands) + 2;

$messages = array($this->getHelpInMarkdown(), '');
if ($namespace) {
$message = sprintf("Available commands for the \"%s\" namespace", $namespace);
$messages[] = $message;
$messages[] = str_repeat('-', mb_strlen($message));
} else {
$messages[] = 'Available commands';
$messages[] = '------------------';
}

// add commands by namespace
foreach ($this->sortCommands($commands) as $space => $commands) {
if (!$namespace && '_global' !== $space) {
$messages[] = '';
}

foreach ($commands as $name => $command) {
$messages[] = sprintf(" %-${width}s %s", $name, $command->getDescription());
}
}

return implode(PHP_EOL, $messages);
}

/**
* Returns an XML representation of the Application.
*
Expand Down Expand Up @@ -954,6 +1031,15 @@ protected function getDefaultHelperSet()
));
}

private function getMaximumCommandNameLength(array $commands) {
$width = 0;
foreach ($commands as $command) {
$width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;
}

return $width;
}

/**
* Runs and parses stty -a if it's available, suppressing any error output
*
Expand Down
42 changes: 42 additions & 0 deletions src/Symfony/Component/Console/Command/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,48 @@ public function asText()
return implode("\n", $messages);
}

/**
* Returns Markdown representation of the command.
*
* @return string Markdown representing the command
*/
public function asMarkdown()
{
if ($this->application && !$this->applicationDefinitionMerged) {
$this->getSynopsis();
$this->mergeApplicationDefinition(false);
}

$markdown = array();
$markdown[] = $this->name;
$markdown[] = \str_repeat('=', mb_strlen($this->name));
$markdown[] = '';
$markdown[] = $this->description;
$markdown[] = '';
$markdown[] = 'Usage';
$markdown[] = '-----';
$markdown[] = ' '.$this->getSynopsis();
$markdown[] = '';

if ($this->getAliases()) {
$markdown[] = 'Aliases';
$markdown[] = '-------';
foreach ($this->getAliases() as $alias) {
$markdown[] = '* '.$alias;
}
$markdown[] = '';
}

$markdown[] = $this->getNativeDefinition()->asMarkdown();
if ($help = $this->getProcessedHelp()) {
$markdown[] = 'Help';
$markdown[] = '----';
$markdown[] = ' '.strip_tags(str_replace("\n", "\n ", $help))."\n";
}

return implode("\n", $markdown);
}

/**
* Returns an XML representation of the command.
*
Expand Down
3 changes: 3 additions & 0 deletions src/Symfony/Component/Console/Command/HelpCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ protected function configure()
->setName('help')
->setDefinition(array(
new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),
new InputOption('markdown', null, InputOption::VALUE_NONE, 'To output help as Markdown'),
new InputOption('xml', null, InputOption::VALUE_NONE, 'To output help as XML'),
))
->setDescription('Displays help for a command')
Expand Down Expand Up @@ -76,6 +77,8 @@ protected function execute(InputInterface $input, OutputInterface $output)

if ($input->getOption('xml')) {
$output->writeln($this->command->asXml(), OutputInterface::OUTPUT_RAW);
} elseif ($input->getOption('markdown')) {
$output->writeln($this->command->asMarkdown(), OutputInterface::OUTPUT_RAW);
} else {
$output->writeln($this->command->asText());
}
Expand Down
94 changes: 80 additions & 14 deletions src/Symfony/Component/Console/Input/InputDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -407,20 +407,7 @@ public function getSynopsis()
*/
public function asText()
{
// find the largest option or argument name
$max = 0;
foreach ($this->getOptions() as $option) {
$nameLength = strlen($option->getName()) + 2;
if ($option->getShortcut()) {
$nameLength += strlen($option->getShortcut()) + 3;
}

$max = max($max, $nameLength);
}
foreach ($this->getArguments() as $argument) {
$max = max($max, strlen($argument->getName()));
}
++$max;
$max = $this->getMaximumOptionOrArgumentNameLength() + 1;

$text = array();

Expand Down Expand Up @@ -470,6 +457,61 @@ public function asText()
return implode("\n", $text);
}

/**
* Returns Markdown representation of the InputDefinition.
*
* @return string Markdown string representing the InputDefinition
*/
public function asMarkdown()
{
$max = $this->getMaximumOptionOrArgumentNameLength() + 1;

$markdown = array();
if ($this->getArguments()) {
$markdown[] = 'Arguments';
$markdown[] = '---------';
foreach ($this->getArguments() as $argument) {
if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) {
$default = sprintf(' (default: %s)', $this->formatDefaultValue($argument->getDefault()));
} else {
$default = '';
}

$description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $argument->getDescription());

$markdown[] = sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default);
}
$markdown[] = '';
}

if ($this->getOptions()) {
$markdown[] = 'Options';
$markdown[] = '-------';
foreach ($this->getOptions() as $option) {
if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) {
$default = sprintf(' (default: %s)', $this->formatDefaultValue($option->getDefault()));
} else {
$default = '';
}

$multiple = $option->isArray() ? ' (multiple values allowed)' : '';
$description = str_replace("\n", "\n".str_pad('', $max + 2, ' '), $option->getDescription());

$optionMax = $max - strlen($option->getName()) - 2;
$markdown[] = sprintf(" %s %-${optionMax}s%s%s%s",
'--'.$option->getName(),
$option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '',
$description,
$default,
$multiple
);
}
$markdown[] = '';
}

return implode("\n", $markdown);
}

/**
* Returns an XML representation of the InputDefinition.
*
Expand Down Expand Up @@ -524,6 +566,30 @@ public function asXml($asDom = false)
return $asDom ? $dom : $dom->saveXml();
}

/**
* Finds the longest option or argument name and returns its length.
*
* @return integer Length of the longest option or argument name
*/
private function getMaximumOptionOrArgumentNameLength()
{
// find the largest option or argument name
$max = 0;
foreach ($this->getOptions() as $option) {
$nameLength = strlen($option->getName()) + 2;
if ($option->getShortcut()) {
$nameLength += strlen($option->getShortcut()) + 3;
}

$max = max($max, $nameLength);
}
foreach ($this->getArguments() as $argument) {
$max = max($max, strlen($argument->getName()));
}

return $max;
}

private function formatDefaultValue($default)
{
if (version_compare(PHP_VERSION, '5.4', '<')) {
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Component/Console/Tests/ApplicationTest.php
10000
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,15 @@ public function testAsText()
$this->assertStringEqualsFile(self::$fixturesPath.'/application_astext2.txt', $this->normalizeLineBreaks($application->asText('foo')), '->asText() returns a text representation of the application');
}

public function testAsMarkdown()
{
$application = new Application();
$application->add(new \FooCommand);
$this->ensureStaticCommandHelp($application);
$this->assertStringEqualsFile(self::$fixturesPath.'/application_asmarkdown1.txt', $application->asMarkdown(), '->asMarkdown() returns Markdown representation of the application');
$this->assertStringEqualsFile(self::$fixturesPath.'/application_asmarkdown2.txt', $application->asMarkdown('foo'), '->asMarkdown() returns Markdown representation of the application');
}

public function testAsXml()
{
$application = new Application();
Expand Down
9 changes: 9 additions & 0 deletions src/Symfony/Component/Console/Tests/Command/CommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,15 @@ public function testAsText()
$this->assertStringEqualsFile(self::$fixturesPath.'/command_astext.txt', $command->asText(), '->asText() returns a text representation of the command');
}

public function testAsMarkdown()
{
$command = new \TestCommand();
$command->setApplication(new Application());
$tester = new CommandTester($command);
$tester->execute(array('command' => $command->getName()));
$this->assertStringEqualsFile(self::$fixturesPath.'/command_asmarkdown.txt', $command->asMarkdown(), '->asMarkdown() returns Markdown representation of the command');
}

public function testAsXml()
{
$command = new \TestCommand();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Console Tool
============

Usage
-----
[options] command [arguments]

Options
-------
--help (-h) Display this help message.
--quiet (-q) Do not output any message.
--verbose (-v) Increase verbosity of messages.
--version (-V) Display this application version.
--ansi Force ANSI output.
--no-ansi Disable ANSI output.
--no-interaction (-n) Do not ask any interactive question.

Available commands
------------------
afoobar The foo:bar command
help Displays help for a command
list Lists commands

foo:bar The foo:bar command
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Console Tool
============

Usage
-----
[options] command [arguments]

Options
-------
--help (-h) Display this help message.
--quiet (-q) Do not output any message.
--verbose (-v) Increase verbosity of messages.
--version (-V) Display this application version.
--ansi Force ANSI output.
--no-ansi Disable ANSI output.
--no-interaction (-n) Do not ask any interactive question.

Available commands for the "foo" namespace
------------------------------------------
foo:bar The foo:bar command
Loading
0