Files
compras/scripts/dev-evaluation.php
T
2026-11-02 20:27:11 +02:00

108 lines
4.7 KiB
PHP

<?php
declare(strict_types=1);
use Symfony\Component\Process\Process;
require dirname(__DIR__).'/vendor/autoload.php';
$root = dirname(__DIR__);
$entry = 'http://127.0.0.1:8005/avaliar';
$settingsFile = 'C:/laragon/data/sgf-tempo/secrets/payables-demo-compras.json';
$router = dirname($root).'/sgf-tempo/scripts/payables-router.php';
$children = [];
$stop = false;
$status = 0;
function evaluationResponse(string $url): string|false
{
return @file_get_contents($url, false, stream_context_create(['http' => [
'timeout' => 3, 'follow_location' => 0,
]]));
}
try {
if (! is_file($settingsFile) || ! is_file($router)) {
throw new RuntimeException('A configuração da avaliação existente não está disponível. Nenhuma base foi criada ou alterada.');
}
$settings = json_decode(file_get_contents($settingsFile), true, 32, JSON_THROW_ON_ERROR);
if (($settings['APP_ENV'] ?? '') !== 'payable-testing'
|| ($settings['DB_HOST'] ?? '') !== '127.0.0.1'
|| ! preg_match('/^compras_receipts_test_[a-f0-9]{12}$/D', $settings['DB_DATABASE'] ?? '')
|| realpath($settings['HOST_ROOT'] ?? '') !== realpath($root)) {
throw new RuntimeException('A configuração não corresponde à avaliação isolada de Compras. Arranque cancelado.');
}
$response = evaluationResponse($entry);
if ($response === false || ! str_contains($response, 'Explorar Compras')) {
$port = @stream_socket_client('tcp://127.0.0.1:8005', $code, $message, 1);
if (is_resource($port)) {
fclose($port);
throw new RuntimeException('A porta 8005 está ocupada, mas não responde como avaliação de Compras. Nenhum processo foi terminado.');
}
if (in_array('--check', $argv, true)) {
throw new RuntimeException('A avaliação não está em execução. Use composer run dev para a retomar.');
}
$children['avaliação'] = new Process([PHP_BINARY, '-S', '127.0.0.1:8005', '-t', 'public', $router], $root, ['PAYABLE_SETTINGS_FILE' => $settingsFile], timeout: null);
$children['avaliação']->start();
for ($attempt = 0; $attempt < 50; $attempt++) {
usleep(100000);
$response = evaluationResponse($entry);
if ($response !== false && str_contains($response, 'Explorar Compras')) {
break;
}
if (! $children['avaliação']->isRunning()) {
break;
}
}
if ($response === false || ! str_contains($response, 'Explorar Compras')) {
throw new RuntimeException('Não foi possível retomar a avaliação existente. Consulte o arranque local; os dados foram preservados.');
}
}
fwrite(STDOUT, "Compras — ambiente de desenvolvimento e avaliação\n$entry\nEscolha «Entrar como proprietário» ou um perfil de avaliação.\nMesma base persistente; sem migrações, seeds ou redefinição de contas.\n");
if (! in_array('--check', $argv, true)) {
$children['reposição'] = new Process([PHP_BINARY, 'scripts/replenishment-evaluation.php', '--daemon'], $root, timeout: null);
$children['reposição']->start();
$hot = is_file($root.'/public/hot') ? trim(file_get_contents($root.'/public/hot')) : '';
$host = parse_url($hot, PHP_URL_HOST);
$viteReady = in_array($host, ['127.0.0.1', 'localhost', '[::1]'], true)
&& ($module = evaluationResponse($hot.'/resources/js/app.tsx')) !== false
&& str_contains($module, 'SgcShell');
if (! $viteReady) {
$children['vite'] = Process::fromShellCommandline('npm.cmd run dev -- --host 127.0.0.1', $root, ['APP_URL' => 'http://127.0.0.1:8005'], timeout: null);
$children['vite']->start();
} else {
fwrite(STDOUT, "Vite de Compras já disponível; reutilizado.\n");
}
if (function_exists('sapi_windows_set_ctrl_handler')) {
sapi_windows_set_ctrl_handler(function () use (&$stop): bool {
$stop = true;
return true;
});
}
while ($children && ! $stop) {
foreach ($children as $name => $process) {
fwrite(STDOUT, $process->getIncrementalOutput());
fwrite(STDERR, $process->getIncrementalErrorOutput());
if (! $process->isRunning()) {
$status = $process->getExitCode() ?? 1;
$stop = true;
}
}
usleep(100000);
}
}
} catch (Throwable $error) {
fwrite(STDERR, $error->getMessage()."\n");
$status = 1;
} finally {
foreach ($children as $process) {
if ($process->isRunning()) {
$process->stop(2);
}
}
}
exit($status);