92 lines
2.7 KiB
PHP
92 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace Spark\Environment;
|
|
|
|
|
|
class ScriptRunner
|
|
{
|
|
|
|
private array $scripts = [];
|
|
|
|
private ?string $directory = null;
|
|
|
|
public function setDirectory(?string $directory)
|
|
{
|
|
$this->directory = $directory;
|
|
}
|
|
|
|
public function defineScript(string $name, string|array $script)
|
|
{
|
|
$this->scripts[$name] = $script;
|
|
}
|
|
|
|
public function evaluateDefinedScript(string $name)
|
|
{
|
|
$script = $this->scripts[$name];
|
|
$this->evaluate($script);
|
|
}
|
|
|
|
public function evaluate(string|array $script)
|
|
{
|
|
if (is_array($script)) {
|
|
foreach ($script as $step) {
|
|
$this->evaluate($step);
|
|
}
|
|
return;
|
|
}
|
|
|
|
$script = $this->expandString($script);
|
|
|
|
// Determine what to do
|
|
if (str_starts_with($script, '@')) {
|
|
// starts with @, call on a defined script
|
|
$subname = substr($script, 1);
|
|
$subscript = $this->scripts[$subname];
|
|
$this->evaluate($subscript);
|
|
} else {
|
|
if (posix_isatty(STDOUT)) {
|
|
printf("\e[0;33m> \e[0;93m%s\e[0m\n", $script);
|
|
} else {
|
|
printf("> %s\n", $script);
|
|
}
|
|
|
|
if (str_contains($script, ' ')) {
|
|
[$script, $args] = explode(" ", $script, 2);
|
|
$args = str_getcsv($args, ' ', "'");
|
|
|
|
} else {
|
|
$args = [];
|
|
}
|
|
if (is_callable($script)) {
|
|
// call script
|
|
call_user_func($script, ...$args);
|
|
} elseif (file_exists((string)$script) && fnmatch("*.php", (string)$script)) {
|
|
include $script;
|
|
} else {
|
|
// call shell
|
|
$cmdl = trim(escapeshellcmd((string)$script) . " " . join(" ", array_map("escapeshellarg", $args)));
|
|
$proc = proc_open($cmdl, [ 0 => STDIN, 1 => STDOUT, 2 => STDERR ], $pipes, $this->directory);
|
|
while ($stat = proc_get_status($proc)) {
|
|
if ($stat['running'] === false) {
|
|
$ec = $stat['exitcode'];
|
|
if ($ec != 0) {
|
|
printf("\e[31mcommand exited with code %d.\e[0m\n", $stat['exitcode']);
|
|
throw new \RuntimeException("Command {$cmdl} exited with code {$ec}");
|
|
}
|
|
break;
|
|
}
|
|
usleep(100000);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function expandString(string $input)
|
|
{
|
|
return preg_replace_callback('/(\$\{(.+?)\})/', function ($match) {
|
|
|
|
return ($_ENV[$match[2]]??getenv($match[2]))??null;
|
|
}, $input);
|
|
}
|
|
}
|