mirror of
https://github.com/pestphp/pest.git
synced 2026-06-05 02:52:12 +02:00
wip
This commit is contained in:
@ -69,11 +69,6 @@ final readonly class BaselineSync
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->output->writeln(sprintf(
|
|
||||||
' <fg=cyan>TIA</> fetching baseline from <fg=white>%s</>…',
|
|
||||||
$repo,
|
|
||||||
));
|
|
||||||
|
|
||||||
$payload = $this->download($repo, $projectRoot);
|
$payload = $this->download($repo, $projectRoot);
|
||||||
|
|
||||||
if ($payload === null) {
|
if ($payload === null) {
|
||||||
@ -322,6 +317,12 @@ YAML;
|
|||||||
// id as recently used and doesn't evict it later.
|
// id as recently used and doesn't evict it later.
|
||||||
@touch($runCacheDir);
|
@touch($runCacheDir);
|
||||||
|
|
||||||
|
$this->output->writeln(sprintf(
|
||||||
|
' <fg=cyan>TIA</> using cached baseline from <fg=white>%s</> (run %s).',
|
||||||
|
$repo,
|
||||||
|
$runId,
|
||||||
|
));
|
||||||
|
|
||||||
return $this->readArtifact($runCacheDir);
|
return $this->readArtifact($runCacheDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +330,19 @@ YAML;
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$artifactSize = $this->artifactSize($repo, $runId);
|
||||||
|
|
||||||
|
$this->output->writeln($artifactSize !== null
|
||||||
|
? sprintf(
|
||||||
|
' <fg=cyan>TIA</> fetching baseline (%s) from <fg=white>%s</>…',
|
||||||
|
$this->formatSize($artifactSize),
|
||||||
|
$repo,
|
||||||
|
)
|
||||||
|
: sprintf(
|
||||||
|
' <fg=cyan>TIA</> fetching baseline from <fg=white>%s</>…',
|
||||||
|
$repo,
|
||||||
|
));
|
||||||
|
|
||||||
$process = new Process([
|
$process = new Process([
|
||||||
'gh', 'run', 'download', $runId,
|
'gh', 'run', 'download', $runId,
|
||||||
'-R', $repo,
|
'-R', $repo,
|
||||||
@ -336,7 +350,17 @@ YAML;
|
|||||||
'-D', $runCacheDir,
|
'-D', $runCacheDir,
|
||||||
]);
|
]);
|
||||||
$process->setTimeout(900.0);
|
$process->setTimeout(900.0);
|
||||||
$process->run();
|
$process->start();
|
||||||
|
|
||||||
|
$startedAt = microtime(true);
|
||||||
|
|
||||||
|
while ($process->isRunning()) {
|
||||||
|
$this->renderDownloadProgress($runCacheDir, $artifactSize, $startedAt);
|
||||||
|
usleep(250_000);
|
||||||
|
}
|
||||||
|
|
||||||
|
$process->wait();
|
||||||
|
$this->clearProgressLine();
|
||||||
|
|
||||||
if (! $process->isSuccessful()) {
|
if (! $process->isSuccessful()) {
|
||||||
$this->cleanup($runCacheDir);
|
$this->cleanup($runCacheDir);
|
||||||
@ -357,6 +381,93 @@ YAML;
|
|||||||
return $payload;
|
return $payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up the artifact's compressed size so the progress bar has a
|
||||||
|
* denominator. Returns null on any failure — callers fall back to a
|
||||||
|
* size-less spinner.
|
||||||
|
*/
|
||||||
|
private function artifactSize(string $repo, string $runId): ?int
|
||||||
|
{
|
||||||
|
$process = new Process([
|
||||||
|
'gh', 'api',
|
||||||
|
sprintf('repos/%s/actions/runs/%s/artifacts', $repo, $runId),
|
||||||
|
'--jq', sprintf(
|
||||||
|
'.artifacts[] | select(.name == "%s") | .size_in_bytes',
|
||||||
|
self::ARTIFACT_NAME,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
$process->setTimeout(30.0);
|
||||||
|
$process->run();
|
||||||
|
|
||||||
|
if (! $process->isSuccessful()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$size = trim($process->getOutput());
|
||||||
|
|
||||||
|
return is_numeric($size) ? (int) $size : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function renderDownloadProgress(string $dir, ?int $totalBytes, float $startedAt): void
|
||||||
|
{
|
||||||
|
$current = $this->dirSize($dir);
|
||||||
|
$elapsed = max(0.001, microtime(true) - $startedAt);
|
||||||
|
$speed = (int) ($current / $elapsed);
|
||||||
|
|
||||||
|
if ($totalBytes !== null && $totalBytes > 0) {
|
||||||
|
// gh extracts as it downloads, so disk size can briefly exceed
|
||||||
|
// the compressed `size_in_bytes` for multi-file artifacts. Cap
|
||||||
|
// the percentage at 99% until the process actually exits — the
|
||||||
|
// cleared line + completion message take care of the final
|
||||||
|
// "100%" message naturally.
|
||||||
|
$percent = min(99, (int) floor(($current / $totalBytes) * 100));
|
||||||
|
$message = sprintf(
|
||||||
|
' <fg=cyan>TIA</> downloading %s / %s (%d%%, %s/s)',
|
||||||
|
$this->formatSize($current),
|
||||||
|
$this->formatSize($totalBytes),
|
||||||
|
$percent,
|
||||||
|
$this->formatSize($speed),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$message = sprintf(
|
||||||
|
' <fg=cyan>TIA</> downloading %s (%s/s)',
|
||||||
|
$this->formatSize($current),
|
||||||
|
$this->formatSize($speed),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// \r returns to start of line, \033[K erases from cursor to end —
|
||||||
|
// safe regardless of message length, no ANSI-aware padding needed.
|
||||||
|
$this->output->write("\r\033[K".$message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function clearProgressLine(): void
|
||||||
|
{
|
||||||
|
$this->output->write("\r\033[K");
|
||||||
|
}
|
||||||
|
|
||||||
|
private function dirSize(string $dir): int
|
||||||
|
{
|
||||||
|
if (! is_dir($dir)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = 0;
|
||||||
|
|
||||||
|
$iterator = new \RecursiveIteratorIterator(
|
||||||
|
new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS),
|
||||||
|
);
|
||||||
|
|
||||||
|
/** @var \SplFileInfo $entry */
|
||||||
|
foreach ($iterator as $entry) {
|
||||||
|
if ($entry->isFile()) {
|
||||||
|
$total += $entry->getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $total;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array{graph: string, coverage: ?string}|null
|
* @return array{graph: string, coverage: ?string}|null
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user