summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--2974291-symfony-process.patch6339
1 files changed, 0 insertions, 6339 deletions
diff --git a/2974291-symfony-process.patch b/2974291-symfony-process.patch
deleted file mode 100644
index 47cee8b..0000000
--- a/2974291-symfony-process.patch
+++ /dev/null
@@ -1,6339 +0,0 @@
-diff --git a/composer.json b/composer.json
-index 938c3582..612735d4 100644
---- a/composer.json
-+++ b/composer.json
-@@ -13,7 +13,9 @@
- "issues": "https://www.drupal.org/project/issues/provision",
- "docs": "http://docs.aegirproject.org/"
- },
-- "require": {},
-+ "require": {
-+ "symfony/process": "^3.3"
-+ },
- "config": {
- "sort-packages": true,
- "platform": {
-diff --git a/composer.lock b/composer.lock
-new file mode 100644
-index 00000000..ff81d077
---- /dev/null
-+++ b/composer.lock
-@@ -0,0 +1,70 @@
-+{
-+ "_readme": [
-+ "This file locks the dependencies of your project to a known state",
-+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
-+ "This file is @generated automatically"
-+ ],
-+ "content-hash": "c6615761b64ee98b0ecc471fd193dd04",
-+ "packages": [
-+ {
-+ "name": "symfony/process",
-+ "version": "v3.3.6",
-+ "source": {
-+ "type": "git",
-+ "url": "https://github.com/symfony/process.git",
-+ "reference": "07432804942b9f6dd7b7377faf9920af5f95d70a"
-+ },
-+ "dist": {
-+ "type": "zip",
-+ "url": "https://api.github.com/repos/symfony/process/zipball/07432804942b9f6dd7b7377faf9920af5f95d70a",
-+ "reference": "07432804942b9f6dd7b7377faf9920af5f95d70a",
-+ "shasum": ""
-+ },
-+ "require": {
-+ "php": ">=5.5.9"
-+ },
-+ "type": "library",
-+ "extra": {
-+ "branch-alias": {
-+ "dev-master": "3.3-dev"
-+ }
-+ },
-+ "autoload": {
-+ "psr-4": {
-+ "Symfony\\Component\\Process\\": ""
-+ },
-+ "exclude-from-classmap": [
-+ "/Tests/"
-+ ]
-+ },
-+ "notification-url": "https://packagist.org/downloads/",
-+ "license": [
-+ "MIT"
-+ ],
-+ "authors": [
-+ {
-+ "name": "Fabien Potencier",
-+ "email": "fabien@symfony.com"
-+ },
-+ {
-+ "name": "Symfony Community",
-+ "homepage": "https://symfony.com/contributors"
-+ }
-+ ],
-+ "description": "Symfony Process Component",
-+ "homepage": "https://symfony.com",
-+ "time": "2017-07-13T13:05:09+00:00"
-+ }
-+ ],
-+ "packages-dev": [],
-+ "aliases": [],
-+ "minimum-stability": "dev",
-+ "stability-flags": [],
-+ "prefer-stable": true,
-+ "prefer-lowest": false,
-+ "platform": [],
-+ "platform-dev": [],
-+ "platform-overrides": {
-+ "php": "7.0"
-+ }
-+}
-diff --git a/platform/verify.provision.inc b/platform/verify.provision.inc
-index 9d140d25..e2a0e4e9 100644
---- a/platform/verify.provision.inc
-+++ b/platform/verify.provision.inc
-@@ -104,31 +104,10 @@ function drush_provision_drupal_pre_provision_verify() {
- // Composer Install command: Do not interact, do not show download progress.
- // Customizable by setting drush option 'provision_composer_install_command'
- $composer_command = drush_get_option('provision_composer_install_command', 'composer install --no-interaction --no-progress --no-dev');
-- drush_log(dt("Running command @command", array(
-- '@command' => $composer_command
-- )), 'ok');
-- $start = time();
--
-- // @TODO: Implement Symfony Process component for line-by-line output logging.
-- if (drush_shell_cd_and_exec($composer_directory, $composer_command)) {
-- $stop = time();
--
-- $output = implode("\n", drush_shell_exec_output());
-- $log_status = strpos($output, 'Warning:') === FALSE? 'success': 'warning';
--
-- drush_log($output, $log_status);
-- drush_log(dt(strpos($output, 'Warning:') . "Command ran successfully in @times: @command", array(
-- '@command' => $composer_command,
-- '@time' => $stop - $start,
-- )), $log_status);
-- }
-- else {
-- drush_log(implode("\n", drush_shell_exec_output()), 'error');
-- drush_set_error('DRUSH_COMPOSER_ERROR', dt('The composer command failed in @dir: @command', array(
-- '@dir' => $composer_directory,
-- '@command' => $composer_command,
-- )));
-- }
-+
-+
-+ // Implement Symfony Process component for line-by-line output logging.
-+ provision_process($composer_command, $composer_directory);
- }
- }
-
-diff --git a/provision.inc b/provision.inc
-index ceaed059..b64d30e7 100644
---- a/provision.inc
-+++ b/provision.inc
-@@ -433,6 +433,46 @@ function provision_backend_invoke($target, $command, $arguments = array(), $data
- }
-
- /**
-+ * Run a Symfony Process saving to drush logs.
-+ */
-+function provision_process($command, $cwd = null, $label = 'Process', $env = array(), $log_output = TRUE, $error_message = 'Process Failed') {
-+ drush_log("[$label] $command", 'p_command');
-+
-+ // Merge in env vars, inheriting the CLI's
-+ if (is_array($env)) {
-+ $env = array_merge($_SERVER, $env);
-+ }
-+ else {
-+ $env = $_SERVER;
-+ }
-+
-+ // Make sure colors always come through
-+ $env['TERM'] = 'xterm';
-+
-+ $process = new \Symfony\Component\Process\Process(escapeshellcmd($command), $cwd, $env);
-+ $process->setTimeout(NULL);
-+ if ($log_output) {
-+ $exit_code = $process->run(function ($type, $buffer) {
-+ drush_log($buffer, 'p_info');
-+ });
-+ }
-+ else {
-+ $exit_code = $process->run();
-+ }
-+
-+ // check exit code
-+ if ($exit_code === 0) {
-+ drush_log('', 'p_ok');
-+ return $process->getOutput();
-+ }
-+ else {
-+ drush_log('', 'p_error');
-+ drush_set_error('PROVISION_PROCESS_ERROR', dt($error_message));
-+ return $process->getErrorOutput();
-+ }
-+}
-+
-+/**
- * the aegir version of the backend
- *
- * @return string
-diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php
-index 2c72175e..95f7e097 100644
---- a/vendor/composer/ClassLoader.php
-+++ b/vendor/composer/ClassLoader.php
-@@ -377,11 +377,11 @@ class ClassLoader
- $subPath = $class;
- while (false !== $lastPos = strrpos($subPath, '\\')) {
- $subPath = substr($subPath, 0, $lastPos);
-- $search = $subPath.'\\';
-+ $search = $subPath . '\\';
- if (isset($this->prefixDirsPsr4[$search])) {
-+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
- foreach ($this->prefixDirsPsr4[$search] as $dir) {
-- $length = $this->prefixLengthsPsr4[$first][$search];
-- if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
-+ if (file_exists($file = $dir . $pathEnd)) {
- return $file;
- }
- }
-diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
-index b265c64a..8ae063a7 100644
---- a/vendor/composer/autoload_psr4.php
-+++ b/vendor/composer/autoload_psr4.php
-@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
- $baseDir = dirname($vendorDir);
-
- return array(
-+ 'Symfony\\Component\\Process\\' => array($vendorDir . '/symfony/process'),
- );
-diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
-index 8f98a329..db03ac48 100644
---- a/vendor/composer/autoload_static.php
-+++ b/vendor/composer/autoload_static.php
-@@ -6,6 +6,20 @@ namespace Composer\Autoload;
-
- class ComposerStaticInit93ce438f8ce8708ef24439d2070dee06
- {
-+ public static $prefixLengthsPsr4 = array (
-+ 'S' =>
-+ array (
-+ 'Symfony\\Component\\Process\\' => 26,
-+ ),
-+ );
-+
-+ public static $prefixDirsPsr4 = array (
-+ 'Symfony\\Component\\Process\\' =>
-+ array (
-+ 0 => __DIR__ . '/..' . '/symfony/process',
-+ ),
-+ );
-+
- public static $prefixesPsr0 = array (
- 'P' =>
- array (
-@@ -19,6 +33,8 @@ class ComposerStaticInit93ce438f8ce8708ef24439d2070dee06
- public static function getInitializer(ClassLoader $loader)
- {
- return \Closure::bind(function () use ($loader) {
-+ $loader->prefixLengthsPsr4 = ComposerStaticInit93ce438f8ce8708ef24439d2070dee06::$prefixLengthsPsr4;
-+ $loader->prefixDirsPsr4 = ComposerStaticInit93ce438f8ce8708ef24439d2070dee06::$prefixDirsPsr4;
- $loader->prefixesPsr0 = ComposerStaticInit93ce438f8ce8708ef24439d2070dee06::$prefixesPsr0;
-
- }, null, ClassLoader::class);
-diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
-index fe51488c..289474b4 100644
---- a/vendor/composer/installed.json
-+++ b/vendor/composer/installed.json
-@@ -1 +1,53 @@
--[]
-+[
-+ {
-+ "name": "symfony/process",
-+ "version": "v3.3.6",
-+ "version_normalized": "3.3.6.0",
-+ "source": {
-+ "type": "git",
-+ "url": "https://github.com/symfony/process.git",
-+ "reference": "07432804942b9f6dd7b7377faf9920af5f95d70a"
-+ },
-+ "dist": {
-+ "type": "zip",
-+ "url": "https://api.github.com/repos/symfony/process/zipball/07432804942b9f6dd7b7377faf9920af5f95d70a",
-+ "reference": "07432804942b9f6dd7b7377faf9920af5f95d70a",
-+ "shasum": ""
-+ },
-+ "require": {
-+ "php": ">=5.5.9"
-+ },
-+ "time": "2017-07-13T13:05:09+00:00",
-+ "type": "library",
-+ "extra": {
-+ "branch-alias": {
-+ "dev-master": "3.3-dev"
-+ }
-+ },
-+ "installation-source": "dist",
-+ "autoload": {
-+ "psr-4": {
-+ "Symfony\\Component\\Process\\": ""
-+ },
-+ "exclude-from-classmap": [
-+ "/Tests/"
-+ ]
-+ },
-+ "notification-url": "https://packagist.org/downloads/",
-+ "license": [
-+ "MIT"
-+ ],
-+ "authors": [
-+ {
-+ "name": "Fabien Potencier",
-+ "email": "fabien@symfony.com"
-+ },
-+ {
-+ "name": "Symfony Community",
-+ "homepage": "https://symfony.com/contributors"
-+ }
-+ ],
-+ "description": "Symfony Process Component",
-+ "homepage": "https://symfony.com"
-+ }
-+]
-diff --git a/vendor/symfony/process/.gitignore b/vendor/symfony/process/.gitignore
-new file mode 100644
-index 00000000..c49a5d8d
---- /dev/null
-+++ b/vendor/symfony/process/.gitignore
-@@ -0,0 +1,3 @@
-+vendor/
-+composer.lock
-+phpunit.xml
-diff --git a/vendor/symfony/process/CHANGELOG.md b/vendor/symfony/process/CHANGELOG.md
-new file mode 100644
-index 00000000..bb719be7
---- /dev/null
-+++ b/vendor/symfony/process/CHANGELOG.md
-@@ -0,0 +1,51 @@
-+CHANGELOG
-+=========
-+
-+3.3.0
-+-----
-+
-+ * added command line arrays in the `Process` class
-+ * added `$env` argument to `Process::start()`, `run()`, `mustRun()` and `restart()` methods
-+ * deprecated the `ProcessUtils::escapeArgument()` method
-+ * deprecated not inheriting environment variables
-+ * deprecated configuring `proc_open()` options
-+ * deprecated configuring enhanced Windows compatibility
-+ * deprecated configuring enhanced sigchild compatibility
-+
-+2.5.0
-+-----
-+
-+ * added support for PTY mode
-+ * added the convenience method "mustRun"
-+ * deprecation: Process::setStdin() is deprecated in favor of Process::setInput()
-+ * deprecation: Process::getStdin() is deprecated in favor of Process::getInput()
-+ * deprecation: Process::setInput() and ProcessBuilder::setInput() do not accept non-scalar types
-+
-+2.4.0
-+-----
-+
-+ * added the ability to define an idle timeout
-+
-+2.3.0
-+-----
-+
-+ * added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows
-+ * added Process::signal()
-+ * added Process::getPid()
-+ * added support for a TTY mode
-+
-+2.2.0
-+-----
-+
-+ * added ProcessBuilder::setArguments() to reset the arguments on a builder
-+ * added a way to retrieve the standard and error output incrementally
-+ * added Process:restart()
-+
-+2.1.0
-+-----
-+
-+ * added support for non-blocking processes (start(), wait(), isRunning(), stop())
-+ * enhanced Windows compatibility
-+ * added Process::getExitCodeText() that returns a string representation for
-+ the exit code returned by the process
-+ * added ProcessBuilder
-diff --git a/vendor/symfony/process/Exception/ExceptionInterface.php b/vendor/symfony/process/Exception/ExceptionInterface.php
-new file mode 100644
-index 00000000..75c1c9e5
---- /dev/null
-+++ b/vendor/symfony/process/Exception/ExceptionInterface.php
-@@ -0,0 +1,21 @@
-+<?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\Process\Exception;
-+
-+/**
-+ * Marker Interface for the Process Component.
-+ *
-+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
-+ */
-+interface ExceptionInterface
-+{
-+}
-diff --git a/vendor/symfony/process/Exception/InvalidArgumentException.php b/vendor/symfony/process/Exception/InvalidArgumentException.php
-new file mode 100644
-index 00000000..926ee211
---- /dev/null
-+++ b/vendor/symfony/process/Exception/InvalidArgumentException.php
-@@ -0,0 +1,21 @@
-+<?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\Process\Exception;
-+
-+/**
-+ * InvalidArgumentException for the Process Component.
-+ *
-+ * @author Romain Neutron <imprec@gmail.com>
-+ */
-+class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
-+{
-+}
-diff --git a/vendor/symfony/process/Exception/LogicException.php b/vendor/symfony/process/Exception/LogicException.php
-new file mode 100644
-index 00000000..be3d490d
---- /dev/null
-+++ b/vendor/symfony/process/Exception/LogicException.php
-@@ -0,0 +1,21 @@
-+<?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\Process\Exception;
-+
-+/**
-+ * LogicException for the Process Component.
-+ *
-+ * @author Romain Neutron <imprec@gmail.com>
-+ */
-+class LogicException extends \LogicException implements ExceptionInterface
-+{
-+}
-diff --git a/vendor/symfony/process/Exception/ProcessFailedException.php b/vendor/symfony/process/Exception/ProcessFailedException.php
-new file mode 100644
-index 00000000..328acfde
---- /dev/null
-+++ b/vendor/symfony/process/Exception/ProcessFailedException.php
-@@ -0,0 +1,54 @@
-+<?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\Process\Exception;
-+
-+use Symfony\Component\Process\Process;
-+
-+/**
-+ * Exception for failed processes.
-+ *
-+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
-+ */
-+class ProcessFailedException extends RuntimeException
-+{
-+ private $process;
-+
-+ public function __construct(Process $process)
-+ {
-+ if ($process->isSuccessful()) {
-+ throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
-+ }
-+
-+ $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
-+ $process->getCommandLine(),
-+ $process->getExitCode(),
-+ $process->getExitCodeText(),
-+ $process->getWorkingDirectory()
-+ );
-+
-+ if (!$process->isOutputDisabled()) {
-+ $error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
-+ $process->getOutput(),
-+ $process->getErrorOutput()
-+ );
-+ }
-+
-+ parent::__construct($error);
-+
-+ $this->process = $process;
-+ }
-+
-+ public function getProcess()
-+ {
-+ return $this->process;
-+ }
-+}
-diff --git a/vendor/symfony/process/Exception/ProcessTimedOutException.php b/vendor/symfony/process/Exception/ProcessTimedOutException.php
-new file mode 100644
-index 00000000..d4511469
---- /dev/null
-+++ b/vendor/symfony/process/Exception/ProcessTimedOutException.php
-@@ -0,0 +1,69 @@
-+<?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\Process\Exception;
-+
-+use Symfony\Component\Process\Process;
-+
-+/**
-+ * Exception that is thrown when a process times out.
-+ *
-+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
-+ */
-+class ProcessTimedOutException extends RuntimeException
-+{
-+ const TYPE_GENERAL = 1;
-+ const TYPE_IDLE = 2;
-+
-+ private $process;
-+ private $timeoutType;
-+
-+ public function __construct(Process $process, $timeoutType)
-+ {
-+ $this->process = $process;
-+ $this->timeoutType = $timeoutType;
-+
-+ parent::__construct(sprintf(
-+ 'The process "%s" exceeded the timeout of %s seconds.',
-+ $process->getCommandLine(),
-+ $this->getExceededTimeout()
-+ ));
-+ }
-+
-+ public function getProcess()
-+ {
-+ return $this->process;
-+ }
-+
-+ public function isGeneralTimeout()
-+ {
-+ return $this->timeoutType === self::TYPE_GENERAL;
-+ }
-+
-+ public function isIdleTimeout()
-+ {
-+ return $this->timeoutType === self::TYPE_IDLE;
-+ }
-+
-+ public function getExceededTimeout()
-+ {
-+ switch ($this->timeoutType) {
-+ case self::TYPE_GENERAL:
-+ return $this->process->getTimeout();
-+
-+ case self::TYPE_IDLE:
-+ return $this->process->getIdleTimeout();
-+
-+ default:
-+ throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType));
-+ }
-+ }
-+}
-diff --git a/vendor/symfony/process/Exception/RuntimeException.php b/vendor/symfony/process/Exception/RuntimeException.php
-new file mode 100644
-index 00000000..adead253
---- /dev/null
-+++ b/vendor/symfony/process/Exception/RuntimeException.php
-@@ -0,0 +1,21 @@
-+<?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\Process\Exception;
-+
-+/**
-+ * RuntimeException for the Process Component.
-+ *
-+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
-+ */
-+class RuntimeException extends \RuntimeException implements ExceptionInterface
-+{
-+}
-diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php
-new file mode 100644
-index 00000000..d8e68962
---- /dev/null
-+++ b/vendor/symfony/process/ExecutableFinder.php
-@@ -0,0 +1,90 @@
-+<?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\Process;
-+
-+/**
-+ * Generic executable finder.
-+ *
-+ * @author Fabien Potencier <fabien@symfony.com>
-+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
-+ */
-+class ExecutableFinder
-+{
-+ private $suffixes = array('.exe', '.bat', '.cmd', '.com');
-+
-+ /**
-+ * Replaces default suffixes of executable.
-+ *
-+ * @param array $suffixes
-+ */
-+ public function setSuffixes(array $suffixes)
-+ {
-+ $this->suffixes = $suffixes;
-+ }
-+
-+ /**
-+ * Adds new possible suffix to check for executable.
-+ *
-+ * @param string $suffix
-+ */
-+ public function addSuffix($suffix)
-+ {
-+ $this->suffixes[] = $suffix;
-+ }
-+
-+ /**
-+ * Finds an executable by name.
-+ *
-+ * @param string $name The executable name (without the extension)
-+ * @param string $default The default to return if no executable is found
-+ * @param array $extraDirs Additional dirs to check into
-+ *
-+ * @return string The executable path or default value
-+ */
-+ public function find($name, $default = null, array $extraDirs = array())
-+ {
-+ if (ini_get('open_basedir')) {
-+ $searchPath = explode(PATH_SEPARATOR, ini_get('open_basedir'));
-+ $dirs = array();
-+ foreach ($searchPath as $path) {
-+ // Silencing against https://bugs.php.net/69240
-+ if (@is_dir($path)) {
-+ $dirs[] = $path;
-+ } else {
-+ if (basename($path) == $name && @is_executable($path)) {
-+ return $path;
-+ }
-+ }
-+ }
-+ } else {
-+ $dirs = array_merge(
-+ explode(PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')),
-+ $extraDirs
-+ );
-+ }
-+
-+ $suffixes = array('');
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $pathExt = getenv('PATHEXT');
-+ $suffixes = array_merge($suffixes, $pathExt ? explode(PATH_SEPARATOR, $pathExt) : $this->suffixes);
-+ }
-+ foreach ($suffixes as $suffix) {
-+ foreach ($dirs as $dir) {
-+ if (@is_file($file = $dir.DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === DIRECTORY_SEPARATOR || is_executable($file))) {
-+ return $file;
-+ }
-+ }
-+ }
-+
-+ return $default;
-+ }
-+}
-diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php
-new file mode 100644
-index 00000000..831b1093
---- /dev/null
-+++ b/vendor/symfony/process/InputStream.php
-@@ -0,0 +1,90 @@
-+<?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\Process;
-+
-+use Symfony\Component\Process\Exception\RuntimeException;
-+
-+/**
-+ * Provides a way to continuously write to the input of a Process until the InputStream is closed.
-+ *
-+ * @author Nicolas Grekas <p@tchwork.com>
-+ */
-+class InputStream implements \IteratorAggregate
-+{
-+ private $onEmpty = null;
-+ private $input = array();
-+ private $open = true;
-+
-+ /**
-+ * Sets a callback that is called when the write buffer becomes empty.
-+ */
-+ public function onEmpty(callable $onEmpty = null)
-+ {
-+ $this->onEmpty = $onEmpty;
-+ }
-+
-+ /**
-+ * Appends an input to the write buffer.
-+ *
-+ * @param resource|scalar|\Traversable|null The input to append as stream resource, scalar or \Traversable
-+ */
-+ public function write($input)
-+ {
-+ if (null === $input) {
-+ return;
-+ }
-+ if ($this->isClosed()) {
-+ throw new RuntimeException(sprintf('%s is closed', static::class));
-+ }
-+ $this->input[] = ProcessUtils::validateInput(__METHOD__, $input);
-+ }
-+
-+ /**
-+ * Closes the write buffer.
-+ */
-+ public function close()
-+ {
-+ $this->open = false;
-+ }
-+
-+ /**
-+ * Tells whether the write buffer is closed or not.
-+ */
-+ public function isClosed()
-+ {
-+ return !$this->open;
-+ }
-+
-+ public function getIterator()
-+ {
-+ $this->open = true;
-+
-+ while ($this->open || $this->input) {
-+ if (!$this->input) {
-+ yield '';
-+ continue;
-+ }
-+ $current = array_shift($this->input);
-+
-+ if ($current instanceof \Iterator) {
-+ foreach ($current as $cur) {
-+ yield $cur;
-+ }
-+ } else {
-+ yield $current;
-+ }
-+ if (!$this->input && $this->open && null !== $onEmpty = $this->onEmpty) {
-+ $this->write($onEmpty($this));
-+ }
-+ }
-+ }
-+}
-diff --git a/vendor/symfony/process/LICENSE b/vendor/symfony/process/LICENSE
-new file mode 100644
-index 00000000..17d16a13
---- /dev/null
-+++ b/vendor/symfony/process/LICENSE
-@@ -0,0 +1,19 @@
-+Copyright (c) 2004-2017 Fabien Potencier
-+
-+Permission is hereby granted, free of charge, to any person obtaining a copy
-+of this software and associated documentation files (the "Software"), to deal
-+in the Software without restriction, including without limitation the rights
-+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-+copies of the Software, and to permit persons to whom the Software is furnished
-+to do so, subject to the following conditions:
-+
-+The above copyright notice and this permission notice shall be included in all
-+copies or substantial portions of the Software.
-+
-+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-+THE SOFTWARE.
-diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php
-new file mode 100644
-index 00000000..db31cc1b
---- /dev/null
-+++ b/vendor/symfony/process/PhpExecutableFinder.php
-@@ -0,0 +1,90 @@
-+<?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\Process;
-+
-+/**
-+ * An executable finder specifically designed for the PHP executable.
-+ *
-+ * @author Fabien Potencier <fabien@symfony.com>
-+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
-+ */
-+class PhpExecutableFinder
-+{
-+ private $executableFinder;
-+
-+ public function __construct()
-+ {
-+ $this->executableFinder = new ExecutableFinder();
-+ }
-+
-+ /**
-+ * Finds The PHP executable.
-+ *
-+ * @param bool $includeArgs Whether or not include command arguments
-+ *
-+ * @return string|false The PHP executable path or false if it cannot be found
-+ */
-+ public function find($includeArgs = true)
-+ {
-+ $args = $this->findArguments();
-+ $args = $includeArgs && $args ? ' '.implode(' ', $args) : '';
-+
-+ // HHVM support
-+ if (defined('HHVM_VERSION')) {
-+ return (getenv('PHP_BINARY') ?: PHP_BINARY).$args;
-+ }
-+
-+ // PHP_BINARY return the current sapi executable
-+ if (PHP_BINARY && in_array(PHP_SAPI, array('cli', 'cli-server', 'phpdbg')) && is_file(PHP_BINARY)) {
-+ return PHP_BINARY.$args;
-+ }
-+
-+ if ($php = getenv('PHP_PATH')) {
-+ if (!is_executable($php)) {
-+ return false;
-+ }
-+
-+ return $php;
-+ }
-+
-+ if ($php = getenv('PHP_PEAR_PHP_BIN')) {
-+ if (is_executable($php)) {
-+ return $php;
-+ }
-+ }
-+
-+ $dirs = array(PHP_BINDIR);
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $dirs[] = 'C:\xampp\php\\';
-+ }
-+
-+ return $this->executableFinder->find('php', false, $dirs);
-+ }
-+
-+ /**
-+ * Finds the PHP executable arguments.
-+ *
-+ * @return array The PHP executable arguments
-+ */
-+ public function findArguments()
-+ {
-+ $arguments = array();
-+
-+ if (defined('HHVM_VERSION')) {
-+ $arguments[] = '--php';
-+ } elseif ('phpdbg' === PHP_SAPI) {
-+ $arguments[] = '-qrr';
-+ }
-+
-+ return $arguments;
-+ }
-+}
-diff --git a/vendor/symfony/process/PhpProcess.php b/vendor/symfony/process/PhpProcess.php
-new file mode 100644
-index 00000000..7afd182f
---- /dev/null
-+++ b/vendor/symfony/process/PhpProcess.php
-@@ -0,0 +1,78 @@
-+<?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\Process;
-+
-+use Symfony\Component\Process\Exception\RuntimeException;
-+
-+/**
-+ * PhpProcess runs a PHP script in an independent process.
-+ *
-+ * $p = new PhpProcess('<?php echo "foo"; ?>');
-+ * $p->run();
-+ * print $p->getOutput()."\n";
-+ *
-+ * @author Fabien Potencier <fabien@symfony.com>
-+ */
-+class PhpProcess extends Process
-+{
-+ /**
-+ * Constructor.
-+ *
-+ * @param string $script The PHP script to run (as a string)
-+ * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
-+ * @param array|null $env The environment variables or null to use the same environment as the current PHP process
-+ * @param int $timeout The timeout in seconds
-+ * @param array $options An array of options for proc_open
-+ */
-+ public function __construct($script, $cwd = null, array $env = null, $timeout = 60, array $options = null)
-+ {
-+ $executableFinder = new PhpExecutableFinder();
-+ if (false === $php = $executableFinder->find(false)) {
-+ $php = null;
-+ } else {
-+ $php = array_merge(array($php), $executableFinder->findArguments());
-+ }
-+ if ('phpdbg' === PHP_SAPI) {
-+ $file = tempnam(sys_get_temp_dir(), 'dbg');
-+ file_put_contents($file, $script);
-+ register_shutdown_function('unlink', $file);
-+ $php[] = $file;
-+ $script = null;
-+ }
-+ if (null !== $options) {
-+ @trigger_error(sprintf('The $options parameter of the %s constructor is deprecated since version 3.3 and will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
-+ }
-+
-+ parent::__construct($php, $cwd, $env, $script, $timeout, $options);
-+ }
-+
-+ /**
-+ * Sets the path to the PHP binary to use.
-+ */
-+ public function setPhpBinary($php)
-+ {
-+ $this->setCommandLine($php);
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function start(callable $callback = null/*, array $env = array()*/)
-+ {
-+ if (null === $this->getCommandLine()) {
-+ throw new RuntimeException('Unable to find the PHP executable.');
-+ }
-+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
-+
-+ parent::start($callback, $env);
-+ }
-+}
-diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php
-new file mode 100644
-index 00000000..4c67d5b8
---- /dev/null
-+++ b/vendor/symfony/process/Pipes/AbstractPipes.php
-@@ -0,0 +1,169 @@
-+<?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\Process\Pipes;
-+
-+use Symfony\Component\Process\Exception\InvalidArgumentException;
-+
-+/**
-+ * @author Romain Neutron <imprec@gmail.com>
-+ *
-+ * @internal
-+ */
-+abstract class AbstractPipes implements PipesInterface
-+{
-+ /** @var array */
-+ public $pipes = array();
-+
-+ /** @var string */
-+ private $inputBuffer = '';
-+ /** @var resource|scalar|\Iterator|null */
-+ private $input;
-+ /** @var bool */
-+ private $blocked = true;
-+
-+ public function __construct($input)
-+ {
-+ if (is_resource($input) || $input instanceof \Iterator) {
-+ $this->input = $input;
-+ } elseif (is_string($input)) {
-+ $this->inputBuffer = $input;
-+ } else {
-+ $this->inputBuffer = (string) $input;
-+ }
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function close()
-+ {
-+ foreach ($this->pipes as $pipe) {
-+ fclose($pipe);
-+ }
-+ $this->pipes = array();
-+ }
-+
-+ /**
-+ * Returns true if a system call has been interrupted.
-+ *
-+ * @return bool
-+ */
-+ protected function hasSystemCallBeenInterrupted()
-+ {
-+ $lastError = error_get_last();
-+
-+ // stream_select returns false when the `select` system call is interrupted by an incoming signal
-+ return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call');
-+ }
-+
-+ /**
-+ * Unblocks streams.
-+ */
-+ protected function unblock()
-+ {
-+ if (!$this->blocked) {
-+ return;
-+ }
-+
-+ foreach ($this->pipes as $pipe) {
-+ stream_set_blocking($pipe, 0);
-+ }
-+ if (is_resource($this->input)) {
-+ stream_set_blocking($this->input, 0);
-+ }
-+
-+ $this->blocked = false;
-+ }
-+
-+ /**
-+ * Writes input to stdin.
-+ *
-+ * @throws InvalidArgumentException When an input iterator yields a non supported value
-+ */
-+ protected function write()
-+ {
-+ if (!isset($this->pipes[0])) {
-+ return;
-+ }
-+ $input = $this->input;
-+
-+ if ($input instanceof \Iterator) {
-+ if (!$input->valid()) {
-+ $input = null;
-+ } elseif (is_resource($input = $input->current())) {
-+ stream_set_blocking($input, 0);
-+ } elseif (!isset($this->inputBuffer[0])) {
-+ if (!is_string($input)) {
-+ if (!is_scalar($input)) {
-+ throw new InvalidArgumentException(sprintf('%s yielded a value of type "%s", but only scalars and stream resources are supported', get_class($this->input), gettype($input)));
-+ }
-+ $input = (string) $input;
-+ }
-+ $this->inputBuffer = $input;
-+ $this->input->next();
-+ $input = null;
-+ } else {
-+ $input = null;
-+ }
-+ }
-+
-+ $r = $e = array();
-+ $w = array($this->pipes[0]);
-+
-+ // let's have a look if something changed in streams
-+ if (false === $n = @stream_select($r, $w, $e, 0, 0)) {
-+ return;
-+ }
-+
-+ foreach ($w as $stdin) {
-+ if (isset($this->inputBuffer[0])) {
-+ $written = fwrite($stdin, $this->inputBuffer);
-+ $this->inputBuffer = substr($this->inputBuffer, $written);
-+ if (isset($this->inputBuffer[0])) {
-+ return array($this->pipes[0]);
-+ }
-+ }
-+
-+ if ($input) {
-+ for (;;) {
-+ $data = fread($input, self::CHUNK_SIZE);
-+ if (!isset($data[0])) {
-+ break;
-+ }
-+ $written = fwrite($stdin, $data);
-+ $data = substr($data, $written);
-+ if (isset($data[0])) {
-+ $this->inputBuffer = $data;
-+
-+ return array($this->pipes[0]);
-+ }
-+ }
-+ if (feof($input)) {
-+ if ($this->input instanceof \Iterator) {
-+ $this->input->next();
-+ } else {
-+ $this->input = null;
-+ }
-+ }
-+ }
-+ }
-+
-+ // no input to read on resource, buffer is empty
-+ if (!isset($this->inputBuffer[0]) && !($this->input instanceof \Iterator ? $this->input->valid() : $this->input)) {
-+ $this->input = null;
-+ fclose($this->pipes[0]);
-+ unset($this->pipes[0]);
-+ } elseif (!$w) {
-+ return array($this->pipes[0]);
-+ }
-+ }
-+}
-diff --git a/vendor/symfony/process/Pipes/PipesInterface.php b/vendor/symfony/process/Pipes/PipesInterface.php
-new file mode 100644
-index 00000000..52bbe76b
---- /dev/null
-+++ b/vendor/symfony/process/Pipes/PipesInterface.php
-@@ -0,0 +1,67 @@
-+<?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\Process\Pipes;
-+
-+/**
-+ * PipesInterface manages descriptors and pipes for the use of proc_open.
-+ *
-+ * @author Romain Neutron <imprec@gmail.com>
-+ *
-+ * @internal
-+ */
-+interface PipesInterface
-+{
-+ const CHUNK_SIZE = 16384;
-+
-+ /**
-+ * Returns an array of descriptors for the use of proc_open.
-+ *
-+ * @return array
-+ */
-+ public function getDescriptors();
-+
-+ /**
-+ * Returns an array of filenames indexed by their related stream in case these pipes use temporary files.
-+ *
-+ * @return string[]
-+ */
-+ public function getFiles();
-+
-+ /**
-+ * Reads data in file handles and pipes.
-+ *
-+ * @param bool $blocking Whether to use blocking calls or not
-+ * @param bool $close Whether to close pipes if they've reached EOF
-+ *
-+ * @return string[] An array of read data indexed by their fd
-+ */
-+ public function readAndWrite($blocking, $close = false);
-+
-+ /**
-+ * Returns if the current state has open file handles or pipes.
-+ *
-+ * @return bool
-+ */
-+ public function areOpen();
-+
-+ /**
-+ * Returns if pipes are able to read output.
-+ *
-+ * @return bool
-+ */
-+ public function haveReadSupport();
-+
-+ /**
-+ * Closes file handles and pipes.
-+ */
-+ public function close();
-+}
-diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php
-new file mode 100644
-index 00000000..3185fe76
---- /dev/null
-+++ b/vendor/symfony/process/Pipes/UnixPipes.php
-@@ -0,0 +1,153 @@
-+<?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\Process\Pipes;
-+
-+use Symfony\Component\Process\Process;
-+
-+/**
-+ * UnixPipes implementation uses unix pipes as handles.
-+ *
-+ * @author Romain Neutron <imprec@gmail.com>
-+ *
-+ * @internal
-+ */
-+class UnixPipes extends AbstractPipes
-+{
-+ /** @var bool */
-+ private $ttyMode;
-+ /** @var bool */
-+ private $ptyMode;
-+ /** @var bool */
-+ private $haveReadSupport;
-+
-+ public function __construct($ttyMode, $ptyMode, $input, $haveReadSupport)
-+ {
-+ $this->ttyMode = (bool) $ttyMode;
-+ $this->ptyMode = (bool) $ptyMode;
-+ $this->haveReadSupport = (bool) $haveReadSupport;
-+
-+ parent::__construct($input);
-+ }
-+
-+ public function __destruct()
-+ {
-+ $this->close();
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function getDescriptors()
-+ {
-+ if (!$this->haveReadSupport) {
-+ $nullstream = fopen('/dev/null', 'c');
-+
-+ return array(
-+ array('pipe', 'r'),
-+ $nullstream,
-+ $nullstream,
-+ );
-+ }
-+
-+ if ($this->ttyMode) {
-+ return array(
-+ array('file', '/dev/tty', 'r'),
-+ array('file', '/dev/tty', 'w'),
-+ array('file', '/dev/tty', 'w'),
-+ );
-+ }
-+
-+ if ($this->ptyMode && Process::isPtySupported()) {
-+ return array(
-+ array('pty'),
-+ array('pty'),
-+ array('pty'),
-+ );
-+ }
-+
-+ return array(
-+ array('pipe', 'r'),
-+ array('pipe', 'w'), // stdout
-+ array('pipe', 'w'), // stderr
-+ );
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function getFiles()
-+ {
-+ return array();
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function readAndWrite($blocking, $close = false)
-+ {
-+ $this->unblock();
-+ $w = $this->write();
-+
-+ $read = $e = array();
-+ $r = $this->pipes;
-+ unset($r[0]);
-+
-+ // let's have a look if something changed in streams
-+ if (($r || $w) && false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
-+ // if a system call has been interrupted, forget about it, let's try again
-+ // otherwise, an error occurred, let's reset pipes
-+ if (!$this->hasSystemCallBeenInterrupted()) {
-+ $this->pipes = array();
-+ }
-+
-+ return $read;
-+ }
-+
-+ foreach ($r as $pipe) {
-+ // prior PHP 5.4 the array passed to stream_select is modified and
-+ // lose key association, we have to find back the key
-+ $read[$type = array_search($pipe, $this->pipes, true)] = '';
-+
-+ do {
-+ $data = fread($pipe, self::CHUNK_SIZE);
-+ $read[$type] .= $data;
-+ } while (isset($data[0]) && ($close || isset($data[self::CHUNK_SIZE - 1])));
-+
-+ if (!isset($read[$type][0])) {
-+ unset($read[$type]);
-+ }
-+
-+ if ($close && feof($pipe)) {
-+ fclose($pipe);
-+ unset($this->pipes[$type]);
-+ }
-+ }
-+
-+ return $read;
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function haveReadSupport()
-+ {
-+ return $this->haveReadSupport;
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function areOpen()
-+ {
-+ return (bool) $this->pipes;
-+ }
-+}
-diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php
-new file mode 100644
-index 00000000..a1e31155
---- /dev/null
-+++ b/vendor/symfony/process/Pipes/WindowsPipes.php
-@@ -0,0 +1,200 @@
-+<?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\Process\Pipes;
-+
-+use Symfony\Component\Process\Process;
-+use Symfony\Component\Process\Exception\RuntimeException;
-+
-+/**
-+ * WindowsPipes implementation uses temporary files as handles.
-+ *
-+ * @see https://bugs.php.net/bug.php?id=51800
-+ * @see https://bugs.php.net/bug.php?id=65650
-+ *
-+ * @author Romain Neutron <imprec@gmail.com>
-+ *
-+ * @internal
-+ */
-+class WindowsPipes extends AbstractPipes
-+{
-+ /** @var array */
-+ private $files = array();
-+ /** @var array */
-+ private $fileHandles = array();
-+ /** @var array */
-+ private $readBytes = array(
-+ Process::STDOUT => 0,
-+ Process::STDERR => 0,
-+ );
-+ /** @var bool */
-+ private $haveReadSupport;
-+
-+ public function __construct($input, $haveReadSupport)
-+ {
-+ $this->haveReadSupport = (bool) $haveReadSupport;
-+
-+ if ($this->haveReadSupport) {
-+ // Fix for PHP bug #51800: reading from STDOUT pipe hangs forever on Windows if the output is too big.
-+ // Workaround for this problem is to use temporary files instead of pipes on Windows platform.
-+ //
-+ // @see https://bugs.php.net/bug.php?id=51800
-+ $pipes = array(
-+ Process::STDOUT => Process::OUT,
-+ Process::STDERR => Process::ERR,
-+ );
-+ $tmpCheck = false;
-+ $tmpDir = sys_get_temp_dir();
-+ $lastError = 'unknown reason';
-+ set_error_handler(function ($type, $msg) use (&$lastError) { $lastError = $msg; });
-+ for ($i = 0;; ++$i) {
-+ foreach ($pipes as $pipe => $name) {
-+ $file = sprintf('%s\\sf_proc_%02X.%s', $tmpDir, $i, $name);
-+ if (file_exists($file) && !unlink($file)) {
-+ continue 2;
-+ }
-+ $h = fopen($file, 'xb');
-+ if (!$h) {
-+ $error = $lastError;
-+ if ($tmpCheck || $tmpCheck = unlink(tempnam(false, 'sf_check_'))) {
-+ continue;
-+ }
-+ restore_error_handler();
-+ throw new RuntimeException(sprintf('A temporary file could not be opened to write the process output: %s', $error));
-+ }
-+ if (!$h || !$this->fileHandles[$pipe] = fopen($file, 'rb')) {
-+ continue 2;
-+ }
-+ if (isset($this->files[$pipe])) {
-+ unlink($this->files[$pipe]);
-+ }
-+ $this->files[$pipe] = $file;
-+ }
-+ break;
-+ }
-+ restore_error_handler();
-+ }
-+
-+ parent::__construct($input);
-+ }
-+
-+ public function __destruct()
-+ {
-+ $this->close();
-+ $this->removeFiles();
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function getDescriptors()
-+ {
-+ if (!$this->haveReadSupport) {
-+ $nullstream = fopen('NUL', 'c');
-+
-+ return array(
-+ array('pipe', 'r'),
-+ $nullstream,
-+ $nullstream,
-+ );
-+ }
-+
-+ // We're not using pipe on Windows platform as it hangs (https://bugs.php.net/bug.php?id=51800)
-+ // We're not using file handles as it can produce corrupted output https://bugs.php.net/bug.php?id=65650
-+ // So we redirect output within the commandline and pass the nul device to the process
-+ return array(
-+ array('pipe', 'r'),
-+ array('file', 'NUL', 'w'),
-+ array('file', 'NUL', 'w'),
-+ );
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function getFiles()
-+ {
-+ return $this->files;
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function readAndWrite($blocking, $close = false)
-+ {
-+ $this->unblock();
-+ $w = $this->write();
-+ $read = $r = $e = array();
-+
-+ if ($blocking) {
-+ if ($w) {
-+ @stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
-+ } elseif ($this->fileHandles) {
-+ usleep(Process::TIMEOUT_PRECISION * 1E6);
-+ }
-+ }
-+ foreach ($this->fileHandles as $type => $fileHandle) {
-+ $data = stream_get_contents($fileHandle, -1, $this->readBytes[$type]);
-+
-+ if (isset($data[0])) {
-+ $this->readBytes[$type] += strlen($data);
-+ $read[$type] = $data;
-+ }
-+ if ($close) {
-+ fclose($fileHandle);
-+ unset($this->fileHandles[$type]);
-+ }
-+ }
-+
-+ return $read;
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function haveReadSupport()
-+ {
-+ return $this->haveReadSupport;
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function areOpen()
-+ {
-+ return $this->pipes && $this->fileHandles;
-+ }
-+
-+ /**
-+ * {@inheritdoc}
-+ */
-+ public function close()
-+ {
-+ parent::close();
-+ foreach ($this->fileHandles as $handle) {
-+ fclose($handle);
-+ }
-+ $this->fileHandles = array();
-+ }
-+
-+ /**
-+ * Removes temporary files.
-+ */
-+ private function removeFiles()
-+ {
-+ foreach ($this->files as $filename) {
-+ if (file_exists($filename)) {
-+ @unlink($filename);
-+ }
-+ }
-+ $this->files = array();
-+ }
-+}
-diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php
-new file mode 100644
-index 00000000..05f88d2d
---- /dev/null
-+++ b/vendor/symfony/process/Process.php
-@@ -0,0 +1,1735 @@
-+<?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\Process;
-+
-+use Symfony\Component\Process\Exception\InvalidArgumentException;
-+use Symfony\Component\Process\Exception\LogicException;
-+use Symfony\Component\Process\Exception\ProcessFailedException;
-+use Symfony\Component\Process\Exception\ProcessTimedOutException;
-+use Symfony\Component\Process\Exception\RuntimeException;
-+use Symfony\Component\Process\Pipes\PipesInterface;
-+use Symfony\Component\Process\Pipes\UnixPipes;
-+use Symfony\Component\Process\Pipes\WindowsPipes;
-+
-+/**
-+ * Process is a thin wrapper around proc_* functions to easily
-+ * start independent PHP processes.
-+ *
-+ * @author Fabien Potencier <fabien@symfony.com>
-+ * @author Romain Neutron <imprec@gmail.com>
-+ */
-+class Process implements \IteratorAggregate
-+{
-+ const ERR = 'err';
-+ const OUT = 'out';
-+
-+ const STATUS_READY = 'ready';
-+ const STATUS_STARTED = 'started';
-+ const STATUS_TERMINATED = 'terminated';
-+
-+ const STDIN = 0;
-+ const STDOUT = 1;
-+ const STDERR = 2;
-+
-+ // Timeout Precision in seconds.
-+ const TIMEOUT_PRECISION = 0.2;
-+
-+ const ITER_NON_BLOCKING = 1; // By default, iterating over outputs is a blocking call, use this flag to make it non-blocking
-+ const ITER_KEEP_OUTPUT = 2; // By default, outputs are cleared while iterating, use this flag to keep them in memory
-+ const ITER_SKIP_OUT = 4; // Use this flag to skip STDOUT while iterating
-+ const ITER_SKIP_ERR = 8; // Use this flag to skip STDERR while iterating
-+
-+ private $callback;
-+ private $hasCallback = false;
-+ private $commandline;
-+ private $cwd;
-+ private $env;
-+ private $input;
-+ private $starttime;
-+ private $lastOutputTime;
-+ private $timeout;
-+ private $idleTimeout;
-+ private $options = array('suppress_errors' => true);
-+ private $exitcode;
-+ private $fallbackStatus = array();
-+ private $processInformation;
-+ private $outputDisabled = false;
-+ private $stdout;
-+ private $stderr;
-+ private $enhanceWindowsCompatibility = true;
-+ private $enhanceSigchildCompatibility;
-+ private $process;
-+ private $status = self::STATUS_READY;
-+ private $incrementalOutputOffset = 0;
-+ private $incrementalErrorOutputOffset = 0;
-+ private $tty;
-+ private $pty;
-+ private $inheritEnv = false;
-+
-+ private $useFileHandles = false;
-+ /** @var PipesInterface */
-+ private $processPipes;
-+
-+ private $latestSignal;
-+
-+ private static $sigchild;
-+
-+ /**
-+ * Exit codes translation table.
-+ *
-+ * User-defined errors must use exit codes in the 64-113 range.
-+ *
-+ * @var array
-+ */
-+ public static $exitCodes = array(
-+ 0 => 'OK',
-+ 1 => 'General error',
-+ 2 => 'Misuse of shell builtins',
-+
-+ 126 => 'Invoked command cannot execute',
-+ 127 => 'Command not found',
-+ 128 => 'Invalid exit argument',
-+
-+ // signals
-+ 129 => 'Hangup',
-+ 130 => 'Interrupt',
-+ 131 => 'Quit and dump core',
-+ 132 => 'Illegal instruction',
-+ 133 => 'Trace/breakpoint trap',
-+ 134 => 'Process aborted',
-+ 135 => 'Bus error: "access to undefined portion of memory object"',
-+ 136 => 'Floating point exception: "erroneous arithmetic operation"',
-+ 137 => 'Kill (terminate immediately)',
-+ 138 => 'User-defined 1',
-+ 139 => 'Segmentation violation',
-+ 140 => 'User-defined 2',
-+ 141 => 'Write to pipe with no one reading',
-+ 142 => 'Signal raised by alarm',
-+ 143 => 'Termination (request to terminate)',
-+ // 144 - not defined
-+ 145 => 'Child process terminated, stopped (or continued*)',
-+ 146 => 'Continue if stopped',
-+ 147 => 'Stop executing temporarily',
-+ 148 => 'Terminal stop signal',
-+ 149 => 'Background process attempting to read from tty ("in")',
-+ 150 => 'Background process attempting to write to tty ("out")',
-+ 151 => 'Urgent data available on socket',
-+ 152 => 'CPU time limit exceeded',
-+ 153 => 'File size limit exceeded',
-+ 154 => 'Signal raised by timer counting virtual time: "virtual timer expired"',
-+ 155 => 'Profiling timer expired',
-+ // 156 - not defined
-+ 157 => 'Pollable event',
-+ // 158 - not defined
-+ 159 => 'Bad syscall',
-+ );
-+
-+ /**
-+ * Constructor.
-+ *
-+ * @param string|array $commandline The command line to run
-+ * @param string|null $cwd The working directory or null to use the working dir of the current PHP process
-+ * @param array|null $env The environment variables or null to use the same environment as the current PHP process
-+ * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
-+ * @param int|float|null $timeout The timeout in seconds or null to disable
-+ * @param array $options An array of options for proc_open
-+ *
-+ * @throws RuntimeException When proc_open is not installed
-+ */
-+ public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = null)
-+ {
-+ if (!function_exists('proc_open')) {
-+ throw new RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');
-+ }
-+
-+ $this->commandline = $commandline;
-+ $this->cwd = $cwd;
-+
-+ // on Windows, if the cwd changed via chdir(), proc_open defaults to the dir where PHP was started
-+ // on Gnu/Linux, PHP builds with --enable-maintainer-zts are also affected
-+ // @see : https://bugs.php.net/bug.php?id=51800
-+ // @see : https://bugs.php.net/bug.php?id=50524
-+ if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\' === DIRECTORY_SEPARATOR)) {
-+ $this->cwd = getcwd();
-+ }
-+ if (null !== $env) {
-+ $this->setEnv($env);
-+ }
-+
-+ $this->setInput($input);
-+ $this->setTimeout($timeout);
-+ $this->useFileHandles = '\\' === DIRECTORY_SEPARATOR;
-+ $this->pty = false;
-+ $this->enhanceSigchildCompatibility = '\\' !== DIRECTORY_SEPARATOR && $this->isSigchildEnabled();
-+ if (null !== $options) {
-+ @trigger_error(sprintf('The $options parameter of the %s constructor is deprecated since version 3.3 and will be removed in 4.0.', __CLASS__), E_USER_DEPRECATED);
-+ $this->options = array_replace($this->options, $options);
-+ }
-+ }
-+
-+ public function __destruct()
-+ {
-+ $this->stop(0);
-+ }
-+
-+ public function __clone()
-+ {
-+ $this->resetProcessData();
-+ }
-+
-+ /**
-+ * Runs the process.
-+ *
-+ * The callback receives the type of output (out or err) and
-+ * some bytes from the output in real-time. It allows to have feedback
-+ * from the independent process during execution.
-+ *
-+ * The STDOUT and STDERR are also available after the process is finished
-+ * via the getOutput() and getErrorOutput() methods.
-+ *
-+ * @param callable|null $callback A PHP callback to run whenever there is some
-+ * output available on STDOUT or STDERR
-+ * @param array $env An array of additional env vars to set when running the process
-+ *
-+ * @return int The exit status code
-+ *
-+ * @throws RuntimeException When process can't be launched
-+ * @throws RuntimeException When process stopped after receiving signal
-+ * @throws LogicException In case a callback is provided and output has been disabled
-+ *
-+ * @final since version 3.3
-+ */
-+ public function run($callback = null/*, array $env = array()*/)
-+ {
-+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
-+ $this->start($callback, $env);
-+
-+ return $this->wait();
-+ }
-+
-+ /**
-+ * Runs the process.
-+ *
-+ * This is identical to run() except that an exception is thrown if the process
-+ * exits with a non-zero exit code.
-+ *
-+ * @param callable|null $callback
-+ * @param array $env An array of additional env vars to set when running the process
-+ *
-+ * @return self
-+ *
-+ * @throws RuntimeException if PHP was compiled with --enable-sigchild and the enhanced sigchild compatibility mode is not enabled
-+ * @throws ProcessFailedException if the process didn't terminate successfully
-+ *
-+ * @final since version 3.3
-+ */
-+ public function mustRun(callable $callback = null/*, array $env = array()*/)
-+ {
-+ if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
-+ }
-+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
-+
-+ if (0 !== $this->run($callback, $env)) {
-+ throw new ProcessFailedException($this);
-+ }
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Starts the process and returns after writing the input to STDIN.
-+ *
-+ * This method blocks until all STDIN data is sent to the process then it
-+ * returns while the process runs in the background.
-+ *
-+ * The termination of the process can be awaited with wait().
-+ *
-+ * The callback receives the type of output (out or err) and some bytes from
-+ * the output in real-time while writing the standard input to the process.
-+ * It allows to have feedback from the independent process during execution.
-+ *
-+ * @param callable|null $callback A PHP callback to run whenever there is some
-+ * output available on STDOUT or STDERR
-+ * @param array $env An array of additional env vars to set when running the process
-+ *
-+ * @throws RuntimeException When process can't be launched
-+ * @throws RuntimeException When process is already running
-+ * @throws LogicException In case a callback is provided and output has been disabled
-+ */
-+ public function start(callable $callback = null/*, array $env = array()*/)
-+ {
-+ if ($this->isRunning()) {
-+ throw new RuntimeException('Process is already running');
-+ }
-+ if (2 <= func_num_args()) {
-+ $env = func_get_arg(1);
-+ } else {
-+ if (__CLASS__ !== static::class) {
-+ $r = new \ReflectionMethod($this, __FUNCTION__);
-+ if (__CLASS__ !== $r->getDeclaringClass()->getName() && (2 > $r->getNumberOfParameters() || 'env' !== $r->getParameters()[0]->name)) {
-+ @trigger_error(sprintf('The %s::start() method expects a second "$env" argument since version 3.3. It will be made mandatory in 4.0.', static::class), E_USER_DEPRECATED);
-+ }
-+ }
-+ $env = null;
-+ }
-+
-+ $this->resetProcessData();
-+ $this->starttime = $this->lastOutputTime = microtime(true);
-+ $this->callback = $this->buildCallback($callback);
-+ $this->hasCallback = null !== $callback;
-+ $descriptors = $this->getDescriptors();
-+ $inheritEnv = $this->inheritEnv;
-+
-+ if (is_array($commandline = $this->commandline)) {
-+ $commandline = implode(' ', array_map(array($this, 'escapeArgument'), $commandline));
-+
-+ if ('\\' !== DIRECTORY_SEPARATOR) {
-+ // exec is mandatory to deal with sending a signal to the process
-+ $commandline = 'exec '.$commandline;
-+ }
-+ }
-+
-+ if (null === $env) {
-+ $env = $this->env;
-+ } else {
-+ if ($this->env) {
-+ $env += $this->env;
-+ }
-+ $inheritEnv = true;
-+ }
-+
-+ $envBackup = array();
-+ if (null !== $env && $inheritEnv) {
-+ foreach ($env as $k => $v) {
-+ $envBackup[$k] = getenv($k);
-+ putenv(false === $v || null === $v ? $k : "$k=$v");
-+ }
-+ $env = null;
-+ } elseif (null !== $env) {
-+ @trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED);
-+ }
-+ if ('\\' === DIRECTORY_SEPARATOR && $this->enhanceWindowsCompatibility) {
-+ $this->options['bypass_shell'] = true;
-+ $commandline = $this->prepareWindowsCommandLine($commandline, $envBackup, $env);
-+ } elseif (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-+ // last exit code is output on the fourth pipe and caught to work around --enable-sigchild
-+ $descriptors[3] = array('pipe', 'w');
-+
-+ // See https://unix.stackexchange.com/questions/71205/background-process-pipe-input
-+ $commandline = '{ ('.$commandline.') <&3 3<&- 3>/dev/null & } 3<&0;';
-+ $commandline .= 'pid=$!; echo $pid >&3; wait $pid; code=$?; echo $code >&3; exit $code';
-+
-+ // Workaround for the bug, when PTS functionality is enabled.
-+ // @see : https://bugs.php.net/69442
-+ $ptsWorkaround = fopen(__FILE__, 'r');
-+ }
-+
-+ $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $env, $this->options);
-+
-+ foreach ($envBackup as $k => $v) {
-+ putenv(false === $v ? $k : "$k=$v");
-+ }
-+
-+ if (!is_resource($this->process)) {
-+ throw new RuntimeException('Unable to launch a new process.');
-+ }
-+ $this->status = self::STATUS_STARTED;
-+
-+ if (isset($descriptors[3])) {
-+ $this->fallbackStatus['pid'] = (int) fgets($this->processPipes->pipes[3]);
-+ }
-+
-+ if ($this->tty) {
-+ return;
-+ }
-+
-+ $this->updateStatus(false);
-+ $this->checkTimeout();
-+ }
-+
-+ /**
-+ * Restarts the process.
-+ *
-+ * Be warned that the process is cloned before being started.
-+ *
-+ * @param callable|null $callback A PHP callback to run whenever there is some
-+ * output available on STDOUT or STDERR
-+ * @param array $env An array of additional env vars to set when running the process
-+ *
-+ * @return $this
-+ *
-+ * @throws RuntimeException When process can't be launched
-+ * @throws RuntimeException When process is already running
-+ *
-+ * @see start()
-+ *
-+ * @final since version 3.3
-+ */
-+ public function restart(callable $callback = null/*, array $env = array()*/)
-+ {
-+ if ($this->isRunning()) {
-+ throw new RuntimeException('Process is already running');
-+ }
-+ $env = 1 < func_num_args() ? func_get_arg(1) : null;
-+
-+ $process = clone $this;
-+ $process->start($callback, $env);
-+
-+ return $process;
-+ }
-+
-+ /**
-+ * Waits for the process to terminate.
-+ *
-+ * The callback receives the type of output (out or err) and some bytes
-+ * from the output in real-time while writing the standard input to the process.
-+ * It allows to have feedback from the independent process during execution.
-+ *
-+ * @param callable|null $callback A valid PHP callback
-+ *
-+ * @return int The exitcode of the process
-+ *
-+ * @throws RuntimeException When process timed out
-+ * @throws RuntimeException When process stopped after receiving signal
-+ * @throws LogicException When process is not yet started
-+ */
-+ public function wait(callable $callback = null)
-+ {
-+ $this->requireProcessIsStarted(__FUNCTION__);
-+
-+ $this->updateStatus(false);
-+
-+ if (null !== $callback) {
-+ if (!$this->processPipes->haveReadSupport()) {
-+ $this->stop(0);
-+ throw new \LogicException('Pass the callback to the Process::start method or enableOutput to use a callback with Process::wait');
-+ }
-+ $this->callback = $this->buildCallback($callback);
-+ }
-+
-+ do {
-+ $this->checkTimeout();
-+ $running = '\\' === DIRECTORY_SEPARATOR ? $this->isRunning() : $this->processPipes->areOpen();
-+ $this->readPipes($running, '\\' !== DIRECTORY_SEPARATOR || !$running);
-+ } while ($running);
-+
-+ while ($this->isRunning()) {
-+ usleep(1000);
-+ }
-+
-+ if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {
-+ throw new RuntimeException(sprintf('The process has been signaled with signal "%s".', $this->processInformation['termsig']));
-+ }
-+
-+ return $this->exitcode;
-+ }
-+
-+ /**
-+ * Returns the Pid (process identifier), if applicable.
-+ *
-+ * @return int|null The process id if running, null otherwise
-+ */
-+ public function getPid()
-+ {
-+ return $this->isRunning() ? $this->processInformation['pid'] : null;
-+ }
-+
-+ /**
-+ * Sends a POSIX signal to the process.
-+ *
-+ * @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
-+ *
-+ * @return $this
-+ *
-+ * @throws LogicException In case the process is not running
-+ * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
-+ * @throws RuntimeException In case of failure
-+ */
-+ public function signal($signal)
-+ {
-+ $this->doSignal($signal, true);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Disables fetching output and error output from the underlying process.
-+ *
-+ * @return $this
-+ *
-+ * @throws RuntimeException In case the process is already running
-+ * @throws LogicException if an idle timeout is set
-+ */
-+ public function disableOutput()
-+ {
-+ if ($this->isRunning()) {
-+ throw new RuntimeException('Disabling output while the process is running is not possible.');
-+ }
-+ if (null !== $this->idleTimeout) {
-+ throw new LogicException('Output can not be disabled while an idle timeout is set.');
-+ }
-+
-+ $this->outputDisabled = true;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Enables fetching output and error output from the underlying process.
-+ *
-+ * @return $this
-+ *
-+ * @throws RuntimeException In case the process is already running
-+ */
-+ public function enableOutput()
-+ {
-+ if ($this->isRunning()) {
-+ throw new RuntimeException('Enabling output while the process is running is not possible.');
-+ }
-+
-+ $this->outputDisabled = false;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Returns true in case the output is disabled, false otherwise.
-+ *
-+ * @return bool
-+ */
-+ public function isOutputDisabled()
-+ {
-+ return $this->outputDisabled;
-+ }
-+
-+ /**
-+ * Returns the current output of the process (STDOUT).
-+ *
-+ * @return string The process output
-+ *
-+ * @throws LogicException in case the output has been disabled
-+ * @throws LogicException In case the process is not started
-+ */
-+ public function getOutput()
-+ {
-+ $this->readPipesForOutput(__FUNCTION__);
-+
-+ if (false === $ret = stream_get_contents($this->stdout, -1, 0)) {
-+ return '';
-+ }
-+
-+ return $ret;
-+ }
-+
-+ /**
-+ * Returns the output incrementally.
-+ *
-+ * In comparison with the getOutput method which always return the whole
-+ * output, this one returns the new output since the last call.
-+ *
-+ * @return string The process output since the last call
-+ *
-+ * @throws LogicException in case the output has been disabled
-+ * @throws LogicException In case the process is not started
-+ */
-+ public function getIncrementalOutput()
-+ {
-+ $this->readPipesForOutput(__FUNCTION__);
-+
-+ $latest = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
-+ $this->incrementalOutputOffset = ftell($this->stdout);
-+
-+ if (false === $latest) {
-+ return '';
-+ }
-+
-+ return $latest;
-+ }
-+
-+ /**
-+ * Returns an iterator to the output of the process, with the output type as keys (Process::OUT/ERR).
-+ *
-+ * @param int $flags A bit field of Process::ITER_* flags
-+ *
-+ * @throws LogicException in case the output has been disabled
-+ * @throws LogicException In case the process is not started
-+ *
-+ * @return \Generator
-+ */
-+ public function getIterator($flags = 0)
-+ {
-+ $this->readPipesForOutput(__FUNCTION__, false);
-+
-+ $clearOutput = !(self::ITER_KEEP_OUTPUT & $flags);
-+ $blocking = !(self::ITER_NON_BLOCKING & $flags);
-+ $yieldOut = !(self::ITER_SKIP_OUT & $flags);
-+ $yieldErr = !(self::ITER_SKIP_ERR & $flags);
-+
-+ while (null !== $this->callback || ($yieldOut && !feof($this->stdout)) || ($yieldErr && !feof($this->stderr))) {
-+ if ($yieldOut) {
-+ $out = stream_get_contents($this->stdout, -1, $this->incrementalOutputOffset);
-+
-+ if (isset($out[0])) {
-+ if ($clearOutput) {
-+ $this->clearOutput();
-+ } else {
-+ $this->incrementalOutputOffset = ftell($this->stdout);
-+ }
-+
-+ yield self::OUT => $out;
-+ }
-+ }
-+
-+ if ($yieldErr) {
-+ $err = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
-+
-+ if (isset($err[0])) {
-+ if ($clearOutput) {
-+ $this->clearErrorOutput();
-+ } else {
-+ $this->incrementalErrorOutputOffset = ftell($this->stderr);
-+ }
-+
-+ yield self::ERR => $err;
-+ }
-+ }
-+
-+ if (!$blocking && !isset($out[0]) && !isset($err[0])) {
-+ yield self::OUT => '';
-+ }
-+
-+ $this->checkTimeout();
-+ $this->readPipesForOutput(__FUNCTION__, $blocking);
-+ }
-+ }
-+
-+ /**
-+ * Clears the process output.
-+ *
-+ * @return $this
-+ */
-+ public function clearOutput()
-+ {
-+ ftruncate($this->stdout, 0);
-+ fseek($this->stdout, 0);
-+ $this->incrementalOutputOffset = 0;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Returns the current error output of the process (STDERR).
-+ *
-+ * @return string The process error output
-+ *
-+ * @throws LogicException in case the output has been disabled
-+ * @throws LogicException In case the process is not started
-+ */
-+ public function getErrorOutput()
-+ {
-+ $this->readPipesForOutput(__FUNCTION__);
-+
-+ if (false === $ret = stream_get_contents($this->stderr, -1, 0)) {
-+ return '';
-+ }
-+
-+ return $ret;
-+ }
-+
-+ /**
-+ * Returns the errorOutput incrementally.
-+ *
-+ * In comparison with the getErrorOutput method which always return the
-+ * whole error output, this one returns the new error output since the last
-+ * call.
-+ *
-+ * @return string The process error output since the last call
-+ *
-+ * @throws LogicException in case the output has been disabled
-+ * @throws LogicException In case the process is not started
-+ */
-+ public function getIncrementalErrorOutput()
-+ {
-+ $this->readPipesForOutput(__FUNCTION__);
-+
-+ $latest = stream_get_contents($this->stderr, -1, $this->incrementalErrorOutputOffset);
-+ $this->incrementalErrorOutputOffset = ftell($this->stderr);
-+
-+ if (false === $latest) {
-+ return '';
-+ }
-+
-+ return $latest;
-+ }
-+
-+ /**
-+ * Clears the process output.
-+ *
-+ * @return $this
-+ */
-+ public function clearErrorOutput()
-+ {
-+ ftruncate($this->stderr, 0);
-+ fseek($this->stderr, 0);
-+ $this->incrementalErrorOutputOffset = 0;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Returns the exit code returned by the process.
-+ *
-+ * @return null|int The exit status code, null if the Process is not terminated
-+ *
-+ * @throws RuntimeException In case --enable-sigchild is activated and the sigchild compatibility mode is disabled
-+ */
-+ public function getExitCode()
-+ {
-+ if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');
-+ }
-+
-+ $this->updateStatus(false);
-+
-+ return $this->exitcode;
-+ }
-+
-+ /**
-+ * Returns a string representation for the exit code returned by the process.
-+ *
-+ * This method relies on the Unix exit code status standardization
-+ * and might not be relevant for other operating systems.
-+ *
-+ * @return null|string A string representation for the exit status code, null if the Process is not terminated
-+ *
-+ * @see http://tldp.org/LDP/abs/html/exitcodes.html
-+ * @see http://en.wikipedia.org/wiki/Unix_signal
-+ */
-+ public function getExitCodeText()
-+ {
-+ if (null === $exitcode = $this->getExitCode()) {
-+ return;
-+ }
-+
-+ return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
-+ }
-+
-+ /**
-+ * Checks if the process ended successfully.
-+ *
-+ * @return bool true if the process ended successfully, false otherwise
-+ */
-+ public function isSuccessful()
-+ {
-+ return 0 === $this->getExitCode();
-+ }
-+
-+ /**
-+ * Returns true if the child process has been terminated by an uncaught signal.
-+ *
-+ * It always returns false on Windows.
-+ *
-+ * @return bool
-+ *
-+ * @throws RuntimeException In case --enable-sigchild is activated
-+ * @throws LogicException In case the process is not terminated
-+ */
-+ public function hasBeenSignaled()
-+ {
-+ $this->requireProcessIsTerminated(__FUNCTION__);
-+
-+ if (!$this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
-+ }
-+
-+ return $this->processInformation['signaled'];
-+ }
-+
-+ /**
-+ * Returns the number of the signal that caused the child process to terminate its execution.
-+ *
-+ * It is only meaningful if hasBeenSignaled() returns true.
-+ *
-+ * @return int
-+ *
-+ * @throws RuntimeException In case --enable-sigchild is activated
-+ * @throws LogicException In case the process is not terminated
-+ */
-+ public function getTermSignal()
-+ {
-+ $this->requireProcessIsTerminated(__FUNCTION__);
-+
-+ if ($this->isSigchildEnabled() && (!$this->enhanceSigchildCompatibility || -1 === $this->processInformation['termsig'])) {
-+ throw new RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');
-+ }
-+
-+ return $this->processInformation['termsig'];
-+ }
-+
-+ /**
-+ * Returns true if the child process has been stopped by a signal.
-+ *
-+ * It always returns false on Windows.
-+ *
-+ * @return bool
-+ *
-+ * @throws LogicException In case the process is not terminated
-+ */
-+ public function hasBeenStopped()
-+ {
-+ $this->requireProcessIsTerminated(__FUNCTION__);
-+
-+ return $this->processInformation['stopped'];
-+ }
-+
-+ /**
-+ * Returns the number of the signal that caused the child process to stop its execution.
-+ *
-+ * It is only meaningful if hasBeenStopped() returns true.
-+ *
-+ * @return int
-+ *
-+ * @throws LogicException In case the process is not terminated
-+ */
-+ public function getStopSignal()
-+ {
-+ $this->requireProcessIsTerminated(__FUNCTION__);
-+
-+ return $this->processInformation['stopsig'];
-+ }
-+
-+ /**
-+ * Checks if the process is currently running.
-+ *
-+ * @return bool true if the process is currently running, false otherwise
-+ */
-+ public function isRunning()
-+ {
-+ if (self::STATUS_STARTED !== $this->status) {
-+ return false;
-+ }
-+
-+ $this->updateStatus(false);
-+
-+ return $this->processInformation['running'];
-+ }
-+
-+ /**
-+ * Checks if the process has been started with no regard to the current state.
-+ *
-+ * @return bool true if status is ready, false otherwise
-+ */
-+ public function isStarted()
-+ {
-+ return $this->status != self::STATUS_READY;
-+ }
-+
-+ /**
-+ * Checks if the process is terminated.
-+ *
-+ * @return bool true if process is terminated, false otherwise
-+ */
-+ public function isTerminated()
-+ {
-+ $this->updateStatus(false);
-+
-+ return $this->status == self::STATUS_TERMINATED;
-+ }
-+
-+ /**
-+ * Gets the process status.
-+ *
-+ * The status is one of: ready, started, terminated.
-+ *
-+ * @return string The current process status
-+ */
-+ public function getStatus()
-+ {
-+ $this->updateStatus(false);
-+
-+ return $this->status;
-+ }
-+
-+ /**
-+ * Stops the process.
-+ *
-+ * @param int|float $timeout The timeout in seconds
-+ * @param int $signal A POSIX signal to send in case the process has not stop at timeout, default is SIGKILL (9)
-+ *
-+ * @return int The exit-code of the process
-+ */
-+ public function stop($timeout = 10, $signal = null)
-+ {
-+ $timeoutMicro = microtime(true) + $timeout;
-+ if ($this->isRunning()) {
-+ // given `SIGTERM` may not be defined and that `proc_terminate` uses the constant value and not the constant itself, we use the same here
-+ $this->doSignal(15, false);
-+ do {
-+ usleep(1000);
-+ } while ($this->isRunning() && microtime(true) < $timeoutMicro);
-+
-+ if ($this->isRunning()) {
-+ // Avoid exception here: process is supposed to be running, but it might have stopped just
-+ // after this line. In any case, let's silently discard the error, we cannot do anything.
-+ $this->doSignal($signal ?: 9, false);
-+ }
-+ }
-+
-+ if ($this->isRunning()) {
-+ if (isset($this->fallbackStatus['pid'])) {
-+ unset($this->fallbackStatus['pid']);
-+
-+ return $this->stop(0, $signal);
-+ }
-+ $this->close();
-+ }
-+
-+ return $this->exitcode;
-+ }
-+
-+ /**
-+ * Adds a line to the STDOUT stream.
-+ *
-+ * @internal
-+ *
-+ * @param string $line The line to append
-+ */
-+ public function addOutput($line)
-+ {
-+ $this->lastOutputTime = microtime(true);
-+
-+ fseek($this->stdout, 0, SEEK_END);
-+ fwrite($this->stdout, $line);
-+ fseek($this->stdout, $this->incrementalOutputOffset);
-+ }
-+
-+ /**
-+ * Adds a line to the STDERR stream.
-+ *
-+ * @internal
-+ *
-+ * @param string $line The line to append
-+ */
-+ public function addErrorOutput($line)
-+ {
-+ $this->lastOutputTime = microtime(true);
-+
-+ fseek($this->stderr, 0, SEEK_END);
-+ fwrite($this->stderr, $line);
-+ fseek($this->stderr, $this->incrementalErrorOutputOffset);
-+ }
-+
-+ /**
-+ * Gets the command line to be executed.
-+ *
-+ * @return string The command to execute
-+ */
-+ public function getCommandLine()
-+ {
-+ return is_array($this->commandline) ? implode(' ', array_map(array($this, 'escapeArgument'), $this->commandline)) : $this->commandline;
-+ }
-+
-+ /**
-+ * Sets the command line to be executed.
-+ *
-+ * @param string|array $commandline The command to execute
-+ *
-+ * @return self The current Process instance
-+ */
-+ public function setCommandLine($commandline)
-+ {
-+ $this->commandline = $commandline;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Gets the process timeout (max. runtime).
-+ *
-+ * @return float|null The timeout in seconds or null if it's disabled
-+ */
-+ public function getTimeout()
-+ {
-+ return $this->timeout;
-+ }
-+
-+ /**
-+ * Gets the process idle timeout (max. time since last output).
-+ *
-+ * @return float|null The timeout in seconds or null if it's disabled
-+ */
-+ public function getIdleTimeout()
-+ {
-+ return $this->idleTimeout;
-+ }
-+
-+ /**
-+ * Sets the process timeout (max. runtime).
-+ *
-+ * To disable the timeout, set this value to null.
-+ *
-+ * @param int|float|null $timeout The timeout in seconds
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @throws InvalidArgumentException if the timeout is negative
-+ */
-+ public function setTimeout($timeout)
-+ {
-+ $this->timeout = $this->validateTimeout($timeout);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets the process idle timeout (max. time since last output).
-+ *
-+ * To disable the timeout, set this value to null.
-+ *
-+ * @param int|float|null $timeout The timeout in seconds
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @throws LogicException if the output is disabled
-+ * @throws InvalidArgumentException if the timeout is negative
-+ */
-+ public function setIdleTimeout($timeout)
-+ {
-+ if (null !== $timeout && $this->outputDisabled) {
-+ throw new LogicException('Idle timeout can not be set while the output is disabled.');
-+ }
-+
-+ $this->idleTimeout = $this->validateTimeout($timeout);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Enables or disables the TTY mode.
-+ *
-+ * @param bool $tty True to enabled and false to disable
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @throws RuntimeException In case the TTY mode is not supported
-+ */
-+ public function setTty($tty)
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR && $tty) {
-+ throw new RuntimeException('TTY mode is not supported on Windows platform.');
-+ }
-+ if ($tty) {
-+ static $isTtySupported;
-+
-+ if (null === $isTtySupported) {
-+ $isTtySupported = (bool) @proc_open('echo 1 >/dev/null', array(array('file', '/dev/tty', 'r'), array('file', '/dev/tty', 'w'), array('file', '/dev/tty', 'w')), $pipes);
-+ }
-+
-+ if (!$isTtySupported) {
-+ throw new RuntimeException('TTY mode requires /dev/tty to be read/writable.');
-+ }
-+ }
-+
-+ $this->tty = (bool) $tty;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Checks if the TTY mode is enabled.
-+ *
-+ * @return bool true if the TTY mode is enabled, false otherwise
-+ */
-+ public function isTty()
-+ {
-+ return $this->tty;
-+ }
-+
-+ /**
-+ * Sets PTY mode.
-+ *
-+ * @param bool $bool
-+ *
-+ * @return self
-+ */
-+ public function setPty($bool)
-+ {
-+ $this->pty = (bool) $bool;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Returns PTY state.
-+ *
-+ * @return bool
-+ */
-+ public function isPty()
-+ {
-+ return $this->pty;
-+ }
-+
-+ /**
-+ * Gets the working directory.
-+ *
-+ * @return string|null The current working directory or null on failure
-+ */
-+ public function getWorkingDirectory()
-+ {
-+ if (null === $this->cwd) {
-+ // getcwd() will return false if any one of the parent directories does not have
-+ // the readable or search mode set, even if the current directory does
-+ return getcwd() ?: null;
-+ }
-+
-+ return $this->cwd;
-+ }
-+
-+ /**
-+ * Sets the current working directory.
-+ *
-+ * @param string $cwd The new working directory
-+ *
-+ * @return self The current Process instance
-+ */
-+ public function setWorkingDirectory($cwd)
-+ {
-+ $this->cwd = $cwd;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Gets the environment variables.
-+ *
-+ * @return array The current environment variables
-+ */
-+ public function getEnv()
-+ {
-+ return $this->env;
-+ }
-+
-+ /**
-+ * Sets the environment variables.
-+ *
-+ * An environment variable value should be a string.
-+ * If it is an array, the variable is ignored.
-+ * If it is false or null, it will be removed when
-+ * env vars are otherwise inherited.
-+ *
-+ * That happens in PHP when 'argv' is registered into
-+ * the $_ENV array for instance.
-+ *
-+ * @param array $env The new environment variables
-+ *
-+ * @return self The current Process instance
-+ */
-+ public function setEnv(array $env)
-+ {
-+ // Process can not handle env values that are arrays
-+ $env = array_filter($env, function ($value) {
-+ return !is_array($value);
-+ });
-+
-+ $this->env = $env;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Gets the Process input.
-+ *
-+ * @return resource|string|\Iterator|null The Process input
-+ */
-+ public function getInput()
-+ {
-+ return $this->input;
-+ }
-+
-+ /**
-+ * Sets the input.
-+ *
-+ * This content will be passed to the underlying process standard input.
-+ *
-+ * @param resource|scalar|\Traversable|null $input The content
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @throws LogicException In case the process is running
-+ */
-+ public function setInput($input)
-+ {
-+ if ($this->isRunning()) {
-+ throw new LogicException('Input can not be set while the process is running.');
-+ }
-+
-+ $this->input = ProcessUtils::validateInput(__METHOD__, $input);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Gets the options for proc_open.
-+ *
-+ * @return array The current options
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0.
-+ */
-+ public function getOptions()
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
-+
-+ return $this->options;
-+ }
-+
-+ /**
-+ * Sets the options for proc_open.
-+ *
-+ * @param array $options The new options
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0.
-+ */
-+ public function setOptions(array $options)
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
-+
-+ $this->options = $options;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Gets whether or not Windows compatibility is enabled.
-+ *
-+ * This is true by default.
-+ *
-+ * @return bool
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0. Enhanced Windows compatibility will always be enabled.
-+ */
-+ public function getEnhanceWindowsCompatibility()
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Enhanced Windows compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
-+
-+ return $this->enhanceWindowsCompatibility;
-+ }
-+
-+ /**
-+ * Sets whether or not Windows compatibility is enabled.
-+ *
-+ * @param bool $enhance
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0. Enhanced Windows compatibility will always be enabled.
-+ */
-+ public function setEnhanceWindowsCompatibility($enhance)
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Enhanced Windows compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
-+
-+ $this->enhanceWindowsCompatibility = (bool) $enhance;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Returns whether sigchild compatibility mode is activated or not.
-+ *
-+ * @return bool
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0. Sigchild compatibility will always be enabled.
-+ */
-+ public function getEnhanceSigchildCompatibility()
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
-+
-+ return $this->enhanceSigchildCompatibility;
-+ }
-+
-+ /**
-+ * Activates sigchild compatibility mode.
-+ *
-+ * Sigchild compatibility mode is required to get the exit code and
-+ * determine the success of a process when PHP has been compiled with
-+ * the --enable-sigchild option
-+ *
-+ * @param bool $enhance
-+ *
-+ * @return self The current Process instance
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0.
-+ */
-+ public function setEnhanceSigchildCompatibility($enhance)
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Sigchild compatibility will always be enabled.', __METHOD__), E_USER_DEPRECATED);
-+
-+ $this->enhanceSigchildCompatibility = (bool) $enhance;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets whether environment variables will be inherited or not.
-+ *
-+ * @param bool $inheritEnv
-+ *
-+ * @return self The current Process instance
-+ */
-+ public function inheritEnvironmentVariables($inheritEnv = true)
-+ {
-+ if (!$inheritEnv) {
-+ @trigger_error('Not inheriting environment variables is deprecated since Symfony 3.3 and will always happen in 4.0. Set "Process::inheritEnvironmentVariables()" to true instead.', E_USER_DEPRECATED);
-+ }
-+
-+ $this->inheritEnv = (bool) $inheritEnv;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Returns whether environment variables will be inherited or not.
-+ *
-+ * @return bool
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0. Environment variables will always be inherited.
-+ */
-+ public function areEnvironmentVariablesInherited()
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Environment variables will always be inherited.', __METHOD__), E_USER_DEPRECATED);
-+
-+ return $this->inheritEnv;
-+ }
-+
-+ /**
-+ * Performs a check between the timeout definition and the time the process started.
-+ *
-+ * In case you run a background process (with the start method), you should
-+ * trigger this method regularly to ensure the process timeout
-+ *
-+ * @throws ProcessTimedOutException In case the timeout was reached
-+ */
-+ public function checkTimeout()
-+ {
-+ if ($this->status !== self::STATUS_STARTED) {
-+ return;
-+ }
-+
-+ if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {
-+ $this->stop(0);
-+
-+ throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_GENERAL);
-+ }
-+
-+ if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {
-+ $this->stop(0);
-+
-+ throw new ProcessTimedOutException($this, ProcessTimedOutException::TYPE_IDLE);
-+ }
-+ }
-+
-+ /**
-+ * Returns whether PTY is supported on the current operating system.
-+ *
-+ * @return bool
-+ */
-+ public static function isPtySupported()
-+ {
-+ static $result;
-+
-+ if (null !== $result) {
-+ return $result;
-+ }
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ return $result = false;
-+ }
-+
-+ return $result = (bool) @proc_open('echo 1 >/dev/null', array(array('pty'), array('pty'), array('pty')), $pipes);
-+ }
-+
-+ /**
-+ * Creates the descriptors needed by the proc_open.
-+ *
-+ * @return array
-+ */
-+ private function getDescriptors()
-+ {
-+ if ($this->input instanceof \Iterator) {
-+ $this->input->rewind();
-+ }
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->processPipes = new WindowsPipes($this->input, !$this->outputDisabled || $this->hasCallback);
-+ } else {
-+ $this->processPipes = new UnixPipes($this->isTty(), $this->isPty(), $this->input, !$this->outputDisabled || $this->hasCallback);
-+ }
-+
-+ return $this->processPipes->getDescriptors();
-+ }
-+
-+ /**
-+ * Builds up the callback used by wait().
-+ *
-+ * The callbacks adds all occurred output to the specific buffer and calls
-+ * the user callback (if present) with the received output.
-+ *
-+ * @param callable|null $callback The user defined PHP callback
-+ *
-+ * @return \Closure A PHP closure
-+ */
-+ protected function buildCallback(callable $callback = null)
-+ {
-+ if ($this->outputDisabled) {
-+ return function ($type, $data) use ($callback) {
-+ if (null !== $callback) {
-+ call_user_func($callback, $type, $data);
-+ }
-+ };
-+ }
-+
-+ $out = self::OUT;
-+
-+ return function ($type, $data) use ($callback, $out) {
-+ if ($out == $type) {
-+ $this->addOutput($data);
-+ } else {
-+ $this->addErrorOutput($data);
-+ }
-+
-+ if (null !== $callback) {
-+ call_user_func($callback, $type, $data);
-+ }
-+ };
-+ }
-+
-+ /**
-+ * Updates the status of the process, reads pipes.
-+ *
-+ * @param bool $blocking Whether to use a blocking read call
-+ */
-+ protected function updateStatus($blocking)
-+ {
-+ if (self::STATUS_STARTED !== $this->status) {
-+ return;
-+ }
-+
-+ $this->processInformation = proc_get_status($this->process);
-+ $running = $this->processInformation['running'];
-+
-+ $this->readPipes($running && $blocking, '\\' !== DIRECTORY_SEPARATOR || !$running);
-+
-+ if ($this->fallbackStatus && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-+ $this->processInformation = $this->fallbackStatus + $this->processInformation;
-+ }
-+
-+ if (!$running) {
-+ $this->close();
-+ }
-+ }
-+
-+ /**
-+ * Returns whether PHP has been compiled with the '--enable-sigchild' option or not.
-+ *
-+ * @return bool
-+ */
-+ protected function isSigchildEnabled()
-+ {
-+ if (null !== self::$sigchild) {
-+ return self::$sigchild;
-+ }
-+
-+ if (!function_exists('phpinfo') || defined('HHVM_VERSION')) {
-+ return self::$sigchild = false;
-+ }
-+
-+ ob_start();
-+ phpinfo(INFO_GENERAL);
-+
-+ return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
-+ }
-+
-+ /**
-+ * Reads pipes for the freshest output.
-+ *
-+ * @param string $caller The name of the method that needs fresh outputs
-+ * @param bool $blocking Whether to use blocking calls or not
-+ *
-+ * @throws LogicException in case output has been disabled or process is not started
-+ */
-+ private function readPipesForOutput($caller, $blocking = false)
-+ {
-+ if ($this->outputDisabled) {
-+ throw new LogicException('Output has been disabled.');
-+ }
-+
-+ $this->requireProcessIsStarted($caller);
-+
-+ $this->updateStatus($blocking);
-+ }
-+
-+ /**
-+ * Validates and returns the filtered timeout.
-+ *
-+ * @param int|float|null $timeout
-+ *
-+ * @return float|null
-+ *
-+ * @throws InvalidArgumentException if the given timeout is a negative number
-+ */
-+ private function validateTimeout($timeout)
-+ {
-+ $timeout = (float) $timeout;
-+
-+ if (0.0 === $timeout) {
-+ $timeout = null;
-+ } elseif ($timeout < 0) {
-+ throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
-+ }
-+
-+ return $timeout;
-+ }
-+
-+ /**
-+ * Reads pipes, executes callback.
-+ *
-+ * @param bool $blocking Whether to use blocking calls or not
-+ * @param bool $close Whether to close file handles or not
-+ */
-+ private function readPipes($blocking, $close)
-+ {
-+ $result = $this->processPipes->readAndWrite($blocking, $close);
-+
-+ $callback = $this->callback;
-+ foreach ($result as $type => $data) {
-+ if (3 !== $type) {
-+ $callback($type === self::STDOUT ? self::OUT : self::ERR, $data);
-+ } elseif (!isset($this->fallbackStatus['signaled'])) {
-+ $this->fallbackStatus['exitcode'] = (int) $data;
-+ }
-+ }
-+ }
-+
-+ /**
-+ * Closes process resource, closes file handles, sets the exitcode.
-+ *
-+ * @return int The exitcode
-+ */
-+ private function close()
-+ {
-+ $this->processPipes->close();
-+ if (is_resource($this->process)) {
-+ proc_close($this->process);
-+ }
-+ $this->exitcode = $this->processInformation['exitcode'];
-+ $this->status = self::STATUS_TERMINATED;
-+
-+ if (-1 === $this->exitcode) {
-+ if ($this->processInformation['signaled'] && 0 < $this->processInformation['termsig']) {
-+ // if process has been signaled, no exitcode but a valid termsig, apply Unix convention
-+ $this->exitcode = 128 + $this->processInformation['termsig'];
-+ } elseif ($this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {
-+ $this->processInformation['signaled'] = true;
-+ $this->processInformation['termsig'] = -1;
-+ }
-+ }
-+
-+ // Free memory from self-reference callback created by buildCallback
-+ // Doing so in other contexts like __destruct or by garbage collector is ineffective
-+ // Now pipes are closed, so the callback is no longer necessary
-+ $this->callback = null;
-+
-+ return $this->exitcode;
-+ }
-+
-+ /**
-+ * Resets data related to the latest run of the process.
-+ */
-+ private function resetProcessData()
-+ {
-+ $this->starttime = null;
-+ $this->callback = null;
-+ $this->exitcode = null;
-+ $this->fallbackStatus = array();
-+ $this->processInformation = null;
-+ $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
-+ $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'wb+');
-+ $this->process = null;
-+ $this->latestSignal = null;
-+ $this->status = self::STATUS_READY;
-+ $this->incrementalOutputOffset = 0;
-+ $this->incrementalErrorOutputOffset = 0;
-+ }
-+
-+ /**
-+ * Sends a POSIX signal to the process.
-+ *
-+ * @param int $signal A valid POSIX signal (see http://www.php.net/manual/en/pcntl.constants.php)
-+ * @param bool $throwException Whether to throw exception in case signal failed
-+ *
-+ * @return bool True if the signal was sent successfully, false otherwise
-+ *
-+ * @throws LogicException In case the process is not running
-+ * @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
-+ * @throws RuntimeException In case of failure
-+ */
-+ private function doSignal($signal, $throwException)
-+ {
-+ if (null === $pid = $this->getPid()) {
-+ if ($throwException) {
-+ throw new LogicException('Can not send signal on a non running process.');
-+ }
-+
-+ return false;
-+ }
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ exec(sprintf('taskkill /F /T /PID %d 2>&1', $pid), $output, $exitCode);
-+ if ($exitCode && $this->isRunning()) {
-+ if ($throwException) {
-+ throw new RuntimeException(sprintf('Unable to kill the process (%s).', implode(' ', $output)));
-+ }
-+
-+ return false;
-+ }
-+ } else {
-+ if (!$this->enhanceSigchildCompatibility || !$this->isSigchildEnabled()) {
-+ $ok = @proc_terminate($this->process, $signal);
-+ } elseif (function_exists('posix_kill')) {
-+ $ok = @posix_kill($pid, $signal);
-+ } elseif ($ok = proc_open(sprintf('kill -%d %d', $signal, $pid), array(2 => array('pipe', 'w')), $pipes)) {
-+ $ok = false === fgets($pipes[2]);
-+ }
-+ if (!$ok) {
-+ if ($throwException) {
-+ throw new RuntimeException(sprintf('Error while sending signal `%s`.', $signal));
-+ }
-+
-+ return false;
-+ }
-+ }
-+
-+ $this->latestSignal = (int) $signal;
-+ $this->fallbackStatus['signaled'] = true;
-+ $this->fallbackStatus['exitcode'] = -1;
-+ $this->fallbackStatus['termsig'] = $this->latestSignal;
-+
-+ return true;
-+ }
-+
-+ private function prepareWindowsCommandLine($cmd, array &$envBackup, array &$env = null)
-+ {
-+ $uid = uniqid('', true);
-+ $varCount = 0;
-+ $varCache = array();
-+ $cmd = preg_replace_callback(
-+ '/"(?:(
-+ [^"%!^]*+
-+ (?:
-+ (?: !LF! | "(?:\^[%!^])?+" )
-+ [^"%!^]*+
-+ )++
-+ ) | [^"]*+ )"/x',
-+ function ($m) use (&$envBackup, &$env, &$varCache, &$varCount, $uid) {
-+ if (!isset($m[1])) {
-+ return $m[0];
-+ }
-+ if (isset($varCache[$m[0]])) {
-+ return $varCache[$m[0]];
-+ }
-+ if (false !== strpos($value = $m[1], "\0")) {
-+ $value = str_replace("\0", '?', $value);
-+ }
-+ if (false === strpbrk($value, "\"%!\n")) {
-+ return '"'.$value.'"';
-+ }
-+
-+ $value = str_replace(array('!LF!', '"^!"', '"^%"', '"^^"', '""'), array("\n", '!', '%', '^', '"'), $value);
-+ $value = '"'.preg_replace('/(\\\\*)"/', '$1$1\\"', $value).'"';
-+ $var = $uid.++$varCount;
-+
-+ if (null === $env) {
-+ putenv("$var=$value");
-+ } else {
-+ $env[$var] = $value;
-+ }
-+
-+ $envBackup[$var] = false;
-+
-+ return $varCache[$m[0]] = '!'.$var.'!';
-+ },
-+ $cmd
-+ );
-+
-+ $cmd = 'cmd /V:ON /E:ON /D /C ('.str_replace("\n", ' ', $cmd).')';
-+ foreach ($this->processPipes->getFiles() as $offset => $filename) {
-+ $cmd .= ' '.$offset.'>"'.$filename.'"';
-+ }
-+
-+ return $cmd;
-+ }
-+
-+ /**
-+ * Ensures the process is running or terminated, throws a LogicException if the process has a not started.
-+ *
-+ * @param string $functionName The function name that was called
-+ *
-+ * @throws LogicException If the process has not run.
-+ */
-+ private function requireProcessIsStarted($functionName)
-+ {
-+ if (!$this->isStarted()) {
-+ throw new LogicException(sprintf('Process must be started before calling %s.', $functionName));
-+ }
-+ }
-+
-+ /**
-+ * Ensures the process is terminated, throws a LogicException if the process has a status different than `terminated`.
-+ *
-+ * @param string $functionName The function name that was called
-+ *
-+ * @throws LogicException If the process is not yet terminated.
-+ */
-+ private function requireProcessIsTerminated($functionName)
-+ {
-+ if (!$this->isTerminated()) {
-+ throw new LogicException(sprintf('Process must be terminated before calling %s.', $functionName));
-+ }
-+ }
-+
-+ /**
-+ * Escapes a string to be used as a shell argument.
-+ *
-+ * @param string $argument The argument that will be escaped
-+ *
-+ * @return string The escaped argument
-+ */
-+ private function escapeArgument($argument)
-+ {
-+ if ('\\' !== DIRECTORY_SEPARATOR) {
-+ return "'".str_replace("'", "'\\''", $argument)."'";
-+ }
-+ if ('' === $argument = (string) $argument) {
-+ return '""';
-+ }
-+ if (false !== strpos($argument, "\0")) {
-+ $argument = str_replace("\0", '?', $argument);
-+ }
-+ if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) {
-+ return $argument;
-+ }
-+ $argument = preg_replace('/(\\\\+)$/', '$1$1', $argument);
-+
-+ return '"'.str_replace(array('"', '^', '%', '!', "\n"), array('""', '"^^"', '"^%"', '"^!"', '!LF!'), $argument).'"';
-+ }
-+}
-diff --git a/vendor/symfony/process/ProcessBuilder.php b/vendor/symfony/process/ProcessBuilder.php
-new file mode 100644
-index 00000000..36db35ed
---- /dev/null
-+++ b/vendor/symfony/process/ProcessBuilder.php
-@@ -0,0 +1,288 @@
-+<?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\Process;
-+
-+use Symfony\Component\Process\Exception\InvalidArgumentException;
-+use Symfony\Component\Process\Exception\LogicException;
-+
-+/**
-+ * Process builder.
-+ *
-+ * @author Kris Wallsmith <kris@symfony.com>
-+ */
-+class ProcessBuilder
-+{
-+ private $arguments;
-+ private $cwd;
-+ private $env = array();
-+ private $input;
-+ private $timeout = 60;
-+ private $options;
-+ private $inheritEnv = true;
-+ private $prefix = array();
-+ private $outputDisabled = false;
-+
-+ /**
-+ * Constructor.
-+ *
-+ * @param string[] $arguments An array of arguments
-+ */
-+ public function __construct(array $arguments = array())
-+ {
-+ $this->arguments = $arguments;
-+ }
-+
-+ /**
-+ * Creates a process builder instance.
-+ *
-+ * @param string[] $arguments An array of arguments
-+ *
-+ * @return static
-+ */
-+ public static function create(array $arguments = array())
-+ {
-+ return new static($arguments);
-+ }
-+
-+ /**
-+ * Adds an unescaped argument to the command string.
-+ *
-+ * @param string $argument A command argument
-+ *
-+ * @return $this
-+ */
-+ public function add($argument)
-+ {
-+ $this->arguments[] = $argument;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Adds a prefix to the command string.
-+ *
-+ * The prefix is preserved when resetting arguments.
-+ *
-+ * @param string|array $prefix A command prefix or an array of command prefixes
-+ *
-+ * @return $this
-+ */
-+ public function setPrefix($prefix)
-+ {
-+ $this->prefix = is_array($prefix) ? $prefix : array($prefix);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets the arguments of the process.
-+ *
-+ * Arguments must not be escaped.
-+ * Previous arguments are removed.
-+ *
-+ * @param string[] $arguments
-+ *
-+ * @return $this
-+ */
-+ public function setArguments(array $arguments)
-+ {
-+ $this->arguments = $arguments;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets the working directory.
-+ *
-+ * @param null|string $cwd The working directory
-+ *
-+ * @return $this
-+ */
-+ public function setWorkingDirectory($cwd)
-+ {
-+ $this->cwd = $cwd;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets whether environment variables will be inherited or not.
-+ *
-+ * @param bool $inheritEnv
-+ *
-+ * @return $this
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0.
-+ */
-+ public function inheritEnvironmentVariables($inheritEnv = true)
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
-+
-+ $this->inheritEnv = $inheritEnv;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets an environment variable.
-+ *
-+ * Setting a variable overrides its previous value. Use `null` to unset a
-+ * defined environment variable.
-+ *
-+ * @param string $name The variable name
-+ * @param null|string $value The variable value
-+ *
-+ * @return $this
-+ */
-+ public function setEnv($name, $value)
-+ {
-+ $this->env[$name] = $value;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Adds a set of environment variables.
-+ *
-+ * Already existing environment variables with the same name will be
-+ * overridden by the new values passed to this method. Pass `null` to unset
-+ * a variable.
-+ *
-+ * @param array $variables The variables
-+ *
-+ * @return $this
-+ */
-+ public function addEnvironmentVariables(array $variables)
-+ {
-+ $this->env = array_replace($this->env, $variables);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets the input of the process.
-+ *
-+ * @param resource|scalar|\Traversable|null $input The input content
-+ *
-+ * @return $this
-+ *
-+ * @throws InvalidArgumentException In case the argument is invalid
-+ */
-+ public function setInput($input)
-+ {
-+ $this->input = ProcessUtils::validateInput(__METHOD__, $input);
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Sets the process timeout.
-+ *
-+ * To disable the timeout, set this value to null.
-+ *
-+ * @param float|null $timeout
-+ *
-+ * @return $this
-+ *
-+ * @throws InvalidArgumentException
-+ */
-+ public function setTimeout($timeout)
-+ {
-+ if (null === $timeout) {
-+ $this->timeout = null;
-+
-+ return $this;
-+ }
-+
-+ $timeout = (float) $timeout;
-+
-+ if ($timeout < 0) {
-+ throw new InvalidArgumentException('The timeout value must be a valid positive integer or float number.');
-+ }
-+
-+ $this->timeout = $timeout;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Adds a proc_open option.
-+ *
-+ * @param string $name The option name
-+ * @param string $value The option value
-+ *
-+ * @return $this
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0.
-+ */
-+ public function setOption($name, $value)
-+ {
-+ @trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0.', __METHOD__), E_USER_DEPRECATED);
-+
-+ $this->options[$name] = $value;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Disables fetching output and error output from the underlying process.
-+ *
-+ * @return $this
-+ */
-+ public function disableOutput()
-+ {
-+ $this->outputDisabled = true;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Enables fetching output and error output from the underlying process.
-+ *
-+ * @return $this
-+ */
-+ public function enableOutput()
-+ {
-+ $this->outputDisabled = false;
-+
-+ return $this;
-+ }
-+
-+ /**
-+ * Creates a Process instance and returns it.
-+ *
-+ * @return Process
-+ *
-+ * @throws LogicException In case no arguments have been provided
-+ */
-+ public function getProcess()
-+ {
-+ if (0 === count($this->prefix) && 0 === count($this->arguments)) {
-+ throw new LogicException('You must add() command arguments before calling getProcess().');
-+ }
-+
-+ $arguments = array_merge($this->prefix, $this->arguments);
-+ $process = new Process($arguments, $this->cwd, $this->env, $this->input, $this->timeout, $this->options);
-+ // to preserve the BC with symfony <3.3, we convert the array structure
-+ // to a string structure to avoid the prefixing with the exec command
-+ $process->setCommandLine($process->getCommandLine());
-+
-+ if ($this->inheritEnv) {
-+ $process->inheritEnvironmentVariables();
-+ }
-+ if ($this->outputDisabled) {
-+ $process->disableOutput();
-+ }
-+
-+ return $process;
-+ }
-+}
-diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php
-new file mode 100644
-index 00000000..24438d98
---- /dev/null
-+++ b/vendor/symfony/process/ProcessUtils.php
-@@ -0,0 +1,123 @@
-+<?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\Process;
-+
-+use Symfony\Component\Process\Exception\InvalidArgumentException;
-+
-+/**
-+ * ProcessUtils is a bunch of utility methods.
-+ *
-+ * This class contains static methods only and is not meant to be instantiated.
-+ *
-+ * @author Martin Hasoň <martin.hason@gmail.com>
-+ */
-+class ProcessUtils
-+{
-+ /**
-+ * This class should not be instantiated.
-+ */
-+ private function __construct()
-+ {
-+ }
-+
-+ /**
-+ * Escapes a string to be used as a shell argument.
-+ *
-+ * @param string $argument The argument that will be escaped
-+ *
-+ * @return string The escaped argument
-+ *
-+ * @deprecated since version 3.3, to be removed in 4.0. Use a command line array or give env vars to the `Process::start/run()` method instead.
-+ */
-+ public static function escapeArgument($argument)
-+ {
-+ @trigger_error('The '.__METHOD__.'() method is deprecated since version 3.3 and will be removed in 4.0. Use a command line array or give env vars to the Process::start/run() method instead.', E_USER_DEPRECATED);
-+
-+ //Fix for PHP bug #43784 escapeshellarg removes % from given string
-+ //Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
-+ //@see https://bugs.php.net/bug.php?id=43784
-+ //@see https://bugs.php.net/bug.php?id=49446
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ if ('' === $argument) {
-+ return escapeshellarg($argument);
-+ }
-+
-+ $escapedArgument = '';
-+ $quote = false;
-+ foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
-+ if ('"' === $part) {
-+ $escapedArgument .= '\\"';
-+ } elseif (self::isSurroundedBy($part, '%')) {
-+ // Avoid environment variable expansion
-+ $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
-+ } else {
-+ // escape trailing backslash
-+ if ('\\' === substr($part, -1)) {
-+ $part .= '\\';
-+ }
-+ $quote = true;
-+ $escapedArgument .= $part;
-+ }
-+ }
-+ if ($quote) {
-+ $escapedArgument = '"'.$escapedArgument.'"';
-+ }
-+
-+ return $escapedArgument;
-+ }
-+
-+ return "'".str_replace("'", "'\\''", $argument)."'";
-+ }
-+
-+ /**
-+ * Validates and normalizes a Process input.
-+ *
-+ * @param string $caller The name of method call that validates the input
-+ * @param mixed $input The input to validate
-+ *
-+ * @return mixed The validated input
-+ *
-+ * @throws InvalidArgumentException In case the input is not valid
-+ */
-+ public static function validateInput($caller, $input)
-+ {
-+ if (null !== $input) {
-+ if (is_resource($input)) {
-+ return $input;
-+ }
-+ if (is_string($input)) {
-+ return $input;
-+ }
-+ if (is_scalar($input)) {
-+ return (string) $input;
-+ }
-+ if ($input instanceof Process) {
-+ return $input->getIterator($input::ITER_SKIP_ERR);
-+ }
-+ if ($input instanceof \Iterator) {
-+ return $input;
-+ }
-+ if ($input instanceof \Traversable) {
-+ return new \IteratorIterator($input);
-+ }
-+
-+ throw new InvalidArgumentException(sprintf('%s only accepts strings, Traversable objects or stream resources.', $caller));
-+ }
-+
-+ return $input;
-+ }
-+
-+ private static function isSurroundedBy($arg, $char)
-+ {
-+ return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
-+ }
-+}
-diff --git a/vendor/symfony/process/README.md b/vendor/symfony/process/README.md
-new file mode 100644
-index 00000000..b7ca5b42
---- /dev/null
-+++ b/vendor/symfony/process/README.md
-@@ -0,0 +1,13 @@
-+Process Component
-+=================
-+
-+The Process component executes commands in sub-processes.
-+
-+Resources
-+---------
-+
-+ * [Documentation](https://symfony.com/doc/current/components/process.html)
-+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
-+ * [Report issues](https://github.com/symfony/symfony/issues) and
-+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
-+ in the [main Symfony repository](https://github.com/symfony/symfony)
-diff --git a/vendor/symfony/process/Tests/ExecutableFinderTest.php b/vendor/symfony/process/Tests/ExecutableFinderTest.php
-new file mode 100644
-index 00000000..bc692f6a
---- /dev/null
-+++ b/vendor/symfony/process/Tests/ExecutableFinderTest.php
-@@ -0,0 +1,133 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\ExecutableFinder;
-+
-+/**
-+ * @author Chris Smith <chris@cs278.org>
-+ */
-+class ExecutableFinderTest extends TestCase
-+{
-+ private $path;
-+
-+ protected function tearDown()
-+ {
-+ if ($this->path) {
-+ // Restore path if it was changed.
-+ putenv('PATH='.$this->path);
-+ }
-+ }
-+
-+ private function setPath($path)
-+ {
-+ $this->path = getenv('PATH');
-+ putenv('PATH='.$path);
-+ }
-+
-+ public function testFind()
-+ {
-+ if (ini_get('open_basedir')) {
-+ $this->markTestSkipped('Cannot test when open_basedir is set');
-+ }
-+
-+ $this->setPath(dirname(PHP_BINARY));
-+
-+ $finder = new ExecutableFinder();
-+ $result = $finder->find($this->getPhpBinaryName());
-+
-+ $this->assertSamePath(PHP_BINARY, $result);
-+ }
-+
-+ public function testFindWithDefault()
-+ {
-+ if (ini_get('open_basedir')) {
-+ $this->markTestSkipped('Cannot test when open_basedir is set');
-+ }
-+
-+ $expected = 'defaultValue';
-+
-+ $this->setPath('');
-+
-+ $finder = new ExecutableFinder();
-+ $result = $finder->find('foo', $expected);
-+
-+ $this->assertEquals($expected, $result);
-+ }
-+
-+ public function testFindWithExtraDirs()
-+ {
-+ if (ini_get('open_basedir')) {
-+ $this->markTestSkipped('Cannot test when open_basedir is set');
-+ }
-+
-+ $this->setPath('');
-+
-+ $extraDirs = array(dirname(PHP_BINARY));
-+
-+ $finder = new ExecutableFinder();
-+ $result = $finder->find($this->getPhpBinaryName(), null, $extraDirs);
-+
-+ $this->assertSamePath(PHP_BINARY, $result);
-+ }
-+
-+ public function testFindWithOpenBaseDir()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Cannot run test on windows');
-+ }
-+
-+ if (ini_get('open_basedir')) {
-+ $this->markTestSkipped('Cannot test when open_basedir is set');
-+ }
-+
-+ $this->iniSet('open_basedir', dirname(PHP_BINARY).(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));
-+
-+ $finder = new ExecutableFinder();
-+ $result = $finder->find($this->getPhpBinaryName());
-+
-+ $this->assertSamePath(PHP_BINARY, $result);
-+ }
-+
-+ public function testFindProcessInOpenBasedir()
-+ {
-+ if (ini_get('open_basedir')) {
-+ $this->markTestSkipped('Cannot test when open_basedir is set');
-+ }
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Cannot run test on windows');
-+ }
-+
-+ $this->setPath('');
-+ $this->iniSet('open_basedir', PHP_BINARY.(!defined('HHVM_VERSION') || HHVM_VERSION_ID >= 30800 ? PATH_SEPARATOR.'/' : ''));
-+
-+ $finder = new ExecutableFinder();
-+ $result = $finder->find($this->getPhpBinaryName(), false);
-+
-+ $this->assertSamePath(PHP_BINARY, $result);
-+ }
-+
-+ private function assertSamePath($expected, $tested)
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals(strtolower($expected), strtolower($tested));
-+ } else {
-+ $this->assertEquals($expected, $tested);
-+ }
-+ }
-+
-+ private function getPhpBinaryName()
-+ {
-+ return basename(PHP_BINARY, '\\' === DIRECTORY_SEPARATOR ? '.exe' : '');
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/NonStopableProcess.php b/vendor/symfony/process/Tests/NonStopableProcess.php
-new file mode 100644
-index 00000000..56432596
---- /dev/null
-+++ b/vendor/symfony/process/Tests/NonStopableProcess.php
-@@ -0,0 +1,47 @@
-+<?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.
-+ */
-+
-+/**
-+ * Runs a PHP script that can be stopped only with a SIGKILL (9) signal for 3 seconds.
-+ *
-+ * @args duration Run this script with a custom duration
-+ *
-+ * @example `php NonStopableProcess.php 42` will run the script for 42 seconds
-+ */
-+function handleSignal($signal)
-+{
-+ switch ($signal) {
-+ case SIGTERM:
-+ $name = 'SIGTERM';
-+ break;
-+ case SIGINT:
-+ $name = 'SIGINT';
-+ break;
-+ default:
-+ $name = $signal.' (unknown)';
-+ break;
-+ }
-+
-+ echo "signal $name\n";
-+}
-+
-+pcntl_signal(SIGTERM, 'handleSignal');
-+pcntl_signal(SIGINT, 'handleSignal');
-+
-+echo 'received ';
-+
-+$duration = isset($argv[1]) ? (int) $argv[1] : 3;
-+$start = microtime(true);
-+
-+while ($duration > (microtime(true) - $start)) {
-+ usleep(10000);
-+ pcntl_signal_dispatch();
-+}
-diff --git a/vendor/symfony/process/Tests/PhpExecutableFinderTest.php b/vendor/symfony/process/Tests/PhpExecutableFinderTest.php
-new file mode 100644
-index 00000000..b08ad5d3
---- /dev/null
-+++ b/vendor/symfony/process/Tests/PhpExecutableFinderTest.php
-@@ -0,0 +1,72 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\PhpExecutableFinder;
-+
-+/**
-+ * @author Robert Schönthal <seroscho@googlemail.com>
-+ */
-+class PhpExecutableFinderTest extends TestCase
-+{
-+ /**
-+ * tests find() with the constant PHP_BINARY.
-+ */
-+ public function testFind()
-+ {
-+ if (defined('HHVM_VERSION')) {
-+ $this->markTestSkipped('Should not be executed in HHVM context.');
-+ }
-+
-+ $f = new PhpExecutableFinder();
-+
-+ $current = PHP_BINARY;
-+ $args = 'phpdbg' === PHP_SAPI ? ' -qrr' : '';
-+
-+ $this->assertEquals($current.$args, $f->find(), '::find() returns the executable PHP');
-+ $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
-+ }
-+
-+ /**
-+ * tests find() with the env var / constant PHP_BINARY with HHVM.
-+ */
-+ public function testFindWithHHVM()
-+ {
-+ if (!defined('HHVM_VERSION')) {
-+ $this->markTestSkipped('Should be executed in HHVM context.');
-+ }
-+
-+ $f = new PhpExecutableFinder();
-+
-+ $current = getenv('PHP_BINARY') ?: PHP_BINARY;
-+
-+ $this->assertEquals($current.' --php', $f->find(), '::find() returns the executable PHP');
-+ $this->assertEquals($current, $f->find(false), '::find() returns the executable PHP');
-+ }
-+
-+ /**
-+ * tests find() with the env var PHP_PATH.
-+ */
-+ public function testFindArguments()
-+ {
-+ $f = new PhpExecutableFinder();
-+
-+ if (defined('HHVM_VERSION')) {
-+ $this->assertEquals($f->findArguments(), array('--php'), '::findArguments() returns HHVM arguments');
-+ } elseif ('phpdbg' === PHP_SAPI) {
-+ $this->assertEquals($f->findArguments(), array('-qrr'), '::findArguments() returns phpdbg arguments');
-+ } else {
-+ $this->assertEquals($f->findArguments(), array(), '::findArguments() returns no arguments');
-+ }
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/PhpProcessTest.php b/vendor/symfony/process/Tests/PhpProcessTest.php
-new file mode 100644
-index 00000000..988cd091
---- /dev/null
-+++ b/vendor/symfony/process/Tests/PhpProcessTest.php
-@@ -0,0 +1,48 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\PhpProcess;
-+
-+class PhpProcessTest extends TestCase
-+{
-+ public function testNonBlockingWorks()
-+ {
-+ $expected = 'hello world!';
-+ $process = new PhpProcess(<<<PHP
-+<?php echo '$expected';
-+PHP
-+ );
-+ $process->start();
-+ $process->wait();
-+ $this->assertEquals($expected, $process->getOutput());
-+ }
-+
-+ public function testCommandLine()
-+ {
-+ $process = new PhpProcess(<<<'PHP'
-+<?php echo phpversion().PHP_SAPI;
-+PHP
-+ );
-+
-+ $commandLine = $process->getCommandLine();
-+
-+ $process->start();
-+ $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after start');
-+
-+ $process->wait();
-+ $this->assertContains($commandLine, $process->getCommandLine(), '::getCommandLine() returns the command line of PHP after wait');
-+
-+ $this->assertSame(phpversion().PHP_SAPI, $process->getOutput());
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php b/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php
-new file mode 100644
-index 00000000..bbd7ddfe
---- /dev/null
-+++ b/vendor/symfony/process/Tests/PipeStdinInStdoutStdErrStreamSelect.php
-@@ -0,0 +1,72 @@
-+<?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.
-+ */
-+
-+define('ERR_SELECT_FAILED', 1);
-+define('ERR_TIMEOUT', 2);
-+define('ERR_READ_FAILED', 3);
-+define('ERR_WRITE_FAILED', 4);
-+
-+$read = array(STDIN);
-+$write = array(STDOUT, STDERR);
-+
-+stream_set_blocking(STDIN, 0);
-+stream_set_blocking(STDOUT, 0);
-+stream_set_blocking(STDERR, 0);
-+
-+$out = $err = '';
-+while ($read || $write) {
-+ $r = $read;
-+ $w = $write;
-+ $e = null;
-+ $n = stream_select($r, $w, $e, 5);
-+
-+ if (false === $n) {
-+ die(ERR_SELECT_FAILED);
-+ } elseif ($n < 1) {
-+ die(ERR_TIMEOUT);
-+ }
-+
-+ if (in_array(STDOUT, $w) && strlen($out) > 0) {
-+ $written = fwrite(STDOUT, (binary) $out, 32768);
-+ if (false === $written) {
-+ die(ERR_WRITE_FAILED);
-+ }
-+ $out = (binary) substr($out, $written);
-+ }
-+ if (null === $read && '' === $out) {
-+ $write = array_diff($write, array(STDOUT));
-+ }
-+
-+ if (in_array(STDERR, $w) && strlen($err) > 0) {
-+ $written = fwrite(STDERR, (binary) $err, 32768);
-+ if (false === $written) {
-+ die(ERR_WRITE_FAILED);
-+ }
-+ $err = (binary) substr($err, $written);
-+ }
-+ if (null === $read && '' === $err) {
-+ $write = array_diff($write, array(STDERR));
-+ }
-+
-+ if ($r) {
-+ $str = fread(STDIN, 32768);
-+ if (false !== $str) {
-+ $out .= $str;
-+ $err .= $str;
-+ }
-+ if (false === $str || feof(STDIN)) {
-+ $read = null;
-+ if (!feof(STDIN)) {
-+ die(ERR_READ_FAILED);
-+ }
-+ }
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/ProcessBuilderTest.php b/vendor/symfony/process/Tests/ProcessBuilderTest.php
-new file mode 100644
-index 00000000..fa7c8c51
---- /dev/null
-+++ b/vendor/symfony/process/Tests/ProcessBuilderTest.php
-@@ -0,0 +1,226 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\ProcessBuilder;
-+
-+class ProcessBuilderTest extends TestCase
-+{
-+ /**
-+ * @group legacy
-+ */
-+ public function testInheritEnvironmentVars()
-+ {
-+ $proc = ProcessBuilder::create()
-+ ->add('foo')
-+ ->getProcess();
-+
-+ $this->assertTrue($proc->areEnvironmentVariablesInherited());
-+
-+ $proc = ProcessBuilder::create()
-+ ->add('foo')
-+ ->inheritEnvironmentVariables(false)
-+ ->getProcess();
-+
-+ $this->assertFalse($proc->areEnvironmentVariablesInherited());
-+ }
-+
-+ public function testAddEnvironmentVariables()
-+ {
-+ $pb = new ProcessBuilder();
-+ $env = array(
-+ 'foo' => 'bar',
-+ 'foo2' => 'bar2',
-+ );
-+ $proc = $pb
-+ ->add('command')
-+ ->setEnv('foo', 'bar2')
-+ ->addEnvironmentVariables($env)
-+ ->getProcess()
-+ ;
-+
-+ $this->assertSame($env, $proc->getEnv());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
-+ */
-+ public function testNegativeTimeoutFromSetter()
-+ {
-+ $pb = new ProcessBuilder();
-+ $pb->setTimeout(-1);
-+ }
-+
-+ public function testNullTimeout()
-+ {
-+ $pb = new ProcessBuilder();
-+ $pb->setTimeout(10);
-+ $pb->setTimeout(null);
-+
-+ $r = new \ReflectionObject($pb);
-+ $p = $r->getProperty('timeout');
-+ $p->setAccessible(true);
-+
-+ $this->assertNull($p->getValue($pb));
-+ }
-+
-+ public function testShouldSetArguments()
-+ {
-+ $pb = new ProcessBuilder(array('initial'));
-+ $pb->setArguments(array('second'));
-+
-+ $proc = $pb->getProcess();
-+
-+ $this->assertContains('second', $proc->getCommandLine());
-+ }
-+
-+ public function testPrefixIsPrependedToAllGeneratedProcess()
-+ {
-+ $pb = new ProcessBuilder();
-+ $pb->setPrefix('/usr/bin/php');
-+
-+ $proc = $pb->setArguments(array('-v'))->getProcess();
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals('"/usr/bin/php" -v', $proc->getCommandLine());
-+ } else {
-+ $this->assertEquals("'/usr/bin/php' '-v'", $proc->getCommandLine());
-+ }
-+
-+ $proc = $pb->setArguments(array('-i'))->getProcess();
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals('"/usr/bin/php" -i', $proc->getCommandLine());
-+ } else {
-+ $this->assertEquals("'/usr/bin/php' '-i'", $proc->getCommandLine());
-+ }
-+ }
-+
-+ public function testArrayPrefixesArePrependedToAllGeneratedProcess()
-+ {
-+ $pb = new ProcessBuilder();
-+ $pb->setPrefix(array('/usr/bin/php', 'composer.phar'));
-+
-+ $proc = $pb->setArguments(array('-v'))->getProcess();
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals('"/usr/bin/php" composer.phar -v', $proc->getCommandLine());
-+ } else {
-+ $this->assertEquals("'/usr/bin/php' 'composer.phar' '-v'", $proc->getCommandLine());
-+ }
-+
-+ $proc = $pb->setArguments(array('-i'))->getProcess();
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals('"/usr/bin/php" composer.phar -i', $proc->getCommandLine());
-+ } else {
-+ $this->assertEquals("'/usr/bin/php' 'composer.phar' '-i'", $proc->getCommandLine());
-+ }
-+ }
-+
-+ public function testShouldEscapeArguments()
-+ {
-+ $pb = new ProcessBuilder(array('%path%', 'foo " bar', '%baz%baz'));
-+ $proc = $pb->getProcess();
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertSame('""^%"path"^%"" "foo "" bar" ""^%"baz"^%"baz"', $proc->getCommandLine());
-+ } else {
-+ $this->assertSame("'%path%' 'foo \" bar' '%baz%baz'", $proc->getCommandLine());
-+ }
-+ }
-+
-+ public function testShouldEscapeArgumentsAndPrefix()
-+ {
-+ $pb = new ProcessBuilder(array('arg'));
-+ $pb->setPrefix('%prefix%');
-+ $proc = $pb->getProcess();
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertSame('""^%"prefix"^%"" arg', $proc->getCommandLine());
-+ } else {
-+ $this->assertSame("'%prefix%' 'arg'", $proc->getCommandLine());
-+ }
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ */
-+ public function testShouldThrowALogicExceptionIfNoPrefixAndNoArgument()
-+ {
-+ ProcessBuilder::create()->getProcess();
-+ }
-+
-+ public function testShouldNotThrowALogicExceptionIfNoArgument()
-+ {
-+ $process = ProcessBuilder::create()
-+ ->setPrefix('/usr/bin/php')
-+ ->getProcess();
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
-+ } else {
-+ $this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
-+ }
-+ }
-+
-+ public function testShouldNotThrowALogicExceptionIfNoPrefix()
-+ {
-+ $process = ProcessBuilder::create(array('/usr/bin/php'))
-+ ->getProcess();
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->assertEquals('"/usr/bin/php"', $process->getCommandLine());
-+ } else {
-+ $this->assertEquals("'/usr/bin/php'", $process->getCommandLine());
-+ }
-+ }
-+
-+ public function testShouldReturnProcessWithDisabledOutput()
-+ {
-+ $process = ProcessBuilder::create(array('/usr/bin/php'))
-+ ->disableOutput()
-+ ->getProcess();
-+
-+ $this->assertTrue($process->isOutputDisabled());
-+ }
-+
-+ public function testShouldReturnProcessWithEnabledOutput()
-+ {
-+ $process = ProcessBuilder::create(array('/usr/bin/php'))
-+ ->disableOutput()
-+ ->enableOutput()
-+ ->getProcess();
-+
-+ $this->assertFalse($process->isOutputDisabled());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
-+ * @expectedExceptionMessage Symfony\Component\Process\ProcessBuilder::setInput only accepts strings, Traversable objects or stream resources.
-+ */
-+ public function testInvalidInput()
-+ {
-+ $builder = ProcessBuilder::create();
-+ $builder->setInput(array());
-+ }
-+
-+ public function testDoesNotPrefixExec()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('This test cannot run on Windows.');
-+ }
-+
-+ $builder = ProcessBuilder::create(array('command', '-v', 'ls'));
-+ $process = $builder->getProcess();
-+ $process->run();
-+
-+ $this->assertTrue($process->isSuccessful());
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php b/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php
-new file mode 100644
-index 00000000..5f739158
---- /dev/null
-+++ b/vendor/symfony/process/Tests/ProcessFailedExceptionTest.php
-@@ -0,0 +1,135 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\Exception\ProcessFailedException;
-+
-+/**
-+ * @author Sebastian Marek <proofek@gmail.com>
-+ */
-+class ProcessFailedExceptionTest extends TestCase
-+{
-+ /**
-+ * tests ProcessFailedException throws exception if the process was successful.
-+ */
-+ public function testProcessFailedExceptionThrowsException()
-+ {
-+ $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful'))->setConstructorArgs(array('php'))->getMock();
-+ $process->expects($this->once())
-+ ->method('isSuccessful')
-+ ->will($this->returnValue(true));
-+
-+ $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(
-+ '\InvalidArgumentException',
-+ 'Expected a failed process, but the given process was successful.'
-+ );
-+
-+ new ProcessFailedException($process);
-+ }
-+
-+ /**
-+ * tests ProcessFailedException uses information from process output
-+ * to generate exception message.
-+ */
-+ public function testProcessFailedExceptionPopulatesInformationFromProcessOutput()
-+ {
-+ $cmd = 'php';
-+ $exitCode = 1;
-+ $exitText = 'General error';
-+ $output = 'Command output';
-+ $errorOutput = 'FATAL: Unexpected error';
-+ $workingDirectory = getcwd();
-+
-+ $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'getOutput', 'getErrorOutput', 'getExitCode', 'getExitCodeText', 'isOutputDisabled', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
-+ $process->expects($this->once())
-+ ->method('isSuccessful')
-+ ->will($this->returnValue(false));
-+
-+ $process->expects($this->once())
-+ ->method('getOutput')
-+ ->will($this->returnValue($output));
-+
-+ $process->expects($this->once())
-+ ->method('getErrorOutput')
-+ ->will($this->returnValue($errorOutput));
-+
-+ $process->expects($this->once())
-+ ->method('getExitCode')
-+ ->will($this->returnValue($exitCode));
-+
-+ $process->expects($this->once())
-+ ->method('getExitCodeText')
-+ ->will($this->returnValue($exitText));
-+
-+ $process->expects($this->once())
-+ ->method('isOutputDisabled')
-+ ->will($this->returnValue(false));
-+
-+ $process->expects($this->once())
-+ ->method('getWorkingDirectory')
-+ ->will($this->returnValue($workingDirectory));
-+
-+ $exception = new ProcessFailedException($process);
-+
-+ $this->assertEquals(
-+ "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}\n\nOutput:\n================\n{$output}\n\nError Output:\n================\n{$errorOutput}",
-+ $exception->getMessage()
-+ );
-+ }
-+
-+ /**
-+ * Tests that ProcessFailedException does not extract information from
-+ * process output if it was previously disabled.
-+ */
-+ public function testDisabledOutputInFailedExceptionDoesNotPopulateOutput()
-+ {
-+ $cmd = 'php';
-+ $exitCode = 1;
-+ $exitText = 'General error';
-+ $workingDirectory = getcwd();
-+
-+ $process = $this->getMockBuilder('Symfony\Component\Process\Process')->setMethods(array('isSuccessful', 'isOutputDisabled', 'getExitCode', 'getExitCodeText', 'getOutput', 'getErrorOutput', 'getWorkingDirectory'))->setConstructorArgs(array($cmd))->getMock();
-+ $process->expects($this->once())
-+ ->method('isSuccessful')
-+ ->will($this->returnValue(false));
-+
-+ $process->expects($this->never())
-+ ->method('getOutput');
-+
-+ $process->expects($this->never())
-+ ->method('getErrorOutput');
-+
-+ $process->expects($this->once())
-+ ->method('getExitCode')
-+ ->will($this->returnValue($exitCode));
-+
-+ $process->expects($this->once())
-+ ->method('getExitCodeText')
-+ ->will($this->returnValue($exitText));
-+
-+ $process->expects($this->once())
-+ ->method('isOutputDisabled')
-+ ->will($this->returnValue(true));
-+
-+ $process->expects($this->once())
-+ ->method('getWorkingDirectory')
-+ ->will($this->returnValue($workingDirectory));
-+
-+ $exception = new ProcessFailedException($process);
-+
-+ $this->assertEquals(
-+ "The command \"$cmd\" failed.\n\nExit Code: $exitCode($exitText)\n\nWorking directory: {$workingDirectory}",
-+ $exception->getMessage()
-+ );
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/ProcessTest.php b/vendor/symfony/process/Tests/ProcessTest.php
-new file mode 100644
-index 00000000..26725711
---- /dev/null
-+++ b/vendor/symfony/process/Tests/ProcessTest.php
-@@ -0,0 +1,1591 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\Exception\LogicException;
-+use Symfony\Component\Process\Exception\ProcessTimedOutException;
-+use Symfony\Component\Process\Exception\RuntimeException;
-+use Symfony\Component\Process\InputStream;
-+use Symfony\Component\Process\PhpExecutableFinder;
-+use Symfony\Component\Process\Pipes\PipesInterface;
-+use Symfony\Component\Process\Process;
-+
-+/**
-+ * @author Robert Schönthal <seroscho@googlemail.com>
-+ */
-+class ProcessTest extends TestCase
-+{
-+ private static $phpBin;
-+ private static $process;
-+ private static $sigchild;
-+ private static $notEnhancedSigchild = false;
-+
-+ public static function setUpBeforeClass()
-+ {
-+ $phpBin = new PhpExecutableFinder();
-+ self::$phpBin = getenv('SYMFONY_PROCESS_PHP_TEST_BINARY') ?: ('phpdbg' === PHP_SAPI ? 'php' : $phpBin->find());
-+
-+ ob_start();
-+ phpinfo(INFO_GENERAL);
-+ self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
-+ }
-+
-+ protected function tearDown()
-+ {
-+ if (self::$process) {
-+ self::$process->stop(0);
-+ self::$process = null;
-+ }
-+ }
-+
-+ public function testThatProcessDoesNotThrowWarningDuringRun()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('This test is transient on Windows');
-+ }
-+ @trigger_error('Test Error', E_USER_NOTICE);
-+ $process = $this->getProcessForCode('sleep(3)');
-+ $process->run();
-+ $actualError = error_get_last();
-+ $this->assertEquals('Test Error', $actualError['message']);
-+ $this->assertEquals(E_USER_NOTICE, $actualError['type']);
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
-+ */
-+ public function testNegativeTimeoutFromConstructor()
-+ {
-+ $this->getProcess('', null, null, null, -1);
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
-+ */
-+ public function testNegativeTimeoutFromSetter()
-+ {
-+ $p = $this->getProcess('');
-+ $p->setTimeout(-1);
-+ }
-+
-+ public function testFloatAndNullTimeout()
-+ {
-+ $p = $this->getProcess('');
-+
-+ $p->setTimeout(10);
-+ $this->assertSame(10.0, $p->getTimeout());
-+
-+ $p->setTimeout(null);
-+ $this->assertNull($p->getTimeout());
-+
-+ $p->setTimeout(0.0);
-+ $this->assertNull($p->getTimeout());
-+ }
-+
-+ /**
-+ * @requires extension pcntl
-+ */
-+ public function testStopWithTimeoutIsActuallyWorking()
-+ {
-+ $p = $this->getProcess(array(self::$phpBin, __DIR__.'/NonStopableProcess.php', 30));
-+ $p->start();
-+
-+ while (false === strpos($p->getOutput(), 'received')) {
-+ usleep(1000);
-+ }
-+ $start = microtime(true);
-+ $p->stop(0.1);
-+
-+ $p->wait();
-+
-+ $this->assertLessThan(15, microtime(true) - $start);
-+ }
-+
-+ public function testAllOutputIsActuallyReadOnTermination()
-+ {
-+ // this code will result in a maximum of 2 reads of 8192 bytes by calling
-+ // start() and isRunning(). by the time getOutput() is called the process
-+ // has terminated so the internal pipes array is already empty. normally
-+ // the call to start() will not read any data as the process will not have
-+ // generated output, but this is non-deterministic so we must count it as
-+ // a possibility. therefore we need 2 * PipesInterface::CHUNK_SIZE plus
-+ // another byte which will never be read.
-+ $expectedOutputSize = PipesInterface::CHUNK_SIZE * 2 + 2;
-+
-+ $code = sprintf('echo str_repeat(\'*\', %d);', $expectedOutputSize);
-+ $p = $this->getProcessForCode($code);
-+
-+ $p->start();
-+
-+ // Don't call Process::run nor Process::wait to avoid any read of pipes
-+ $h = new \ReflectionProperty($p, 'process');
-+ $h->setAccessible(true);
-+ $h = $h->getValue($p);
-+ $s = @proc_get_status($h);
-+
-+ while (!empty($s['running'])) {
-+ usleep(1000);
-+ $s = proc_get_status($h);
-+ }
-+
-+ $o = $p->getOutput();
-+
-+ $this->assertEquals($expectedOutputSize, strlen($o));
-+ }
-+
-+ public function testCallbacksAreExecutedWithStart()
-+ {
-+ $process = $this->getProcess('echo foo');
-+ $process->start(function ($type, $buffer) use (&$data) {
-+ $data .= $buffer;
-+ });
-+
-+ $process->wait();
-+
-+ $this->assertSame('foo'.PHP_EOL, $data);
-+ }
-+
-+ /**
-+ * tests results from sub processes.
-+ *
-+ * @dataProvider responsesCodeProvider
-+ */
-+ public function testProcessResponses($expected, $getter, $code)
-+ {
-+ $p = $this->getProcessForCode($code);
-+ $p->run();
-+
-+ $this->assertSame($expected, $p->$getter());
-+ }
-+
-+ /**
-+ * tests results from sub processes.
-+ *
-+ * @dataProvider pipesCodeProvider
-+ */
-+ public function testProcessPipes($code, $size)
-+ {
-+ $expected = str_repeat(str_repeat('*', 1024), $size).'!';
-+ $expectedLength = (1024 * $size) + 1;
-+
-+ $p = $this->getProcessForCode($code);
-+ $p->setInput($expected);
-+ $p->run();
-+
-+ $this->assertEquals($expectedLength, strlen($p->getOutput()));
-+ $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
-+ }
-+
-+ /**
-+ * @dataProvider pipesCodeProvider
-+ */
-+ public function testSetStreamAsInput($code, $size)
-+ {
-+ $expected = str_repeat(str_repeat('*', 1024), $size).'!';
-+ $expectedLength = (1024 * $size) + 1;
-+
-+ $stream = fopen('php://temporary', 'w+');
-+ fwrite($stream, $expected);
-+ rewind($stream);
-+
-+ $p = $this->getProcessForCode($code);
-+ $p->setInput($stream);
-+ $p->run();
-+
-+ fclose($stream);
-+
-+ $this->assertEquals($expectedLength, strlen($p->getOutput()));
-+ $this->assertEquals($expectedLength, strlen($p->getErrorOutput()));
-+ }
-+
-+ public function testLiveStreamAsInput()
-+ {
-+ $stream = fopen('php://memory', 'r+');
-+ fwrite($stream, 'hello');
-+ rewind($stream);
-+
-+ $p = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
-+ $p->setInput($stream);
-+ $p->start(function ($type, $data) use ($stream) {
-+ if ('hello' === $data) {
-+ fclose($stream);
-+ }
-+ });
-+ $p->wait();
-+
-+ $this->assertSame('hello', $p->getOutput());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ * @expectedExceptionMessage Input can not be set while the process is running.
-+ */
-+ public function testSetInputWhileRunningThrowsAnException()
-+ {
-+ $process = $this->getProcessForCode('sleep(30);');
-+ $process->start();
-+ try {
-+ $process->setInput('foobar');
-+ $process->stop();
-+ $this->fail('A LogicException should have been raised.');
-+ } catch (LogicException $e) {
-+ }
-+ $process->stop();
-+
-+ throw $e;
-+ }
-+
-+ /**
-+ * @dataProvider provideInvalidInputValues
-+ * @expectedException \Symfony\Component\Process\Exception\InvalidArgumentException
-+ * @expectedExceptionMessage Symfony\Component\Process\Process::setInput only accepts strings, Traversable objects or stream resources.
-+ */
-+ public function testInvalidInput($value)
-+ {
-+ $process = $this->getProcess('foo');
-+ $process->setInput($value);
-+ }
-+
-+ public function provideInvalidInputValues()
-+ {
-+ return array(
-+ array(array()),
-+ array(new NonStringifiable()),
-+ );
-+ }
-+
-+ /**
-+ * @dataProvider provideInputValues
-+ */
-+ public function testValidInput($expected, $value)
-+ {
-+ $process = $this->getProcess('foo');
-+ $process->setInput($value);
-+ $this->assertSame($expected, $process->getInput());
-+ }
-+
-+ public function provideInputValues()
-+ {
-+ return array(
-+ array(null, null),
-+ array('24.5', 24.5),
-+ array('input data', 'input data'),
-+ );
-+ }
-+
-+ public function chainedCommandsOutputProvider()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ return array(
-+ array("2 \r\n2\r\n", '&&', '2'),
-+ );
-+ }
-+
-+ return array(
-+ array("1\n1\n", ';', '1'),
-+ array("2\n2\n", '&&', '2'),
-+ );
-+ }
-+
-+ /**
-+ * @dataProvider chainedCommandsOutputProvider
-+ */
-+ public function testChainedCommandsOutput($expected, $operator, $input)
-+ {
-+ $process = $this->getProcess(sprintf('echo %s %s echo %s', $input, $operator, $input));
-+ $process->run();
-+ $this->assertEquals($expected, $process->getOutput());
-+ }
-+
-+ public function testCallbackIsExecutedForOutput()
-+ {
-+ $p = $this->getProcessForCode('echo \'foo\';');
-+
-+ $called = false;
-+ $p->run(function ($type, $buffer) use (&$called) {
-+ $called = $buffer === 'foo';
-+ });
-+
-+ $this->assertTrue($called, 'The callback should be executed with the output');
-+ }
-+
-+ public function testCallbackIsExecutedForOutputWheneverOutputIsDisabled()
-+ {
-+ $p = $this->getProcessForCode('echo \'foo\';');
-+ $p->disableOutput();
-+
-+ $called = false;
-+ $p->run(function ($type, $buffer) use (&$called) {
-+ $called = $buffer === 'foo';
-+ });
-+
-+ $this->assertTrue($called, 'The callback should be executed with the output');
-+ }
-+
-+ public function testGetErrorOutput()
-+ {
-+ $p = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }');
-+
-+ $p->run();
-+ $this->assertEquals(3, preg_match_all('/ERROR/', $p->getErrorOutput(), $matches));
-+ }
-+
-+ public function testFlushErrorOutput()
-+ {
-+ $p = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\'php://stderr\', \'ERROR\'); $n++; }');
-+
-+ $p->run();
-+ $p->clearErrorOutput();
-+ $this->assertEmpty($p->getErrorOutput());
-+ }
-+
-+ /**
-+ * @dataProvider provideIncrementalOutput
-+ */
-+ public function testIncrementalOutput($getOutput, $getIncrementalOutput, $uri)
-+ {
-+ $lock = tempnam(sys_get_temp_dir(), __FUNCTION__);
-+
-+ $p = $this->getProcessForCode('file_put_contents($s = \''.$uri.'\', \'foo\'); flock(fopen('.var_export($lock, true).', \'r\'), LOCK_EX); file_put_contents($s, \'bar\');');
-+
-+ $h = fopen($lock, 'w');
-+ flock($h, LOCK_EX);
-+
-+ $p->start();
-+
-+ foreach (array('foo', 'bar') as $s) {
-+ while (false === strpos($p->$getOutput(), $s)) {
-+ usleep(1000);
-+ }
-+
-+ $this->assertSame($s, $p->$getIncrementalOutput());
-+ $this->assertSame('', $p->$getIncrementalOutput());
-+
-+ flock($h, LOCK_UN);
-+ }
-+
-+ fclose($h);
-+ }
-+
-+ public function provideIncrementalOutput()
-+ {
-+ return array(
-+ array('getOutput', 'getIncrementalOutput', 'php://stdout'),
-+ array('getErrorOutput', 'getIncrementalErrorOutput', 'php://stderr'),
-+ );
-+ }
-+
-+ public function testGetOutput()
-+ {
-+ $p = $this->getProcessForCode('$n = 0; while ($n < 3) { echo \' foo \'; $n++; }');
-+
-+ $p->run();
-+ $this->assertEquals(3, preg_match_all('/foo/', $p->getOutput(), $matches));
-+ }
-+
-+ public function testFlushOutput()
-+ {
-+ $p = $this->getProcessForCode('$n=0;while ($n<3) {echo \' foo \';$n++;}');
-+
-+ $p->run();
-+ $p->clearOutput();
-+ $this->assertEmpty($p->getOutput());
-+ }
-+
-+ public function testZeroAsOutput()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ // see http://stackoverflow.com/questions/7105433/windows-batch-echo-without-new-line
-+ $p = $this->getProcess('echo | set /p dummyName=0');
-+ } else {
-+ $p = $this->getProcess('printf 0');
-+ }
-+
-+ $p->run();
-+ $this->assertSame('0', $p->getOutput());
-+ }
-+
-+ public function testExitCodeCommandFailed()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Windows does not support POSIX exit code');
-+ }
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ // such command run in bash return an exitcode 127
-+ $process = $this->getProcess('nonexistingcommandIhopeneversomeonewouldnameacommandlikethis');
-+ $process->run();
-+
-+ $this->assertGreaterThan(0, $process->getExitCode());
-+ }
-+
-+ /**
-+ * @group tty
-+ */
-+ public function testTTYCommand()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Windows does not have /dev/tty support');
-+ }
-+
-+ $process = $this->getProcess('echo "foo" >> /dev/null && '.$this->getProcessForCode('usleep(100000);')->getCommandLine());
-+ $process->setTty(true);
-+ $process->start();
-+ $this->assertTrue($process->isRunning());
-+ $process->wait();
-+
-+ $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
-+ }
-+
-+ /**
-+ * @group tty
-+ */
-+ public function testTTYCommandExitCode()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Windows does have /dev/tty support');
-+ }
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo "foo" >> /dev/null');
-+ $process->setTty(true);
-+ $process->run();
-+
-+ $this->assertTrue($process->isSuccessful());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
-+ * @expectedExceptionMessage TTY mode is not supported on Windows platform.
-+ */
-+ public function testTTYInWindowsEnvironment()
-+ {
-+ if ('\\' !== DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('This test is for Windows platform only');
-+ }
-+
-+ $process = $this->getProcess('echo "foo" >> /dev/null');
-+ $process->setTty(false);
-+ $process->setTty(true);
-+ }
-+
-+ public function testExitCodeTextIsNullWhenExitCodeIsNull()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('');
-+ $this->assertNull($process->getExitCodeText());
-+ }
-+
-+ public function testPTYCommand()
-+ {
-+ if (!Process::isPtySupported()) {
-+ $this->markTestSkipped('PTY is not supported on this operating system.');
-+ }
-+
-+ $process = $this->getProcess('echo "foo"');
-+ $process->setPty(true);
-+ $process->run();
-+
-+ $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
-+ $this->assertEquals("foo\r\n", $process->getOutput());
-+ }
-+
-+ public function testMustRun()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo foo');
-+
-+ $this->assertSame($process, $process->mustRun());
-+ $this->assertEquals('foo'.PHP_EOL, $process->getOutput());
-+ }
-+
-+ public function testSuccessfulMustRunHasCorrectExitCode()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo foo')->mustRun();
-+ $this->assertEquals(0, $process->getExitCode());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\ProcessFailedException
-+ */
-+ public function testMustRunThrowsException()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('exit 1');
-+ $process->mustRun();
-+ }
-+
-+ public function testExitCodeText()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('');
-+ $r = new \ReflectionObject($process);
-+ $p = $r->getProperty('exitcode');
-+ $p->setAccessible(true);
-+
-+ $p->setValue($process, 2);
-+ $this->assertEquals('Misuse of shell builtins', $process->getExitCodeText());
-+ }
-+
-+ public function testStartIsNonBlocking()
-+ {
-+ $process = $this->getProcessForCode('usleep(500000);');
-+ $start = microtime(true);
-+ $process->start();
-+ $end = microtime(true);
-+ $this->assertLessThan(0.4, $end - $start);
-+ $process->stop();
-+ }
-+
-+ public function testUpdateStatus()
-+ {
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertTrue(strlen($process->getOutput()) > 0);
-+ }
-+
-+ public function testGetExitCodeIsNullOnStart()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcessForCode('usleep(100000);');
-+ $this->assertNull($process->getExitCode());
-+ $process->start();
-+ $this->assertNull($process->getExitCode());
-+ $process->wait();
-+ $this->assertEquals(0, $process->getExitCode());
-+ }
-+
-+ public function testGetExitCodeIsNullOnWhenStartingAgain()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcessForCode('usleep(100000);');
-+ $process->run();
-+ $this->assertEquals(0, $process->getExitCode());
-+ $process->start();
-+ $this->assertNull($process->getExitCode());
-+ $process->wait();
-+ $this->assertEquals(0, $process->getExitCode());
-+ }
-+
-+ public function testGetExitCode()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertSame(0, $process->getExitCode());
-+ }
-+
-+ public function testStatus()
-+ {
-+ $process = $this->getProcessForCode('usleep(100000);');
-+ $this->assertFalse($process->isRunning());
-+ $this->assertFalse($process->isStarted());
-+ $this->assertFalse($process->isTerminated());
-+ $this->assertSame(Process::STATUS_READY, $process->getStatus());
-+ $process->start();
-+ $this->assertTrue($process->isRunning());
-+ $this->assertTrue($process->isStarted());
-+ $this->assertFalse($process->isTerminated());
-+ $this->assertSame(Process::STATUS_STARTED, $process->getStatus());
-+ $process->wait();
-+ $this->assertFalse($process->isRunning());
-+ $this->assertTrue($process->isStarted());
-+ $this->assertTrue($process->isTerminated());
-+ $this->assertSame(Process::STATUS_TERMINATED, $process->getStatus());
-+ }
-+
-+ public function testStop()
-+ {
-+ $process = $this->getProcessForCode('sleep(31);');
-+ $process->start();
-+ $this->assertTrue($process->isRunning());
-+ $process->stop();
-+ $this->assertFalse($process->isRunning());
-+ }
-+
-+ public function testIsSuccessful()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertTrue($process->isSuccessful());
-+ }
-+
-+ public function testIsSuccessfulOnlyAfterTerminated()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcessForCode('usleep(100000);');
-+ $process->start();
-+
-+ $this->assertFalse($process->isSuccessful());
-+
-+ $process->wait();
-+
-+ $this->assertTrue($process->isSuccessful());
-+ }
-+
-+ public function testIsNotSuccessful()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcessForCode('throw new \Exception(\'BOUM\');');
-+ $process->run();
-+ $this->assertFalse($process->isSuccessful());
-+ }
-+
-+ public function testProcessIsNotSignaled()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Windows does not support POSIX signals');
-+ }
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertFalse($process->hasBeenSignaled());
-+ }
-+
-+ public function testProcessWithoutTermSignal()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Windows does not support POSIX signals');
-+ }
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertEquals(0, $process->getTermSignal());
-+ }
-+
-+ public function testProcessIsSignaledIfStopped()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('Windows does not support POSIX signals');
-+ }
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcessForCode('sleep(32);');
-+ $process->start();
-+ $process->stop();
-+ $this->assertTrue($process->hasBeenSignaled());
-+ $this->assertEquals(15, $process->getTermSignal()); // SIGTERM
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
-+ * @expectedExceptionMessage The process has been signaled
-+ */
-+ public function testProcessThrowsExceptionWhenExternallySignaled()
-+ {
-+ if (!function_exists('posix_kill')) {
-+ $this->markTestSkipped('Function posix_kill is required.');
-+ }
-+ $this->skipIfNotEnhancedSigchild(false);
-+
-+ $process = $this->getProcessForCode('sleep(32.1);');
-+ $process->start();
-+ posix_kill($process->getPid(), 9); // SIGKILL
-+
-+ $process->wait();
-+ }
-+
-+ public function testRestart()
-+ {
-+ $process1 = $this->getProcessForCode('echo getmypid();');
-+ $process1->run();
-+ $process2 = $process1->restart();
-+
-+ $process2->wait(); // wait for output
-+
-+ // Ensure that both processed finished and the output is numeric
-+ $this->assertFalse($process1->isRunning());
-+ $this->assertFalse($process2->isRunning());
-+ $this->assertInternalType('numeric', $process1->getOutput());
-+ $this->assertInternalType('numeric', $process2->getOutput());
-+
-+ // Ensure that restart returned a new process by check that the output is different
-+ $this->assertNotEquals($process1->getOutput(), $process2->getOutput());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
-+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
-+ */
-+ public function testRunProcessWithTimeout()
-+ {
-+ $process = $this->getProcessForCode('sleep(30);');
-+ $process->setTimeout(0.1);
-+ $start = microtime(true);
-+ try {
-+ $process->run();
-+ $this->fail('A RuntimeException should have been raised');
-+ } catch (RuntimeException $e) {
-+ }
-+
-+ $this->assertLessThan(15, microtime(true) - $start);
-+
-+ throw $e;
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
-+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
-+ */
-+ public function testIterateOverProcessWithTimeout()
-+ {
-+ $process = $this->getProcessForCode('sleep(30);');
-+ $process->setTimeout(0.1);
-+ $start = microtime(true);
-+ try {
-+ $process->start();
-+ foreach ($process as $buffer);
-+ $this->fail('A RuntimeException should have been raised');
-+ } catch (RuntimeException $e) {
-+ }
-+
-+ $this->assertLessThan(15, microtime(true) - $start);
-+
-+ throw $e;
-+ }
-+
-+ public function testCheckTimeoutOnNonStartedProcess()
-+ {
-+ $process = $this->getProcess('echo foo');
-+ $this->assertNull($process->checkTimeout());
-+ }
-+
-+ public function testCheckTimeoutOnTerminatedProcess()
-+ {
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertNull($process->checkTimeout());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
-+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
-+ */
-+ public function testCheckTimeoutOnStartedProcess()
-+ {
-+ $process = $this->getProcessForCode('sleep(33);');
-+ $process->setTimeout(0.1);
-+
-+ $process->start();
-+ $start = microtime(true);
-+
-+ try {
-+ while ($process->isRunning()) {
-+ $process->checkTimeout();
-+ usleep(100000);
-+ }
-+ $this->fail('A ProcessTimedOutException should have been raised');
-+ } catch (ProcessTimedOutException $e) {
-+ }
-+
-+ $this->assertLessThan(15, microtime(true) - $start);
-+
-+ throw $e;
-+ }
-+
-+ public function testIdleTimeout()
-+ {
-+ $process = $this->getProcessForCode('sleep(34);');
-+ $process->setTimeout(60);
-+ $process->setIdleTimeout(0.1);
-+
-+ try {
-+ $process->run();
-+
-+ $this->fail('A timeout exception was expected.');
-+ } catch (ProcessTimedOutException $e) {
-+ $this->assertTrue($e->isIdleTimeout());
-+ $this->assertFalse($e->isGeneralTimeout());
-+ $this->assertEquals(0.1, $e->getExceededTimeout());
-+ }
-+ }
-+
-+ public function testIdleTimeoutNotExceededWhenOutputIsSent()
-+ {
-+ $process = $this->getProcessForCode('while (true) {echo \'foo \'; usleep(1000);}');
-+ $process->setTimeout(1);
-+ $process->start();
-+
-+ while (false === strpos($process->getOutput(), 'foo')) {
-+ usleep(1000);
-+ }
-+
-+ $process->setIdleTimeout(0.5);
-+
-+ try {
-+ $process->wait();
-+ $this->fail('A timeout exception was expected.');
-+ } catch (ProcessTimedOutException $e) {
-+ $this->assertTrue($e->isGeneralTimeout(), 'A general timeout is expected.');
-+ $this->assertFalse($e->isIdleTimeout(), 'No idle timeout is expected.');
-+ $this->assertEquals(1, $e->getExceededTimeout());
-+ }
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\ProcessTimedOutException
-+ * @expectedExceptionMessage exceeded the timeout of 0.1 seconds.
-+ */
-+ public function testStartAfterATimeout()
-+ {
-+ $process = $this->getProcessForCode('sleep(35);');
-+ $process->setTimeout(0.1);
-+
-+ try {
-+ $process->run();
-+ $this->fail('A ProcessTimedOutException should have been raised.');
-+ } catch (ProcessTimedOutException $e) {
-+ }
-+ $this->assertFalse($process->isRunning());
-+ $process->start();
-+ $this->assertTrue($process->isRunning());
-+ $process->stop(0);
-+
-+ throw $e;
-+ }
-+
-+ public function testGetPid()
-+ {
-+ $process = $this->getProcessForCode('sleep(36);');
-+ $process->start();
-+ $this->assertGreaterThan(0, $process->getPid());
-+ $process->stop(0);
-+ }
-+
-+ public function testGetPidIsNullBeforeStart()
-+ {
-+ $process = $this->getProcess('foo');
-+ $this->assertNull($process->getPid());
-+ }
-+
-+ public function testGetPidIsNullAfterRun()
-+ {
-+ $process = $this->getProcess('echo foo');
-+ $process->run();
-+ $this->assertNull($process->getPid());
-+ }
-+
-+ /**
-+ * @requires extension pcntl
-+ */
-+ public function testSignal()
-+ {
-+ $process = $this->getProcess(array(self::$phpBin, __DIR__.'/SignalListener.php'));
-+ $process->start();
-+
-+ while (false === strpos($process->getOutput(), 'Caught')) {
-+ usleep(1000);
-+ }
-+ $process->signal(SIGUSR1);
-+ $process->wait();
-+
-+ $this->assertEquals('Caught SIGUSR1', $process->getOutput());
-+ }
-+
-+ /**
-+ * @requires extension pcntl
-+ */
-+ public function testExitCodeIsAvailableAfterSignal()
-+ {
-+ $this->skipIfNotEnhancedSigchild();
-+
-+ $process = $this->getProcess('sleep 4');
-+ $process->start();
-+ $process->signal(SIGKILL);
-+
-+ while ($process->isRunning()) {
-+ usleep(10000);
-+ }
-+
-+ $this->assertFalse($process->isRunning());
-+ $this->assertTrue($process->hasBeenSignaled());
-+ $this->assertFalse($process->isSuccessful());
-+ $this->assertEquals(137, $process->getExitCode());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ * @expectedExceptionMessage Can not send signal on a non running process.
-+ */
-+ public function testSignalProcessNotRunning()
-+ {
-+ $process = $this->getProcess('foo');
-+ $process->signal(1); // SIGHUP
-+ }
-+
-+ /**
-+ * @dataProvider provideMethodsThatNeedARunningProcess
-+ */
-+ public function testMethodsThatNeedARunningProcess($method)
-+ {
-+ $process = $this->getProcess('foo');
-+
-+ if (method_exists($this, 'expectException')) {
-+ $this->expectException('Symfony\Component\Process\Exception\LogicException');
-+ $this->expectExceptionMessage(sprintf('Process must be started before calling %s.', $method));
-+ } else {
-+ $this->setExpectedException('Symfony\Component\Process\Exception\LogicException', sprintf('Process must be started before calling %s.', $method));
-+ }
-+
-+ $process->{$method}();
-+ }
-+
-+ public function provideMethodsThatNeedARunningProcess()
-+ {
-+ return array(
-+ array('getOutput'),
-+ array('getIncrementalOutput'),
-+ array('getErrorOutput'),
-+ array('getIncrementalErrorOutput'),
-+ array('wait'),
-+ );
-+ }
-+
-+ /**
-+ * @dataProvider provideMethodsThatNeedATerminatedProcess
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ * @expectedExceptionMessage Process must be terminated before calling
-+ */
-+ public function testMethodsThatNeedATerminatedProcess($method)
-+ {
-+ $process = $this->getProcessForCode('sleep(37);');
-+ $process->start();
-+ try {
-+ $process->{$method}();
-+ $process->stop(0);
-+ $this->fail('A LogicException must have been thrown');
-+ } catch (\Exception $e) {
-+ }
-+ $process->stop(0);
-+
-+ throw $e;
-+ }
-+
-+ public function provideMethodsThatNeedATerminatedProcess()
-+ {
-+ return array(
-+ array('hasBeenSignaled'),
-+ array('getTermSignal'),
-+ array('hasBeenStopped'),
-+ array('getStopSignal'),
-+ );
-+ }
-+
-+ /**
-+ * @dataProvider provideWrongSignal
-+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
-+ */
-+ public function testWrongSignal($signal)
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ $this->markTestSkipped('POSIX signals do not work on Windows');
-+ }
-+
-+ $process = $this->getProcessForCode('sleep(38);');
-+ $process->start();
-+ try {
-+ $process->signal($signal);
-+ $this->fail('A RuntimeException must have been thrown');
-+ } catch (RuntimeException $e) {
-+ $process->stop(0);
-+ }
-+
-+ throw $e;
-+ }
-+
-+ public function provideWrongSignal()
-+ {
-+ return array(
-+ array(-4),
-+ array('Céphalopodes'),
-+ );
-+ }
-+
-+ public function testDisableOutputDisablesTheOutput()
-+ {
-+ $p = $this->getProcess('foo');
-+ $this->assertFalse($p->isOutputDisabled());
-+ $p->disableOutput();
-+ $this->assertTrue($p->isOutputDisabled());
-+ $p->enableOutput();
-+ $this->assertFalse($p->isOutputDisabled());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
-+ * @expectedExceptionMessage Disabling output while the process is running is not possible.
-+ */
-+ public function testDisableOutputWhileRunningThrowsException()
-+ {
-+ $p = $this->getProcessForCode('sleep(39);');
-+ $p->start();
-+ $p->disableOutput();
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\RuntimeException
-+ * @expectedExceptionMessage Enabling output while the process is running is not possible.
-+ */
-+ public function testEnableOutputWhileRunningThrowsException()
-+ {
-+ $p = $this->getProcessForCode('sleep(40);');
-+ $p->disableOutput();
-+ $p->start();
-+ $p->enableOutput();
-+ }
-+
-+ public function testEnableOrDisableOutputAfterRunDoesNotThrowException()
-+ {
-+ $p = $this->getProcess('echo foo');
-+ $p->disableOutput();
-+ $p->run();
-+ $p->enableOutput();
-+ $p->disableOutput();
-+ $this->assertTrue($p->isOutputDisabled());
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ * @expectedExceptionMessage Output can not be disabled while an idle timeout is set.
-+ */
-+ public function testDisableOutputWhileIdleTimeoutIsSet()
-+ {
-+ $process = $this->getProcess('foo');
-+ $process->setIdleTimeout(1);
-+ $process->disableOutput();
-+ }
-+
-+ /**
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ * @expectedExceptionMessage timeout can not be set while the output is disabled.
-+ */
-+ public function testSetIdleTimeoutWhileOutputIsDisabled()
-+ {
-+ $process = $this->getProcess('foo');
-+ $process->disableOutput();
-+ $process->setIdleTimeout(1);
-+ }
-+
-+ public function testSetNullIdleTimeoutWhileOutputIsDisabled()
-+ {
-+ $process = $this->getProcess('foo');
-+ $process->disableOutput();
-+ $this->assertSame($process, $process->setIdleTimeout(null));
-+ }
-+
-+ /**
-+ * @dataProvider provideOutputFetchingMethods
-+ * @expectedException \Symfony\Component\Process\Exception\LogicException
-+ * @expectedExceptionMessage Output has been disabled.
-+ */
-+ public function testGetOutputWhileDisabled($fetchMethod)
-+ {
-+ $p = $this->getProcessForCode('sleep(41);');
-+ $p->disableOutput();
-+ $p->start();
-+ $p->{$fetchMethod}();
-+ }
-+
-+ public function provideOutputFetchingMethods()
-+ {
-+ return array(
-+ array('getOutput'),
-+ array('getIncrementalOutput'),
-+ array('getErrorOutput'),
-+ array('getIncrementalErrorOutput'),
-+ );
-+ }
-+
-+ public function testStopTerminatesProcessCleanly()
-+ {
-+ $process = $this->getProcessForCode('echo 123; sleep(42);');
-+ $process->run(function () use ($process) {
-+ $process->stop();
-+ });
-+ $this->assertTrue(true, 'A call to stop() is not expected to cause wait() to throw a RuntimeException');
-+ }
-+
-+ public function testKillSignalTerminatesProcessCleanly()
-+ {
-+ $process = $this->getProcessForCode('echo 123; sleep(43);');
-+ $process->run(function () use ($process) {
-+ $process->signal(9); // SIGKILL
-+ });
-+ $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
-+ }
-+
-+ public function testTermSignalTerminatesProcessCleanly()
-+ {
-+ $process = $this->getProcessForCode('echo 123; sleep(44);');
-+ $process->run(function () use ($process) {
-+ $process->signal(15); // SIGTERM
-+ });
-+ $this->assertTrue(true, 'A call to signal() is not expected to cause wait() to throw a RuntimeException');
-+ }
-+
-+ public function responsesCodeProvider()
-+ {
-+ return array(
-+ //expected output / getter / code to execute
-+ //array(1,'getExitCode','exit(1);'),
-+ //array(true,'isSuccessful','exit();'),
-+ array('output', 'getOutput', 'echo \'output\';'),
-+ );
-+ }
-+
-+ public function pipesCodeProvider()
-+ {
-+ $variations = array(
-+ 'fwrite(STDOUT, $in = file_get_contents(\'php://stdin\')); fwrite(STDERR, $in);',
-+ 'include \''.__DIR__.'/PipeStdinInStdoutStdErrStreamSelect.php\';',
-+ );
-+
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ // Avoid XL buffers on Windows because of https://bugs.php.net/bug.php?id=65650
-+ $sizes = array(1, 2, 4, 8);
-+ } else {
-+ $sizes = array(1, 16, 64, 1024, 4096);
-+ }
-+
-+ $codes = array();
-+ foreach ($sizes as $size) {
-+ foreach ($variations as $code) {
-+ $codes[] = array($code, $size);
-+ }
-+ }
-+
-+ return $codes;
-+ }
-+
-+ /**
-+ * @dataProvider provideVariousIncrementals
-+ */
-+ public function testIncrementalOutputDoesNotRequireAnotherCall($stream, $method)
-+ {
-+ $process = $this->getProcessForCode('$n = 0; while ($n < 3) { file_put_contents(\''.$stream.'\', $n, 1); $n++; usleep(1000); }', null, null, null, null);
-+ $process->start();
-+ $result = '';
-+ $limit = microtime(true) + 3;
-+ $expected = '012';
-+
-+ while ($result !== $expected && microtime(true) < $limit) {
-+ $result .= $process->$method();
-+ }
-+
-+ $this->assertSame($expected, $result);
-+ $process->stop();
-+ }
-+
-+ public function provideVariousIncrementals()
-+ {
-+ return array(
-+ array('php://stdout', 'getIncrementalOutput'),
-+ array('php://stderr', 'getIncrementalErrorOutput'),
-+ );
-+ }
-+
-+ public function testIteratorInput()
-+ {
-+ $input = function () {
-+ yield 'ping';
-+ yield 'pong';
-+ };
-+
-+ $process = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);', null, null, $input());
-+ $process->run();
-+ $this->assertSame('pingpong', $process->getOutput());
-+ }
-+
-+ public function testSimpleInputStream()
-+ {
-+ $input = new InputStream();
-+
-+ $process = $this->getProcessForCode('echo \'ping\'; stream_copy_to_stream(STDIN, STDOUT);');
-+ $process->setInput($input);
-+
-+ $process->start(function ($type, $data) use ($input) {
-+ if ('ping' === $data) {
-+ $input->write('pang');
-+ } elseif (!$input->isClosed()) {
-+ $input->write('pong');
-+ $input->close();
-+ }
-+ });
-+
-+ $process->wait();
-+ $this->assertSame('pingpangpong', $process->getOutput());
-+ }
-+
-+ public function testInputStreamWithCallable()
-+ {
-+ $i = 0;
-+ $stream = fopen('php://memory', 'w+');
-+ $stream = function () use ($stream, &$i) {
-+ if ($i < 3) {
-+ rewind($stream);
-+ fwrite($stream, ++$i);
-+ rewind($stream);
-+
-+ return $stream;
-+ }
-+ };
-+
-+ $input = new InputStream();
-+ $input->onEmpty($stream);
-+ $input->write($stream());
-+
-+ $process = $this->getProcessForCode('echo fread(STDIN, 3);');
-+ $process->setInput($input);
-+ $process->start(function ($type, $data) use ($input) {
-+ $input->close();
-+ });
-+
-+ $process->wait();
-+ $this->assertSame('123', $process->getOutput());
-+ }
-+
-+ public function testInputStreamWithGenerator()
-+ {
-+ $input = new InputStream();
-+ $input->onEmpty(function ($input) {
-+ yield 'pong';
-+ $input->close();
-+ });
-+
-+ $process = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
-+ $process->setInput($input);
-+ $process->start();
-+ $input->write('ping');
-+ $process->wait();
-+ $this->assertSame('pingpong', $process->getOutput());
-+ }
-+
-+ public function testInputStreamOnEmpty()
-+ {
-+ $i = 0;
-+ $input = new InputStream();
-+ $input->onEmpty(function () use (&$i) { ++$i; });
-+
-+ $process = $this->getProcessForCode('echo 123; echo fread(STDIN, 1); echo 456;');
-+ $process->setInput($input);
-+ $process->start(function ($type, $data) use ($input) {
-+ if ('123' === $data) {
-+ $input->close();
-+ }
-+ });
-+ $process->wait();
-+
-+ $this->assertSame(0, $i, 'InputStream->onEmpty callback should be called only when the input *becomes* empty');
-+ $this->assertSame('123456', $process->getOutput());
-+ }
-+
-+ public function testIteratorOutput()
-+ {
-+ $input = new InputStream();
-+
-+ $process = $this->getProcessForCode('fwrite(STDOUT, 123); fwrite(STDERR, 234); flush(); usleep(10000); fwrite(STDOUT, fread(STDIN, 3)); fwrite(STDERR, 456);');
-+ $process->setInput($input);
-+ $process->start();
-+ $output = array();
-+
-+ foreach ($process as $type => $data) {
-+ $output[] = array($type, $data);
-+ break;
-+ }
-+ $expectedOutput = array(
-+ array($process::OUT, '123'),
-+ );
-+ $this->assertSame($expectedOutput, $output);
-+
-+ $input->write(345);
-+
-+ foreach ($process as $type => $data) {
-+ $output[] = array($type, $data);
-+ }
-+
-+ $this->assertSame('', $process->getOutput());
-+ $this->assertFalse($process->isRunning());
-+
-+ $expectedOutput = array(
-+ array($process::OUT, '123'),
-+ array($process::ERR, '234'),
-+ array($process::OUT, '345'),
-+ array($process::ERR, '456'),
-+ );
-+ $this->assertSame($expectedOutput, $output);
-+ }
-+
-+ public function testNonBlockingNorClearingIteratorOutput()
-+ {
-+ $input = new InputStream();
-+
-+ $process = $this->getProcessForCode('fwrite(STDOUT, fread(STDIN, 3));');
-+ $process->setInput($input);
-+ $process->start();
-+ $output = array();
-+
-+ foreach ($process->getIterator($process::ITER_NON_BLOCKING | $process::ITER_KEEP_OUTPUT) as $type => $data) {
-+ $output[] = array($type, $data);
-+ break;
-+ }
-+ $expectedOutput = array(
-+ array($process::OUT, ''),
-+ );
-+ $this->assertSame($expectedOutput, $output);
-+
-+ $input->write(123);
-+
-+ foreach ($process->getIterator($process::ITER_NON_BLOCKING | $process::ITER_KEEP_OUTPUT) as $type => $data) {
-+ if ('' !== $data) {
-+ $output[] = array($type, $data);
-+ }
-+ }
-+
-+ $this->assertSame('123', $process->getOutput());
-+ $this->assertFalse($process->isRunning());
-+
-+ $expectedOutput = array(
-+ array($process::OUT, ''),
-+ array($process::OUT, '123'),
-+ );
-+ $this->assertSame($expectedOutput, $output);
-+ }
-+
-+ public function testChainedProcesses()
-+ {
-+ $p1 = $this->getProcessForCode('fwrite(STDERR, 123); fwrite(STDOUT, 456);');
-+ $p2 = $this->getProcessForCode('stream_copy_to_stream(STDIN, STDOUT);');
-+ $p2->setInput($p1);
-+
-+ $p1->start();
-+ $p2->run();
-+
-+ $this->assertSame('123', $p1->getErrorOutput());
-+ $this->assertSame('', $p1->getOutput());
-+ $this->assertSame('', $p2->getErrorOutput());
-+ $this->assertSame('456', $p2->getOutput());
-+ }
-+
-+ public function testSetBadEnv()
-+ {
-+ $process = $this->getProcess('echo hello');
-+ $process->setEnv(array('bad%%' => '123'));
-+ $process->inheritEnvironmentVariables(true);
-+
-+ $process->run();
-+
-+ $this->assertSame('hello'.PHP_EOL, $process->getOutput());
-+ $this->assertSame('', $process->getErrorOutput());
-+ }
-+
-+ public function testEnvBackupDoesNotDeleteExistingVars()
-+ {
-+ putenv('existing_var=foo');
-+ $process = $this->getProcess('php -r "echo getenv(\'new_test_var\');"');
-+ $process->setEnv(array('existing_var' => 'bar', 'new_test_var' => 'foo'));
-+ $process->inheritEnvironmentVariables();
-+
-+ $process->run();
-+
-+ $this->assertSame('foo', $process->getOutput());
-+ $this->assertSame('foo', getenv('existing_var'));
-+ $this->assertFalse(getenv('new_test_var'));
-+ }
-+
-+ public function testEnvIsInherited()
-+ {
-+ $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));
-+
-+ putenv('FOO=BAR');
-+
-+ $process->run();
-+
-+ $expected = array('BAR' => 'BAZ', 'FOO' => 'BAR');
-+ $env = array_intersect_key(unserialize($process->getOutput()), $expected);
-+
-+ $this->assertEquals($expected, $env);
-+ }
-+
-+ /**
-+ * @group legacy
-+ */
-+ public function testInheritEnvDisabled()
-+ {
-+ $process = $this->getProcessForCode('echo serialize($_SERVER);', null, array('BAR' => 'BAZ'));
-+
-+ putenv('FOO=BAR');
-+
-+ $this->assertSame($process, $process->inheritEnvironmentVariables(false));
-+ $this->assertFalse($process->areEnvironmentVariablesInherited());
-+
-+ $process->run();
-+
-+ $expected = array('BAR' => 'BAZ', 'FOO' => 'BAR');
-+ $env = array_intersect_key(unserialize($process->getOutput()), $expected);
-+ unset($expected['FOO']);
-+
-+ $this->assertSame($expected, $env);
-+ }
-+
-+ public function testGetCommandLine()
-+ {
-+ $p = new Process(array('/usr/bin/php'));
-+
-+ $expected = '\\' === DIRECTORY_SEPARATOR ? '"/usr/bin/php"' : "'/usr/bin/php'";
-+ $this->assertSame($expected, $p->getCommandLine());
-+ }
-+
-+ /**
-+ * @dataProvider provideEscapeArgument
-+ */
-+ public function testEscapeArgument($arg)
-+ {
-+ $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg));
-+ $p->run();
-+
-+ $this->assertSame($arg, $p->getOutput());
-+ }
-+
-+ /**
-+ * @dataProvider provideEscapeArgument
-+ * @group legacy
-+ */
-+ public function testEscapeArgumentWhenInheritEnvDisabled($arg)
-+ {
-+ $p = new Process(array(self::$phpBin, '-r', 'echo $argv[1];', $arg), null, array('BAR' => 'BAZ'));
-+ $p->inheritEnvironmentVariables(false);
-+ $p->run();
-+
-+ $this->assertSame($arg, $p->getOutput());
-+ }
-+
-+ public function testRawCommandLine()
-+ {
-+ $p = new Process(sprintf('"%s" -r %s "a" "" "b"', self::$phpBin, escapeshellarg('print_r($argv);')));
-+ $p->run();
-+
-+ $expected = <<<EOTXT
-+Array
-+(
-+ [0] => -
-+ [1] => a
-+ [2] =>
-+ [3] => b
-+)
-+
-+EOTXT;
-+ $this->assertSame($expected, $p->getOutput());
-+ }
-+
-+ public function provideEscapeArgument()
-+ {
-+ yield array('a"b%c%');
-+ yield array('a"b^c^');
-+ yield array("a\nb'c");
-+ yield array('a^b c!');
-+ yield array("a!b\tc");
-+ yield array('a\\\\"\\"');
-+ yield array('éÉèÈàÀöä');
-+ }
-+
-+ public function testEnvArgument()
-+ {
-+ $env = array('FOO' => 'Foo', 'BAR' => 'Bar');
-+ $cmd = '\\' === DIRECTORY_SEPARATOR ? 'echo !FOO! !BAR! !BAZ!' : 'echo $FOO $BAR $BAZ';
-+ $p = new Process($cmd, null, $env);
-+ $p->run(null, array('BAR' => 'baR', 'BAZ' => 'baZ'));
-+
-+ $this->assertSame('Foo baR baZ', rtrim($p->getOutput()));
-+ $this->assertSame($env, $p->getEnv());
-+ }
-+
-+ /**
-+ * @param string $commandline
-+ * @param null|string $cwd
-+ * @param null|array $env
-+ * @param null|string $input
-+ * @param int $timeout
-+ * @param array $options
-+ *
-+ * @return Process
-+ */
-+ private function getProcess($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60)
-+ {
-+ $process = new Process($commandline, $cwd, $env, $input, $timeout);
-+ $process->inheritEnvironmentVariables();
-+
-+ if (false !== $enhance = getenv('ENHANCE_SIGCHLD')) {
-+ try {
-+ $process->setEnhanceSigchildCompatibility(false);
-+ $process->getExitCode();
-+ $this->fail('ENHANCE_SIGCHLD must be used together with a sigchild-enabled PHP.');
-+ } catch (RuntimeException $e) {
-+ $this->assertSame('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.', $e->getMessage());
-+ if ($enhance) {
-+ $process->setEnhanceSigchildCompatibility(true);
-+ } else {
-+ self::$notEnhancedSigchild = true;
-+ }
-+ }
-+ }
-+
-+ if (self::$process) {
-+ self::$process->stop(0);
-+ }
-+
-+ return self::$process = $process;
-+ }
-+
-+ /**
-+ * @return Process
-+ */
-+ private function getProcessForCode($code, $cwd = null, array $env = null, $input = null, $timeout = 60)
-+ {
-+ return $this->getProcess(array(self::$phpBin, '-r', $code), $cwd, $env, $input, $timeout);
-+ }
-+
-+ private function skipIfNotEnhancedSigchild($expectException = true)
-+ {
-+ if (self::$sigchild) {
-+ if (!$expectException) {
-+ $this->markTestSkipped('PHP is compiled with --enable-sigchild.');
-+ } elseif (self::$notEnhancedSigchild) {
-+ if (method_exists($this, 'expectException')) {
-+ $this->expectException('Symfony\Component\Process\Exception\RuntimeException');
-+ $this->expectExceptionMessage('This PHP has been compiled with --enable-sigchild.');
-+ } else {
-+ $this->setExpectedException('Symfony\Component\Process\Exception\RuntimeException', 'This PHP has been compiled with --enable-sigchild.');
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+class NonStringifiable
-+{
-+}
-diff --git a/vendor/symfony/process/Tests/ProcessUtilsTest.php b/vendor/symfony/process/Tests/ProcessUtilsTest.php
-new file mode 100644
-index 00000000..82fd8cfa
---- /dev/null
-+++ b/vendor/symfony/process/Tests/ProcessUtilsTest.php
-@@ -0,0 +1,53 @@
-+<?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\Process\Tests;
-+
-+use PHPUnit\Framework\TestCase;
-+use Symfony\Component\Process\ProcessUtils;
-+
-+/**
-+ * @group legacy
-+ */
-+class ProcessUtilsTest extends TestCase
-+{
-+ /**
-+ * @dataProvider dataArguments
-+ */
-+ public function testEscapeArgument($result, $argument)
-+ {
-+ $this->assertSame($result, ProcessUtils::escapeArgument($argument));
-+ }
-+
-+ public function dataArguments()
-+ {
-+ if ('\\' === DIRECTORY_SEPARATOR) {
-+ return array(
-+ array('"\"php\" \"-v\""', '"php" "-v"'),
-+ array('"foo bar"', 'foo bar'),
-+ array('^%"path"^%', '%path%'),
-+ array('"<|>\\" \\"\'f"', '<|>" "\'f'),
-+ array('""', ''),
-+ array('"with\trailingbs\\\\"', 'with\trailingbs\\'),
-+ );
-+ }
-+
-+ return array(
-+ array("'\"php\" \"-v\"'", '"php" "-v"'),
-+ array("'foo bar'", 'foo bar'),
-+ array("'%path%'", '%path%'),
-+ array("'<|>\" \"'\\''f'", '<|>" "\'f'),
-+ array("''", ''),
-+ array("'with\\trailingbs\\'", 'with\trailingbs\\'),
-+ array("'withNonAsciiAccentLikeéÉèÈàÀöä'", 'withNonAsciiAccentLikeéÉèÈàÀöä'),
-+ );
-+ }
-+}
-diff --git a/vendor/symfony/process/Tests/SignalListener.php b/vendor/symfony/process/Tests/SignalListener.php
-new file mode 100644
-index 00000000..9e30ce3b
---- /dev/null
-+++ b/vendor/symfony/process/Tests/SignalListener.php
-@@ -0,0 +1,21 @@
-+<?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.
-+ */
-+
-+pcntl_signal(SIGUSR1, function () { echo 'SIGUSR1'; exit; });
-+
-+echo 'Caught ';
-+
-+$n = 0;
-+
-+while ($n++ < 400) {
-+ usleep(10000);
-+ pcntl_signal_dispatch();
-+}
-diff --git a/vendor/symfony/process/composer.json b/vendor/symfony/process/composer.json
-new file mode 100644
-index 00000000..f899c52b
---- /dev/null
-+++ b/vendor/symfony/process/composer.json
-@@ -0,0 +1,33 @@
-+{
-+ "name": "symfony/process",
-+ "type": "library",
-+ "description": "Symfony Process Component",
-+ "keywords": [],
-+ "homepage": "https://symfony.com",
-+ "license": "MIT",
-+ "authors": [
-+ {
-+ "name": "Fabien Potencier",
-+ "email": "fabien@symfony.com"
-+ },
-+ {
-+ "name": "Symfony Community",
-+ "homepage": "https://symfony.com/contributors"
-+ }
-+ ],
-+ "require": {
-+ "php": ">=5.5.9"
-+ },
-+ "autoload": {
-+ "psr-4": { "Symfony\\Component\\Process\\": "" },
-+ "exclude-from-classmap": [
-+ "/Tests/"
-+ ]
-+ },
-+ "minimum-stability": "dev",
-+ "extra": {
-+ "branch-alias": {
-+ "dev-master": "3.3-dev"
-+ }
-+ }
-+}
-diff --git a/vendor/symfony/process/phpunit.xml.dist b/vendor/symfony/process/phpunit.xml.dist
-new file mode 100644
-index 00000000..d3884673
---- /dev/null
-+++ b/vendor/symfony/process/phpunit.xml.dist
-@@ -0,0 +1,30 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+
-+<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
-+ backupGlobals="false"
-+ colors="true"
-+ bootstrap="vendor/autoload.php"
-+ failOnRisky="true"
-+ failOnWarning="true"
-+>
-+ <php>
-+ <ini name="error_reporting" value="-1" />
-+ </php>
-+
-+ <testsuites>
-+ <testsuite name="Symfony Process Component Test Suite">
-+ <directory>./Tests/</directory>
-+ </testsuite>
-+ </testsuites>
-+
-+ <filter>
-+ <whitelist>
-+ <directory>./</directory>
-+ <exclude>
-+ <directory>./Tests</directory>
-+ <directory>./vendor</directory>
-+ </exclude>
-+ </whitelist>
-+ </filter>
-+</phpunit>