-<?php
+<?php declare(strict_types=1);
namespace Cli\Services;
+use Exception;
use Symfony\Component\Process\ExecutableFinder;
use Symfony\Component\Process\Process;
class ProgramRunner
{
+ /**
+ * Names of the program to search for.
+ * @var string[]
+ */
+ protected array $programNames = [];
+
protected int $timeout = 240;
protected int $idleTimeout = 15;
protected array $environment = [];
protected array $additionalProgramDirectories = [];
public function __construct(
- protected string $program,
+ string|array $program,
protected string $defaultPath
) {
+ $this->programNames = is_string($program) ? [$program] : $program;
}
public function withTimeout(int $timeoutSeconds): static
}
/**
- * @throws \Exception
+ * @throws Exception
*/
public function ensureFound(): void
{
try {
$this->ensureFound();
return true;
- } catch (\Exception $exception) {
+ } catch (Exception $exception) {
return false;
}
}
return $process;
}
+ /**
+ * @throws Exception
+ */
protected function resolveProgramPath(): string
{
- $executableFinder = new ExecutableFinder();
- $path = $executableFinder->find($this->program, $this->defaultPath, $this->additionalProgramDirectories);
+ foreach ($this->programNames as $programName) {
+ $executableFinder = new ExecutableFinder();
+ $path = $executableFinder->find($programName, $this->defaultPath, $this->additionalProgramDirectories);
- if (is_null($path) || !is_file($path)) {
- throw new \Exception("Could not locate \"{$this->program}\" program.");
+ if (!is_null($path) && is_file($path)) {
+ return $path;
+ }
}
- return $path;
+ $combinedProgram = implode('|', $this->programNames);
+ throw new Exception("Could not locate \"{$combinedProgram}\" program.");
}
}