[Console] added a Process helper

This commit is contained in:
Fabien Potencier 2014-04-01 18:31:55 +02:00 committed by Romain Neutron
parent 8f0b984d76
commit faffe7e3a8
4 changed files with 178 additions and 0 deletions

View File

@ -5,11 +5,13 @@ CHANGELOG
-----
* deprecated the dialog helper (use the question helper instead)
* added a Process helper
* deprecated TableHelper in favor of Table
* deprecated ProgressHelper in favor of ProgressBar
* added a question helper
* added a way to set the process name of a command
* added a way to set a default command instead of `ListCommand`
* added a way to set the process title of a command
2.4.0
-----

View File

@ -0,0 +1,82 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Helper\Helper;
/**
* Helps outputting debug information when running an external program from a command.
*
* An external program can be a Process, an HTTP request, or anything else.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class DebugFormatterHelper extends Helper
{
private $colors = array('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white');
private $started = array();
private $count = -1;
public function start($id, $message, $prefix = 'RUN')
{
$this->started[$id] = array('border' => ++$this->count % count($this->colors));
return sprintf("%s<bg=blue;fg=white> %s </> <fg=blue>%s</>\n", $this->getBorder($id), $prefix, $message);
}
public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR')
{
$message = '';
if ($error) {
if (!isset($this->started[$id]['err'])) {
$message = sprintf("%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix);
$this->started[$id]['err'] = true;
}
$message .= str_replace("\n", sprintf("\n%s<bg=red;fg=white> %s </> ", $this->getBorder($id), $errorPrefix), $buffer);
} else {
if (!isset($this->started[$id]['out'])) {
$message = sprintf("%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix);
$this->started[$id]['out'] = true;
}
$message .= str_replace("\n", sprintf("\n%s<bg=green;fg=white> %s </> ", $this->getBorder($id), $prefix), $buffer);
}
return $message;
}
public function stop($id, $message, $successful, $prefix = 'RES')
{
$trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : '';
if ($successful) {
return sprintf("%s%s<bg=green;fg=white> %s </> <fg=green>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
}
return sprintf("%s%s<bg=red;fg=white> %s </> <fg=red>%s</>\n", $trailingEOL, $this->getBorder($id), $prefix, $message);
}
private function getBorder($id)
{
return sprintf('<bg=%s> </>', $this->colors[$this->started[$id]['border']]);
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'debug_formatter';
}
}

View File

@ -0,0 +1,93 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Helper\Helper;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;
/**
* The Process class provides helpers to run external processes.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class ProcessHelper extends Helper
{
/**
* Runs an external process.
*
* @param OutputInterface $output An OutputInterface instance
* @param string|Process $cmd An instance of Process or a command to run
* @param string|null $error An error message that must be displayed if something went wrong
* @param callback|null $callback A PHP callback to run whenever there is some
* output available on STDOUT or STDERR
*
* @return Process The process that ran
*/
public function run(OutputInterface $output, $cmd, $error = null, $callback = null)
{
$verbose = $output->getVerbosity() >= OutputInterface::VERBOSITY_VERY_VERBOSE;
$debug = $output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG;
$formatter = $this->getHelperSet()->get('debug_formatter');
$process = $cmd instanceof Process ? $cmd : new Process($cmd);
if ($verbose) {
$output->write($formatter->start(spl_object_hash($process), $process->getCommandLine()));
}
if ($debug) {
$callback = $this->wrapCallback($output, $process, $callback);
}
$process->run($callback);
if ($verbose) {
$message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run sucessfully', $process->getExitCode());
$output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful()));
}
if (!$process->isSuccessful() && null !== $error) {
$output->writeln(sprintf('<error>%s</error>'), $error);
}
return $process;
}
/**
* Wraps a Process callback to add debugging output.
*
* @param OutputInterface $output An OutputInterface interface
* @param callable|null $callback A PHP callable
*/
public function wrapCallback(OutputInterface $output, Process $process, $callback = null)
{
$formatter = $this->getHelperSet()->get('debug_formatter');
return function ($type, $buffer) use ($output, $process, $callback, $formatter) {
$output->write($formatter->progress(spl_object_hash($process), $buffer, 'err' === $type));
if (null !== $callback) {
$callback($type, $buffer);
}
};
}
/**
* {@inheritDoc}
*/
public function getName()
{
return 'process';
}
}

View File

@ -24,6 +24,7 @@
},
"suggest": {
"symfony/event-dispatcher": "",
"symfony/process": "",
"psr/log": "For using the console logger"
},
"autoload": {