diff options
Diffstat (limited to 'scripts/plugin-stub-generator/generate-stubs')
| -rwxr-xr-x | scripts/plugin-stub-generator/generate-stubs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/scripts/plugin-stub-generator/generate-stubs b/scripts/plugin-stub-generator/generate-stubs new file mode 100755 index 00000000..c6b03c97 --- /dev/null +++ b/scripts/plugin-stub-generator/generate-stubs @@ -0,0 +1,97 @@ +#!/usr/bin/env php +<?php + +declare(strict_types=1); + +require __DIR__ . '/vendor/autoload.php'; + +use Shirabe\PluginStubGenerator\GenerationError; +use Shirabe\PluginStubGenerator\Generator; +use Shirabe\PluginStubGenerator\Report; + +$repoRoot = dirname(__DIR__, 2); +$composerRoot = $repoRoot . '/composer'; +$reportPath = $repoRoot . '/scripts/plugin-class-classifier/report.json'; +$stubsDir = $repoRoot . '/crates/shirabe-php-rpc/php/stubs'; +$libRs = $repoRoot . '/crates/shirabe-php-rpc/src/lib.rs'; +$check = false; + +foreach (array_slice($argv, 1) as $arg) { + if (str_starts_with($arg, '--composer-root=')) { + $composerRoot = substr($arg, strlen('--composer-root=')); + } elseif (str_starts_with($arg, '--report=')) { + $reportPath = substr($arg, strlen('--report=')); + } elseif (str_starts_with($arg, '--stubs-dir=')) { + $stubsDir = substr($arg, strlen('--stubs-dir=')); + } elseif ($arg === '--check') { + $check = true; + } else { + fwrite(STDERR, "usage: generate-stubs [--composer-root=DIR] [--report=FILE] [--stubs-dir=DIR] [--check]\n"); + exit(2); + } +} + +$targets = []; +foreach (file(__DIR__ . '/targets.list', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) { + $line = trim($line); + if ($line !== '' && !str_starts_with($line, '#')) { + $targets[] = $line; + } +} + +try { + $generator = new Generator($composerRoot, Report::load($reportPath), $targets); + $files = $generator->generate(); +} catch (GenerationError $e) { + foreach ($e->errors as $error) { + fwrite(STDERR, "error: $error\n"); + } + exit(1); +} + +$problems = []; + +$iterator = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($stubsDir, FilesystemIterator::SKIP_DOTS) +); +foreach ($iterator as $entry) { + if ($entry->isFile() && str_ends_with($entry->getFilename(), '.php')) { + $relative = substr($entry->getPathname(), strlen($stubsDir) + 1); + if (!isset($files[$relative])) { + $problems[] = "stale stub not covered by targets.list: $stubsDir/$relative"; + } + } +} + +// The Rust side embeds every stub with include_str!; the two lists must not drift apart. +$libRsText = (string) file_get_contents($libRs); +foreach ($files as $relative => $_) { + if (!str_contains($libRsText, "include_str!(\"../php/stubs/$relative\")")) { + $problems[] = "STUB_FILES in $libRs does not embed $relative"; + } +} + +if ($check) { + foreach ($files as $relative => $content) { + $current = @file_get_contents("$stubsDir/$relative"); + if ($current === false) { + $problems[] = "missing stub (regenerate): $stubsDir/$relative"; + } elseif ($current !== $content) { + $problems[] = "stale stub (regenerate): $stubsDir/$relative"; + } + } +} else { + foreach ($files as $relative => $content) { + $path = "$stubsDir/$relative"; + if (!is_dir(dirname($path))) { + mkdir(dirname($path), 0777, true); + } + file_put_contents($path, $content); + } + fwrite(STDERR, count($files) . " stubs written to $stubsDir\n"); +} + +foreach ($problems as $problem) { + fwrite(STDERR, "error: $problem\n"); +} +exit($problems === [] ? 0 : 1); |
