Skip to content
Browse files

[Console] added a Process helper

  • Loading branch information...
1 parent 8f0b984 commit faffe7e3a8a832580aa8090ba73b7c77f680fb54 @fabpot fabpot committed with romainneutron Apr 1, 2014
View
2 src/Symfony/Component/Console/CHANGELOG.md
@@ -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
82 src/Symfony/Component/Console/Helper/DebugFormatterHelper.php
@@ -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
93 src/Symfony/Component/Console/Helper/ProcessHelper.php
@@ -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
1 src/Symfony/Component/Console/composer.json
@@ -24,6 +24,7 @@
},
"suggest": {
"symfony/event-dispatcher": "",
+ "symfony/process": "",
"psr/log": "For using the console logger"
},
"autoload": {

0 comments on commit faffe7e

Please sign in to comment.
Something went wrong with that request. Please try again.