diff --git a/composer.json b/composer.json index e6cd45d..0afe6d4 100755 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "psr-4": {"Utopia\\": "src/"} }, "require": { - "php": ">=7.4" + "php": ">=8.0" }, "require-dev": { "phpunit/phpunit": "^9.3", diff --git a/composer.lock b/composer.lock index d4f49f3..8f1ddab 100644 --- a/composer.lock +++ b/composer.lock @@ -4,37 +4,35 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4fc542db2c5d2c7aa335936d5ed23e98", + "content-hash": "a068f575add4bafb95e49a4a079fd14f", "packages": [], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "2.0.x-dev", + "version": "2.2.x-dev", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "0dfb69d79d0964b8a80bfa92c07f50e3e8d73542" + "reference": "78f5d718c7f52afc31e59434f625b34c52875d72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0dfb69d79d0964b8a80bfa92c07f50e3e8d73542", - "reference": "0dfb69d79d0964b8a80bfa92c07f50e3e8d73542", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/78f5d718c7f52afc31e59434f625b34c52875d72", + "reference": "78f5d718c7f52afc31e59434f625b34c52875d72", "shasum": "" }, "require": { - "php": "^8.1" + "php": "^8.4" }, "require-dev": { - "doctrine/coding-standard": "^12", + "doctrine/coding-standard": "^14", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^1.2", - "phpstan/phpstan": "^1.9.4", - "phpstan/phpstan-phpunit": "^1.3", - "phpunit/phpunit": "^10.5", - "vimeo/psalm": "^5.4" + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5.58" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -60,7 +58,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/2.0.x" + "source": "https://github.com/doctrine/instantiator/tree/2.2.x" }, "funding": [ { @@ -76,7 +74,7 @@ "type": "tidelift" } ], - "time": "2024-06-20T19:34:15+00:00" + "time": "2026-01-14T07:50:32+00:00" }, { "name": "laravel/pint", @@ -150,12 +148,12 @@ "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "5ee4e978b7fec6dbd844282126a5a32daa2044c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/5ee4e978b7fec6dbd844282126a5a32daa2044c6", + "reference": "5ee4e978b7fec6dbd844282126a5a32daa2044c6", "shasum": "" }, "require": { @@ -195,7 +193,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.x" }, "funding": [ { @@ -203,20 +201,20 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2025-12-30T16:10:21+00:00" }, { "name": "nikic/php-parser", - "version": "v5.1.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1" + "reference": "8c360e27327c8bd29e1c57721574709d0d706118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1", - "reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8c360e27327c8bd29e1c57721574709d0d706118", + "reference": "8c360e27327c8bd29e1c57721574709d0d706118", "shasum": "" }, "require": { @@ -229,13 +227,14 @@ "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^9.0" }, + "default-branch": true, "bin": [ "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -259,9 +258,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0" + "source": "https://github.com/nikic/PHP-Parser/tree/master" }, - "time": "2024-07-01T20:03:41+00:00" + "time": "2025-12-06T20:24:35+00:00" }, { "name": "phar-io/manifest", @@ -269,12 +268,12 @@ "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" + "reference": "c581d4941e196459bf76c945a8ca922963a66708" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/c581d4941e196459bf76c945a8ca922963a66708", + "reference": "c581d4941e196459bf76c945a8ca922963a66708", "shasum": "" }, "require": { @@ -321,7 +320,7 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" + "source": "https://github.com/phar-io/manifest/tree/master" }, "funding": [ { @@ -329,7 +328,7 @@ "type": "github" } ], - "time": "2024-03-03T12:33:53+00:00" + "time": "2025-11-27T15:23:09+00:00" }, { "name": "phar-io/version", @@ -385,15 +384,10 @@ { "name": "phpstan/phpstan", "version": "1.12.x-dev", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "99756056e2447c92b9e9e24801d17a97b415ead6" - }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/99756056e2447c92b9e9e24801d17a97b415ead6", - "reference": "99756056e2447c92b9e9e24801d17a97b415ead6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/2770dcdf5078d0b0d53f94317e06affe88419aa8", + "reference": "2770dcdf5078d0b0d53f94317e06affe88419aa8", "shasum": "" }, "require": { @@ -438,7 +432,7 @@ "type": "github" } ], - "time": "2024-09-05T15:27:23+00:00" + "time": "2025-09-30T10:16:31+00:00" }, { "name": "phpunit/php-code-coverage", @@ -446,12 +440,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" + "reference": "653bca7ea05439961818f429a2a49ec8a8c7d2fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", - "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/653bca7ea05439961818f429a2a49ec8a8c7d2fb", + "reference": "653bca7ea05439961818f429a2a49ec8a8c7d2fb", "shasum": "" }, "require": { @@ -508,15 +502,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" } ], - "time": "2024-08-22T04:23:01+00:00" + "time": "2025-11-26T14:28:02+00:00" }, { "name": "phpunit/php-file-iterator", @@ -765,12 +771,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e6a204cd0360ecdb88c200384133df8573abcdb5" + "reference": "f9f31a35f726beaab98d1efe3b640e9b40c80baf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6a204cd0360ecdb88c200384133df8573abcdb5", - "reference": "e6a204cd0360ecdb88c200384133df8573abcdb5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f9f31a35f726beaab98d1efe3b640e9b40c80baf", + "reference": "f9f31a35f726beaab98d1efe3b640e9b40c80baf", "shasum": "" }, "require": { @@ -781,7 +787,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=7.3", @@ -792,11 +798,11 @@ "phpunit/php-timer": "^5.0.3", "sebastian/cli-parser": "^1.0.2", "sebastian/code-unit": "^1.0.8", - "sebastian/comparator": "^4.0.8", + "sebastian/comparator": "^4.0.10", "sebastian/diff": "^4.0.6", "sebastian/environment": "^5.1.5", - "sebastian/exporter": "^4.0.6", - "sebastian/global-state": "^5.0.7", + "sebastian/exporter": "^4.0.8", + "sebastian/global-state": "^5.0.8", "sebastian/object-enumerator": "^4.0.4", "sebastian/resource-operations": "^3.0.4", "sebastian/type": "^3.2.1", @@ -855,12 +861,20 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2024-09-04T06:06:52+00:00" + "time": "2026-02-01T08:24:05+00:00" }, { "name": "sebastian/cli-parser", @@ -1035,12 +1049,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "b247957a1c8dc81a671770f74b479c0a78a818f1" + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/b247957a1c8dc81a671770f74b479c0a78a818f1", - "reference": "b247957a1c8dc81a671770f74b479c0a78a818f1", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d", "shasum": "" }, "require": { @@ -1093,15 +1107,27 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2022-09-14T12:46:14+00:00" + "time": "2026-01-24T09:22:56+00:00" }, { "name": "sebastian/complexity", @@ -1295,12 +1321,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/14c6ba52f95a36c3d27c835d65efc7123c446e8c", + "reference": "14c6ba52f95a36c3d27c835d65efc7123c446e8c", "shasum": "" }, "require": { @@ -1356,15 +1382,27 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2024-03-02T06:33:00+00:00" + "time": "2025-09-24T06:03:27+00:00" }, { "name": "sebastian/global-state", @@ -1372,12 +1410,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6", "shasum": "" }, "require": { @@ -1420,15 +1458,27 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" } ], - "time": "2024-03-02T06:35:11+00:00" + "time": "2025-08-10T07:10:35+00:00" }, { "name": "sebastian/lines-of-code", @@ -1605,12 +1655,12 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "reference": "539c6691e0623af6dc6f9c20384c120f963465a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0", + "reference": "539c6691e0623af6dc6f9c20384c120f963465a0", "shasum": "" }, "require": { @@ -1652,15 +1702,27 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2023-02-03T06:07:39+00:00" + "time": "2025-08-10T06:57:39+00:00" }, { "name": "sebastian/resource-operations", @@ -1832,12 +1894,12 @@ "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "9efde63eae583083691719257e7d103e8dc8836f" + "reference": "9c42a808cf53f4ab9b531af2023ef1815699938a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/9efde63eae583083691719257e7d103e8dc8836f", - "reference": "9efde63eae583083691719257e7d103e8dc8836f", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/9c42a808cf53f4ab9b531af2023ef1815699938a", + "reference": "9c42a808cf53f4ab9b531af2023ef1815699938a", "shasum": "" }, "require": { @@ -1903,7 +1965,7 @@ "type": "thanks_dev" } ], - "time": "2025-10-20T12:11:31+00:00" + "time": "2026-02-05T23:49:55+00:00" }, { "name": "swoole/ide-helper", @@ -1949,16 +2011,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.3", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { @@ -1987,7 +2049,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" }, "funding": [ { @@ -1995,7 +2057,7 @@ "type": "github" } ], - "time": "2024-03-03T12:36:25+00:00" + "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], @@ -2004,7 +2066,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.4" + "php": ">=8.0" }, "platform-dev": {}, "plugin-api-version": "2.6.0" diff --git a/src/Console.php b/src/Console.php index a34fcef..893b119 100644 --- a/src/Console.php +++ b/src/Console.php @@ -125,13 +125,14 @@ public static function exit(int $status = 0): void * This function was inspired by: https://stackoverflow.com/a/13287902/2299554 * * @param array|string $cmd - * @param string $input - * @param string $output + * @param string $stdin + * @param string $stdout Stdout contents (by reference). + * @param string $stderr Stderr contents (by reference). * @param int $timeout * @param callable|null $onProgress * @return int */ - public static function execute(array|string $cmd, string $input, string &$output, int $timeout = -1, ?callable $onProgress = null): int + public static function execute(array|string $cmd, string $stdin, string &$stdout, string &$stderr, int $timeout = -1, ?callable $onProgress = null): int { // If the $cmd is passed as string, it will be wrapped into a subshell by \proc_open // Forward stdout and exit codes from the subshell. @@ -146,7 +147,8 @@ public static function execute(array|string $cmd, string $input, string &$output $pipes ); $start = \time(); - $output = ''; + $stdout = ''; + $stderr = ''; $status = ''; if (\is_resource($process)) { @@ -155,7 +157,7 @@ public static function execute(array|string $cmd, string $input, string &$output \stream_set_blocking($pipes[2], false); \stream_set_blocking($pipes[3], false); - \fwrite($pipes[0], $input); + \fwrite($pipes[0], $stdin); \fclose($pipes[0]); } @@ -163,18 +165,15 @@ public static function execute(array|string $cmd, string $input, string &$output $stdoutContents = \stream_get_contents($pipes[1]) ?: ''; $stderrContents = \stream_get_contents($pipes[2]) ?: ''; - $outputContents = $stdoutContents; + $stderr .= $stderrContents; - if (! empty($stderrContents)) { - $separator = empty($outputContents) ? '' : "\n"; - $outputContents .= $separator.$stderrContents; - } + $outputContents = $stdoutContents; if (isset($onProgress) && (! empty($outputContents))) { $onProgress($outputContents, $process); } - $output .= $outputContents; + $stdout .= $outputContents; $status .= \stream_get_contents($pipes[3]); if ($timeout > 0 && \time() - $start > $timeout) { @@ -214,9 +213,9 @@ public static function isInteractive(): bool * * Repeatedly execute a callback while limiting CPU consumption. * - * @param callable $callback - * @param int $sleep Sleep duration in seconds. - * @param int $delay Initial delay in seconds. + * @param callable $callback + * @param int $sleep Sleep duration in seconds. + * @param int $delay Initial delay in seconds. * @param callable|null $onError * * @throws \Exception diff --git a/tests/Console/ConsoleTest.php b/tests/Console/ConsoleTest.php index 2b2a86b..ed5f18c 100644 --- a/tests/Console/ConsoleTest.php +++ b/tests/Console/ConsoleTest.php @@ -20,8 +20,9 @@ public function testLogs(): void public function testExecuteBasic(): void { $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('php -r "echo \'hello world\';"', $input, $output, 10); + $code = Console::execute('php -r "echo \'hello world\';"', $input, $output, $stderr, 10); $this->assertEquals('hello world', $output); $this->assertEquals(0, $code); @@ -30,9 +31,10 @@ public function testExecuteBasic(): void public function testExecuteArray(): void { $output = ''; + $stderr = ''; $input = ''; $cmd = ['php', '-r', "echo 'hello world';"]; - $code = Console::execute($cmd, $input, $output, 10); + $code = Console::execute($cmd, $input, $output, $stderr, 10); $this->assertEquals('hello world', $output); $this->assertEquals(0, $code); @@ -44,9 +46,10 @@ public function testExecuteEnvVariables(): void putenv("FOO={$randomData}"); $output = ''; + $stderr = ''; $input = ''; $cmd = ['printenv']; - $code = Console::execute($cmd, $input, $output, 10); + $code = Console::execute($cmd, $input, $output, $stderr, 10); $this->assertEquals(0, $code); @@ -68,10 +71,11 @@ public function testExecuteEnvVariables(): void public function testExecuteStream(): void { $output = ''; + $stderr = ''; $input = ''; $outputStream = ''; - $code = Console::execute('printf 1 && sleep 1 && printf 2 && sleep 1 && printf 3 && sleep 1 && printf 4 && sleep 1 && printf 5', $input, $output, 10, function ($output) use (&$outputStream) { + $code = Console::execute('printf 1 && sleep 1 && printf 2 && sleep 1 && printf 3 && sleep 1 && printf 4 && sleep 1 && printf 5', $input, $output, $stderr, 10, function ($output) use (&$outputStream) { $outputStream .= $output; }); @@ -83,35 +87,41 @@ public function testExecuteStream(): void public function testExecuteStdOut(): void { $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('>&1 echo "success"', $input, $output, 3); + $code = Console::execute('>&1 echo "success"', $input, $output, $stderr, 3); $this->assertEquals("success\n", $output); + $this->assertEquals('', $stderr); $this->assertEquals(0, $code); } public function testExecuteStdErr(): void { $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('>&2 echo "error"', $input, $output, 3); + $code = Console::execute('>&2 echo "error"', $input, $output, $stderr, 3); - $this->assertEquals("error\n", $output); + $this->assertEquals('', $output); + $this->assertEquals("error\n", $stderr); $this->assertEquals(0, $code); } public function testExecuteExitCode(): void { $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('php -r "echo \'hello world\'; exit(2);"', $input, $output, 10); + $code = Console::execute('php -r "echo \'hello world\'; exit(2);"', $input, $output, $stderr, 10); $this->assertEquals('hello world', $output); $this->assertEquals(2, $code); $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('php -r "echo \'hello world\'; exit(100);"', $input, $output, 10); + $code = Console::execute('php -r "echo \'hello world\'; exit(100);"', $input, $output, $stderr, 10); $this->assertEquals('hello world', $output); $this->assertEquals(100, $code); @@ -120,15 +130,17 @@ public function testExecuteExitCode(): void public function testExecuteTimeout(): void { $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('php -r "sleep(1); echo \'hello world\'; exit(0);"', $input, $output, 3); + $code = Console::execute('php -r "sleep(1); echo \'hello world\'; exit(0);"', $input, $output, $stderr, 3); $this->assertEquals('hello world', $output); $this->assertEquals(0, $code); $output = ''; + $stderr = ''; $input = ''; - $code = Console::execute('php -r "sleep(4); echo \'hello world\'; exit(0);"', $input, $output, 3); + $code = Console::execute('php -r "sleep(4); echo \'hello world\'; exit(0);"', $input, $output, $stderr, 3); $this->assertEquals('', $output); $this->assertEquals(1, $code); @@ -139,7 +151,8 @@ public function testLoop(): void $file = __DIR__.'/../resources/loop.php'; $input = ''; $output = ''; - $code = Console::execute('php '.$file, $input, $output, 30); + $stderr = ''; + $code = Console::execute('php '.$file, $input, $output, $stderr, 30); $lines = explode("\n", $output);