diff --git a/src/Composer/Package/Version/VersionGuesser.php b/src/Composer/Package/Version/VersionGuesser.php index d9c18a8239f0..fbf695a369e5 100644 --- a/src/Composer/Package/Version/VersionGuesser.php +++ b/src/Composer/Package/Version/VersionGuesser.php @@ -137,7 +137,7 @@ private function guessGitVersion(array $packageConfig, $path) $isDetached = false; // try to fetch current version from git branch - if (0 === $this->process->execute('git branch -a --no-color --no-abbrev -v', $output, $path)) { + if (0 === $this->process->execute(['git', 'branch', '-a', '--no-color', '--no-abbrev', '-v'], $output, $path)) { $branches = array(); $isFeatureBranch = false; diff --git a/src/Composer/Util/ProcessExecutor.php b/src/Composer/Util/ProcessExecutor.php index e6281dd58a87..67eeffd1499b 100644 --- a/src/Composer/Util/ProcessExecutor.php +++ b/src/Composer/Util/ProcessExecutor.php @@ -62,7 +62,7 @@ public function __construct(IOInterface $io = null) /** * runs a process on the commandline * - * @param string $command the command to execute + * @param string|list $command the command to execute * @param mixed $output the output will be written into this var if passed by ref * if a callable is passed it will be used as output handler * @param ?string $cwd the working directory @@ -80,7 +80,7 @@ public function execute($command, &$output = null, $cwd = null) /** * runs a process on the commandline in TTY mode * - * @param string $command the command to execute + * @param string|list $command the command to execute * @param ?string $cwd the working directory * @return int statuscode */ @@ -94,7 +94,7 @@ public function executeTty($command, $cwd = null) } /** - * @param string $command + * @param string|list $command * @param ?string $cwd * @param bool $tty * @param mixed $output @@ -107,7 +107,12 @@ private function doExecute($command, $cwd, $tty, &$output = null) $this->captureOutput = func_num_args() > 3; $this->errorOutput = ''; - $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout()); + if (is_string($command)) { + $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout()); + } else { + $process = new Process($command, $cwd, null, null, static::getTimeout()); + } + if (!Platform::isWindows() && $tty) { try { $process->setTty(true); @@ -131,8 +136,8 @@ private function doExecute($command, $cwd, $tty, &$output = null) /** * starts a process on the commandline in async mode * - * @param string $command the command to execute - * @param string $cwd the working directory + * @param string|list $command the command to execute + * @param string $cwd the working directory * @return PromiseInterface */ public function executeAsync($command, $cwd = null) @@ -222,7 +227,11 @@ private function startJob($id) $this->outputCommandRun($command, $cwd, true); try { - $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout()); + if (is_string($command)) { + $process = Process::fromShellCommandline($command, $cwd, null, null, static::getTimeout()); + } else { + $process = new Process($command, $cwd, null, null, static::getTimeout()); + } } catch (\Throwable $e) { call_user_func($job['reject'], $e); @@ -387,17 +396,15 @@ public static function escape($argument) } /** - * @param string $command - * @param ?string $cwd - * @param bool $async - * @return void + * @param string|list $command */ - private function outputCommandRun($command, $cwd, $async) + private function outputCommandRun($command, ?string $cwd, bool $async): void { if (null === $this->io || !$this->io->isDebug()) { return; } + $commandString = is_string($command) ? $command : implode(' ', array_map(self::class.'::escape', $command)); $safeCommand = Preg::replaceCallback('{://(?P[^:/\s]+):(?P[^@\s/]+)@}i', function ($m) { // if the username looks like a long (12char+) hex string, or a modern github token (e.g. ghp_xxx) we obfuscate that if (Preg::isMatch('{^([a-f0-9]{12,}|gh[a-z]_[a-zA-Z0-9_]+)$}', $m['user'])) { @@ -408,7 +415,7 @@ private function outputCommandRun($command, $cwd, $async) } return '://'.$m['user'].':***@'; - }, $command); + }, $commandString); $safeCommand = Preg::replace("{--password (.*[^\\\\]\') }", '--password \'***\' ', $safeCommand); $this->io->writeError('Executing'.($async ? ' async' : '').' command ('.($cwd ?: 'CWD').'): '.$safeCommand); }