1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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);
|