diff --git a/CHANGELOG-2.1.md b/CHANGELOG-2.1.md index 0111cf2ade..fba86109c4 100644 --- a/CHANGELOG-2.1.md +++ b/CHANGELOG-2.1.md @@ -162,6 +162,10 @@ To get the diff between two versions, go to https://github.com/symfony/symfony/c * added Locale::getIcuVersion() and Locale::getIcuDataVersion() +### Process + + * added ProcessBuilder + ### Routing * added a TraceableUrlMatcher diff --git a/src/Symfony/Component/Process/ProcessBuilder.php b/src/Symfony/Component/Process/ProcessBuilder.php new file mode 100644 index 0000000000..90dad5ad41 --- /dev/null +++ b/src/Symfony/Component/Process/ProcessBuilder.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Process; + +/** + * Process builder. + * + * @author Kris Wallsmith + */ +class ProcessBuilder +{ + private $arguments; + private $cwd; + private $env; + private $stdin; + private $timeout; + private $options; + private $inheritEnv; + + public function __construct(array $arguments = array()) + { + $this->arguments = $arguments; + + $this->timeout = 60; + $this->options = array(); + $this->inheritEnv = false; + } + + /** + * Adds an unescaped argument to the command string. + * + * @param string $argument A command argument + */ + public function add($argument) + { + $this->arguments[] = $argument; + + return $this; + } + + public function setWorkingDirectory($cwd) + { + $this->cwd = $cwd; + + return $this; + } + + public function inheritEnvironmentVariables($inheritEnv = true) + { + $this->inheritEnv = $inheritEnv; + + return $this; + } + + public function setEnv($name, $value) + { + if (null === $this->env) { + $this->env = array(); + } + + $this->env[$name] = $value; + + return $this; + } + + public function setInput($stdin) + { + $this->stdin = $stdin; + + return $this; + } + + public function setTimeout($timeout) + { + $this->timeout = $timeout; + + return $this; + } + + public function setOption($name, $value) + { + $this->options[$name] = $value; + + return $this; + } + + public function getProcess() + { + if (!count($this->arguments)) { + throw new \LogicException('You must add() command arguments before calling getProcess().'); + } + + $options = $this->options; + + if (defined('PHP_WINDOWS_VERSION_MAJOR')) { + $options['bypass_shell'] = true; + + $arguments = $this->arguments; + $command = array_shift($arguments); + + $script = '"'.$command.'"'; + if ($arguments) { + $script .= ' '.implode(' ', array_map('escapeshellarg', $arguments)); + } + + $script = 'cmd /V:ON /E:ON /C "'.$script.'"'; + } else { + $script = implode(' ', array_map('escapeshellarg', $this->arguments)); + } + + $env = $this->inheritEnv && $_ENV ? ($this->env ?: array()) + $_ENV : $this->env; + + return new Process($script, $this->cwd, $env, $this->stdin, $this->timeout, $options); + } +} diff --git a/tests/Symfony/Tests/Component/Process/ProcessBuilderTest.php b/tests/Symfony/Tests/Component/Process/ProcessBuilderTest.php new file mode 100644 index 0000000000..56a15d3fba --- /dev/null +++ b/tests/Symfony/Tests/Component/Process/ProcessBuilderTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Tests\Component\Process; + +use Symfony\Component\Process\ProcessBuilder; + +class ProcessBuilderTest extends \PHPUnit_Framework_TestCase +{ + /** + * @test + */ + public function shouldInheritEnvironmentVars() + { + $snapshot = $_ENV; + $_ENV = $expected = array('foo' => 'bar'); + + $pb = new ProcessBuilder(); + $pb->add('foo')->inheritEnvironmentVariables(); + $proc = $pb->getProcess(); + + $this->assertEquals($expected, $proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } + + /** + * @test + */ + public function shouldNotReplaceExplicitlySetVars() + { + $snapshot = $_ENV; + $_ENV = array('foo' => 'bar'); + $expected = array('foo' => 'baz'); + + $pb = new ProcessBuilder(); + $pb + ->setEnv('foo', 'baz') + ->inheritEnvironmentVariables() + ->add('foo') + ; + $proc = $pb->getProcess(); + + $this->assertEquals($expected, $proc->getEnv(), '->inheritEnvironmentVariables() copies $_ENV'); + + $_ENV = $snapshot; + } +}