phpstan-mcp-mx 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -0
- package/dist/baseline.d.ts +13 -0
- package/dist/baseline.js +47 -0
- package/dist/baseline.js.map +1 -1
- package/dist/changed.d.ts +3 -1
- package/dist/changed.js +10 -3
- package/dist/changed.js.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/phpstan.d.ts +55 -0
- package/dist/phpstan.js +141 -11
- package/dist/phpstan.js.map +1 -1
- package/dist/project.d.ts +12 -0
- package/dist/project.js +44 -2
- package/dist/project.js.map +1 -1
- package/dist/report.d.ts +6 -1
- package/dist/report.js +10 -4
- package/dist/report.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/tools.d.ts +11 -0
- package/dist/tools.js +244 -8
- package/dist/tools.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -286,6 +286,7 @@ antwoord volloopt met wat er al jaren stond.
|
|
|
286
286
|
| --- | --- | --- |
|
|
287
287
|
| `project` | ja | absoluut pad naar de projectroot |
|
|
288
288
|
| `base` | nee | commit, branch of tag om tegen te vergelijken (standaard `HEAD`) |
|
|
289
|
+
| `staged` | nee | alleen wat gestaged is (`git diff --cached`), voor een check vóór een commit |
|
|
289
290
|
|
|
290
291
|
Verder dezelfde argumenten als `analyse_project`, op `paths` na. Met `base=main` krijg je de
|
|
291
292
|
hele branch in plaats van alleen je onopgeslagen werk.
|
|
@@ -302,6 +303,34 @@ als "overgeslagen" bij het antwoord te staan in plaats van er stil uit te vallen
|
|
|
302
303
|
Staat het project niet onder git, dan zegt de tool dat en verwijst hij naar `analyse_project`
|
|
303
304
|
met expliciete `paths`.
|
|
304
305
|
|
|
306
|
+
### `diagnose_project`
|
|
307
|
+
|
|
308
|
+
Vraagt PHPStan zelf om zijn opstelling: PHP- en PHPStan-versie, de configs die
|
|
309
|
+
Composer-pakketten meebrengen (zoals Larastan) en of de turbo-extensie aanstaat. Draait geen
|
|
310
|
+
analyse.
|
|
311
|
+
|
|
312
|
+
Gebruik dit als een project zich anders gedraagt dan een ander project, vóórdat je aan de
|
|
313
|
+
code gaat twijfelen. Dat is niet theoretisch: hiermee bleek dat één project een dependency
|
|
314
|
+
had (`laravel/pao`) die de uitvoer van PHPStan onderschepte.
|
|
315
|
+
|
|
316
|
+
### `clear_result_cache`
|
|
317
|
+
|
|
318
|
+
Leegt PHPStans resultcache, zodat de volgende analyse alles opnieuw doorrekent. Nuttig als
|
|
319
|
+
een uitslag niet klopt met de code — bijvoorbeeld na een wijziging aan een extensie of een
|
|
320
|
+
geïncludeerde config.
|
|
321
|
+
|
|
322
|
+
Die cache ligt standaard **niet** in het project maar in de tijdelijke map van het systeem
|
|
323
|
+
(`sys_get_temp_dir()/phpstan`), en wordt dan gedeeld met elk ander project dat geen eigen
|
|
324
|
+
`tmpDir` zet. Bovendien volgt die map `TMPDIR`, dus wat de server leegt hoeft niet dezelfde
|
|
325
|
+
map te zijn als wat je terminal gebruikt. Het antwoord noemt daarom de map die geleegd is:
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
Result cache cleared from directory:
|
|
329
|
+
/var/tmp/phpstan
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Wil je per project een eigen cache, zet dan `tmpDir` in je `phpstan.neon`.
|
|
333
|
+
|
|
305
334
|
### `baseline_summary`
|
|
306
335
|
|
|
307
336
|
Leest de `phpstan-baseline*.neon` van een project en telt wat er genegeerd wordt, per
|
|
@@ -311,6 +340,45 @@ Let op het onderscheid: wat hier in staat is precies wat `analyse_project` *niet
|
|
|
311
340
|
project dat zijn baseline includet, rapporteert alleen de fouten die er nieuw bij komen —
|
|
312
341
|
die vergelijking maakt PHPStan zelf al.
|
|
313
342
|
|
|
343
|
+
### `generate_baseline` (alleen met schrijfrechten)
|
|
344
|
+
|
|
345
|
+
Zet alle huidige fouten in een baseline, zodat een volgende analyse alleen meldt wat er nieuw
|
|
346
|
+
bij komt. Bedoeld om een bestaand project onder PHPStan te krijgen — niet om fouten weg te
|
|
347
|
+
werken.
|
|
348
|
+
|
|
349
|
+
Deze tool bestaat alleen als de server met `PHPSTAN_MCP_ALLOW_WRITES=1` gestart is:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
claude mcp add phpstan --scope user \
|
|
353
|
+
--env PHPSTAN_MCP_ROOTS=/pad/naar/projecten \
|
|
354
|
+
--env PHPSTAN_MCP_ALLOW_WRITES=1 \
|
|
355
|
+
-- phpstan-mcp-mx
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Zonder die variabele wordt hij niet geregistreerd — hij staat dan dus ook niet in de
|
|
359
|
+
toollijst, in plaats van dat hij bestaat en bij elke aanroep weigert. Alle andere tools
|
|
360
|
+
blijven read-only.
|
|
361
|
+
|
|
362
|
+
| Argument | Verplicht | Betekenis |
|
|
363
|
+
| --- | --- | --- |
|
|
364
|
+
| `project` | ja | absoluut pad naar de projectroot |
|
|
365
|
+
| `file` | nee | doelbestand binnen het project (standaard `phpstan-baseline.neon`) |
|
|
366
|
+
| `allowEmpty` | nee | ook schrijven als er niets te negeren valt |
|
|
367
|
+
|
|
368
|
+
Verder dezelfde `paths`, `level`, `config` en `memoryLimit` als een analyse. Het antwoord
|
|
369
|
+
zegt erbij wat er nog moet gebeuren, want een baseline die nergens ingesloten wordt doet
|
|
370
|
+
niets:
|
|
371
|
+
|
|
372
|
+
```
|
|
373
|
+
5 fout(en) in phpstan-baseline.neon gezet.
|
|
374
|
+
|
|
375
|
+
Deze fouten worden vanaf nu niet meer gemeld zodra phpstan-baseline.neon in de
|
|
376
|
+
configuratie staat:
|
|
377
|
+
|
|
378
|
+
includes:
|
|
379
|
+
- phpstan-baseline.neon
|
|
380
|
+
```
|
|
381
|
+
|
|
314
382
|
## Wat je terugkrijgt
|
|
315
383
|
|
|
316
384
|
Een analyse levert eerst tellingen over álle bevindingen en daarna één pagina met de
|
|
@@ -354,6 +422,18 @@ Dat onderscheid is wezenlijk: zonder die regel is een lege uitslag niet te onder
|
|
|
354
422
|
een schone. Staat er een waarschuwing, dan leest het antwoord ook niet meer "Geen
|
|
355
423
|
bevindingen" maar "Verder geen bevindingen".
|
|
356
424
|
|
|
425
|
+
Doet er een baseline mee, dan staat dat er ook bij:
|
|
426
|
+
|
|
427
|
+
```
|
|
428
|
+
Ter info:
|
|
429
|
+
- phpstan-baseline.neon wordt geïncludeerd: 1037 genegeerde fout(en) staan niet in dit
|
|
430
|
+
rapport. Gebruik baseline_summary om te zien wat er in staat.
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
Dat is het verschil tussen "geen bevindingen" en "geen bevindingen, plus duizend die niet
|
|
434
|
+
gemeld worden". De check kijkt of je config het bestand echt includeert — een baseline die
|
|
435
|
+
naast `phpstan.neon` ligt zonder erin te staan, doet niets.
|
|
436
|
+
|
|
357
437
|
Het `warnings`-veld staat los van `generalErrors`: dat tweede is PHPStans eigen
|
|
358
438
|
`errors`-array uit de JSON. Beide lijsten zijn begrensd op tien meldingen van elk hoogstens
|
|
359
439
|
1000 tekens — een mislukte Laravel-bootstrap levert anders een lap tekst op die het hele
|
package/dist/baseline.d.ts
CHANGED
|
@@ -37,6 +37,19 @@ export declare class BaselineError extends Error {
|
|
|
37
37
|
* van pakketten in vendor/ oppikken.
|
|
38
38
|
*/
|
|
39
39
|
export declare function findBaselineFiles(project: ResolvedProject): string[];
|
|
40
|
+
/**
|
|
41
|
+
* Meldt of de configuratie van dit project een baseline includeert, en hoeveel
|
|
42
|
+
* fouten die dan verbergt. Null als er geen baseline meedoet.
|
|
43
|
+
*
|
|
44
|
+
* Dit is nodig omdat een schone uitslag dan geen schone code betekent: PHPStan past
|
|
45
|
+
* de baseline zelf toe en rapporteert alleen wat er nieuw bij komt. Dat staat in de
|
|
46
|
+
* toolbeschrijving, maar niet in het antwoord waar het model naar kijkt.
|
|
47
|
+
*
|
|
48
|
+
* De include-check is regelgericht, net als de parser zelf: een lijst-entry die naar
|
|
49
|
+
* een baseline-bestand verwijst. Op de hele bestandsinhoud matchen zou ook aanslaan
|
|
50
|
+
* op een naam in een comment of onder een andere sleutel.
|
|
51
|
+
*/
|
|
52
|
+
export declare function describeIncludedBaseline(project: ResolvedProject): string | null;
|
|
40
53
|
/**
|
|
41
54
|
* Leest een baseline-bestand uit.
|
|
42
55
|
*
|
package/dist/baseline.js
CHANGED
|
@@ -21,6 +21,53 @@ export function findBaselineFiles(project) {
|
|
|
21
21
|
return [];
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Meldt of de configuratie van dit project een baseline includeert, en hoeveel
|
|
26
|
+
* fouten die dan verbergt. Null als er geen baseline meedoet.
|
|
27
|
+
*
|
|
28
|
+
* Dit is nodig omdat een schone uitslag dan geen schone code betekent: PHPStan past
|
|
29
|
+
* de baseline zelf toe en rapporteert alleen wat er nieuw bij komt. Dat staat in de
|
|
30
|
+
* toolbeschrijving, maar niet in het antwoord waar het model naar kijkt.
|
|
31
|
+
*
|
|
32
|
+
* De include-check is regelgericht, net als de parser zelf: een lijst-entry die naar
|
|
33
|
+
* een baseline-bestand verwijst. Op de hele bestandsinhoud matchen zou ook aanslaan
|
|
34
|
+
* op een naam in een comment of onder een andere sleutel.
|
|
35
|
+
*/
|
|
36
|
+
export function describeIncludedBaseline(project) {
|
|
37
|
+
if (project.config === null)
|
|
38
|
+
return null;
|
|
39
|
+
let config;
|
|
40
|
+
try {
|
|
41
|
+
config = readFileSync(join(project.path, project.config), 'utf8');
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
const included = findBaselineFiles(project).filter((file) => isIncludedIn(config, file));
|
|
47
|
+
if (included.length === 0)
|
|
48
|
+
return null;
|
|
49
|
+
const namen = included.join(', ');
|
|
50
|
+
let errors;
|
|
51
|
+
try {
|
|
52
|
+
const summary = summariseBaseline(project);
|
|
53
|
+
errors = summary.files
|
|
54
|
+
.filter((entry) => included.includes(entry.file))
|
|
55
|
+
.reduce((total, entry) => total + entry.errors, 0);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Een onleesbare baseline mag geen analyse omleggen. Dat hij meedoet is ook
|
|
59
|
+
// zonder aantal het vermelden waard — juist dan, want dan is niet te zeggen
|
|
60
|
+
// hoeveel er verborgen wordt.
|
|
61
|
+
return `${namen} wordt geïncludeerd en is niet te lezen; wat daarin staat, meldt deze analyse niet.`;
|
|
62
|
+
}
|
|
63
|
+
return (`${namen} wordt geïncludeerd: ${String(errors)} genegeerde fout(en) staan niet in dit ` +
|
|
64
|
+
'rapport. Gebruik baseline_summary om te zien wat er in staat.');
|
|
65
|
+
}
|
|
66
|
+
/** Of `file` in deze config als lijst-entry voorkomt, met of zonder ./ ervoor. */
|
|
67
|
+
function isIncludedIn(config, file) {
|
|
68
|
+
const escaped = file.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
69
|
+
return new RegExp(`^\\s*-\\s*['"]?(?:\\./)?${escaped}['"]?\\s*$`, 'm').test(config);
|
|
70
|
+
}
|
|
24
71
|
/**
|
|
25
72
|
* Leest een baseline-bestand uit.
|
|
26
73
|
*
|
package/dist/baseline.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../src/baseline.ts"],"names":[],"mappings":"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"}
|
package/dist/changed.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export declare const DEFAULT_BASE = "HEAD";
|
|
|
7
7
|
/** De gewijzigde PHP-bestanden van een project, met wat er niet bruikbaar was. */
|
|
8
8
|
export interface ChangedFiles {
|
|
9
9
|
readonly base: string;
|
|
10
|
+
/** Of er naar de index gekeken is in plaats van naar de werkboom. */
|
|
11
|
+
readonly staged: boolean;
|
|
10
12
|
/** Absolute paden binnen het project, alfabetisch zodat de volgorde vastligt. */
|
|
11
13
|
readonly files: readonly string[];
|
|
12
14
|
/** Paden die git noemde maar die niet te gebruiken zijn, met de reden. */
|
|
@@ -22,4 +24,4 @@ export interface ChangedFiles {
|
|
|
22
24
|
* veranderd is, en `ls-files --others` de nieuwe bestanden die nog nergens in staan.
|
|
23
25
|
* Zonder die tweede mist juist het bestand dat net is aangemaakt.
|
|
24
26
|
*/
|
|
25
|
-
export declare function changedPhpFiles(project: ResolvedProject, base?: string): Promise<ChangedFiles>;
|
|
27
|
+
export declare function changedPhpFiles(project: ResolvedProject, base?: string, staged?: boolean): Promise<ChangedFiles>;
|
package/dist/changed.js
CHANGED
|
@@ -17,7 +17,7 @@ const GIT_TIMEOUT_MS = 15_000;
|
|
|
17
17
|
* veranderd is, en `ls-files --others` de nieuwe bestanden die nog nergens in staan.
|
|
18
18
|
* Zonder die tweede mist juist het bestand dat net is aangemaakt.
|
|
19
19
|
*/
|
|
20
|
-
export async function changedPhpFiles(project, base = DEFAULT_BASE) {
|
|
20
|
+
export async function changedPhpFiles(project, base = DEFAULT_BASE, staged = false) {
|
|
21
21
|
// --relative: zonder dat rapporteert git paden vanaf de repositoryroot, en die
|
|
22
22
|
// hoeft niet de projectroot te zijn — een project kan in een monorepo liggen.
|
|
23
23
|
//
|
|
@@ -32,10 +32,17 @@ export async function changedPhpFiles(project, base = DEFAULT_BASE) {
|
|
|
32
32
|
'--name-only',
|
|
33
33
|
'--relative',
|
|
34
34
|
'--diff-filter=ACMR',
|
|
35
|
+
// --cached vergelijkt de index met `base` in plaats van de werkboom: dat is de
|
|
36
|
+
// vraag "wat sta ik op het punt te committen".
|
|
37
|
+
...(staged ? ['--cached'] : []),
|
|
35
38
|
'--end-of-options',
|
|
36
39
|
checkBase(base),
|
|
37
40
|
]);
|
|
38
|
-
|
|
41
|
+
// Niet-toegevoegde bestanden horen er alleen bij als je naar de werkboom kijkt.
|
|
42
|
+
// Bij --cached zijn ze per definitie niet gestaged, dus dan blijft die uitvraag weg.
|
|
43
|
+
const untracked = staged
|
|
44
|
+
? ''
|
|
45
|
+
: await git(project.path, ['ls-files', '--others', '--exclude-standard']);
|
|
39
46
|
const candidates = [...new Set([...lines(changed), ...lines(untracked)])]
|
|
40
47
|
.filter(isAnalysablePhp)
|
|
41
48
|
.sort();
|
|
@@ -58,7 +65,7 @@ export async function changedPhpFiles(project, base = DEFAULT_BASE) {
|
|
|
58
65
|
});
|
|
59
66
|
}
|
|
60
67
|
}
|
|
61
|
-
return { base, files, skipped };
|
|
68
|
+
return { base, staged, files, skipped };
|
|
62
69
|
}
|
|
63
70
|
/**
|
|
64
71
|
* Blade-templates eindigen óók op `.php`, en juist die moeten er niet in: een
|
package/dist/changed.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changed.js","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D,+EAA+E;AAC/E,MAAM,OAAO,QAAS,SAAQ,KAAK;CAAG;AAEtC,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAEnC;;;GAGG;AACH,MAAM,cAAc,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"changed.js","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { loadDefaultMemoryLimit, loadMaxParallel } from './phpstan.js';
|
|
4
|
+
import { WRITES_ENV_VAR, writesAllowed } from './tools.js';
|
|
4
5
|
import { loadRoots } from './roots.js';
|
|
5
6
|
import { VERSION, createServer } from './server.js';
|
|
6
7
|
async function main() {
|
|
@@ -11,7 +12,8 @@ async function main() {
|
|
|
11
12
|
await server.connect(new StdioServerTransport());
|
|
12
13
|
console.error(`phpstan-mcp ${VERSION} luistert op stdio, ${roots.length} root(s) geconfigureerd` +
|
|
13
14
|
describeMemoryDefault() +
|
|
14
|
-
describeMaxParallel()
|
|
15
|
+
describeMaxParallel() +
|
|
16
|
+
describeWrites());
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Zet de standaard geheugenlimiet in de opstartregel, zodat je in het clientlog ziet
|
|
@@ -19,6 +21,19 @@ async function main() {
|
|
|
19
21
|
* kan er verder prima mee door, en analyse() legt het probleem alsnog uit aan wie
|
|
20
22
|
* een analyse aanvraagt.
|
|
21
23
|
*/
|
|
24
|
+
/**
|
|
25
|
+
* Zegt of schrijvende tools meedoen. Ook bij "uit" iets melden zou ruis zijn, maar
|
|
26
|
+
* een waarde die níet herkend wordt moet je wel zien: die staat er met een bedoeling
|
|
27
|
+
* en doet niets.
|
|
28
|
+
*/
|
|
29
|
+
function describeWrites() {
|
|
30
|
+
if (writesAllowed())
|
|
31
|
+
return ', schrijvende tools aan';
|
|
32
|
+
const configured = process.env[WRITES_ENV_VAR]?.trim();
|
|
33
|
+
return configured === undefined || configured === ''
|
|
34
|
+
? ''
|
|
35
|
+
: `, LET OP: ${WRITES_ENV_VAR} staat op "${configured}"; alleen "1" en "true" zetten schrijven aan`;
|
|
36
|
+
}
|
|
22
37
|
/** Zelfde afweging als bij de geheugenlimiet: melden, niet fataal. */
|
|
23
38
|
function describeMaxParallel() {
|
|
24
39
|
try {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEnC,8EAA8E;IAC9E,kEAAkE;IAClE,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAEjD,OAAO,CAAC,KAAK,CACX,eAAe,OAAO,uBAAuB,KAAK,CAAC,MAAM,yBAAyB;QAChF,qBAAqB,EAAE;QACvB,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAEnC,8EAA8E;IAC9E,kEAAkE;IAClE,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAEjD,OAAO,CAAC,KAAK,CACX,eAAe,OAAO,uBAAuB,KAAK,CAAC,MAAM,yBAAyB;QAChF,qBAAqB,EAAE;QACvB,mBAAmB,EAAE;QACrB,cAAc,EAAE,CACnB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH;;;;GAIG;AACH,SAAS,cAAc;IACrB,IAAI,aAAa,EAAE;QAAE,OAAO,yBAAyB,CAAC;IAEtD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC;IACvD,OAAO,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,EAAE;QAClD,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,aAAa,cAAc,cAAc,UAAU,8CAA8C,CAAC;AACxG,CAAC;AAED,sEAAsE;AACtE,SAAS,mBAAmB;IAC1B,IAAI,CAAC;QACH,OAAO,eAAe,MAAM,CAAC,eAAe,EAAE,CAAC,WAAW,CAAC;IAC7D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB;IAC5B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;QACvC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oBAAoB,KAAK,EAAE,CAAC;IAChE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,aAAa,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/E,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/phpstan.d.ts
CHANGED
|
@@ -45,6 +45,61 @@ export interface AnalyseOptions {
|
|
|
45
45
|
/** Fout die als bruikbare melding naar het model teruggaat, niet als crash. */
|
|
46
46
|
export declare class PhpstanError extends Error {
|
|
47
47
|
}
|
|
48
|
+
/** Uitkomst van `phpstan diagnose`: PHPStans eigen tekst, ongewijzigd. */
|
|
49
|
+
export interface Diagnosis {
|
|
50
|
+
readonly project: string;
|
|
51
|
+
/** De regels zoals PHPStan ze op stdout zet. */
|
|
52
|
+
readonly output: string;
|
|
53
|
+
}
|
|
54
|
+
/** Uitkomst van het legen van de resultcache. */
|
|
55
|
+
export interface CacheCleared {
|
|
56
|
+
readonly project: string;
|
|
57
|
+
/** PHPStans eigen tekst; die noemt de map die geleegd is. */
|
|
58
|
+
readonly output: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Leegt PHPStans resultcache voor dit project.
|
|
62
|
+
*
|
|
63
|
+
* Wél door de queue van dit project: een analyse die tegelijk draait gebruikt
|
|
64
|
+
* diezelfde cache. Let op dat de cache standaard *niet* in het project ligt maar in
|
|
65
|
+
* `sys_get_temp_dir()/phpstan`, en dus gedeeld wordt met elk ander project dat geen
|
|
66
|
+
* eigen `tmpDir` in zijn config zet. PHPStans uitvoer noemt de map, zodat aan het
|
|
67
|
+
* antwoord te zien is wat er precies geleegd is.
|
|
68
|
+
*/
|
|
69
|
+
export declare function clearResultCache(project: ResolvedProject, options?: Pick<AnalyseOptions, 'config' | 'timeoutMs' | 'signal'>): Promise<CacheCleared>;
|
|
70
|
+
/** Opties voor het genereren van een baseline. */
|
|
71
|
+
export interface GenerateBaselineOptions extends AnalyseOptions {
|
|
72
|
+
/** Absoluut pad waar de baseline geschreven wordt. */
|
|
73
|
+
readonly file: string;
|
|
74
|
+
/** Ook schrijven als er niets te negeren valt. */
|
|
75
|
+
readonly allowEmpty?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/** Uitkomst van het genereren van een baseline. */
|
|
78
|
+
export interface BaselineGenerated {
|
|
79
|
+
readonly project: string;
|
|
80
|
+
readonly file: string;
|
|
81
|
+
/** Hoeveel fouten er in de baseline gezet zijn. */
|
|
82
|
+
readonly errors: number;
|
|
83
|
+
readonly output: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Laat PHPStan een baseline schrijven: alle huidige fouten worden erin gezet, zodat
|
|
87
|
+
* een volgende analyse alleen meldt wat er nieuw bij komt.
|
|
88
|
+
*
|
|
89
|
+
* Dit schrijft een bestand in het project — de enige tool die dat doet, en daarom
|
|
90
|
+
* alleen bereikbaar als de server met schrijfrechten gestart is.
|
|
91
|
+
*/
|
|
92
|
+
export declare function generateBaseline(project: ResolvedProject, options: GenerateBaselineOptions): Promise<BaselineGenerated>;
|
|
93
|
+
/**
|
|
94
|
+
* Draait `phpstan diagnose` in één project: PHP- en PHPStan-versie, de configs die
|
|
95
|
+
* Composer-pakketten meebrengen, en of de turbo-extensie aanstaat. Geen analyse, dus
|
|
96
|
+
* geen bevindingen — dit is wat je wil weten als een project zich vreemd gedraagt.
|
|
97
|
+
*
|
|
98
|
+
* Wel door de semafoor en niet door de queue per project: dit is een PHPStan-proces
|
|
99
|
+
* dat de machine belast, maar het schrijft geen resultcache waar een analyse
|
|
100
|
+
* overheen zou kunnen lopen.
|
|
101
|
+
*/
|
|
102
|
+
export declare function diagnose(project: ResolvedProject, options?: Pick<AnalyseOptions, 'timeoutMs' | 'signal'>): Promise<Diagnosis>;
|
|
48
103
|
/**
|
|
49
104
|
* Draait PHPStan in één project en levert de bevindingen.
|
|
50
105
|
*
|
package/dist/phpstan.js
CHANGED
|
@@ -20,6 +20,100 @@ const MEMORY_LIMIT_PATTERN = /^(-1|\d+[KMG]?)$/i;
|
|
|
20
20
|
/** Fout die als bruikbare melding naar het model teruggaat, niet als crash. */
|
|
21
21
|
export class PhpstanError extends Error {
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Leegt PHPStans resultcache voor dit project.
|
|
25
|
+
*
|
|
26
|
+
* Wél door de queue van dit project: een analyse die tegelijk draait gebruikt
|
|
27
|
+
* diezelfde cache. Let op dat de cache standaard *niet* in het project ligt maar in
|
|
28
|
+
* `sys_get_temp_dir()/phpstan`, en dus gedeeld wordt met elk ander project dat geen
|
|
29
|
+
* eigen `tmpDir` in zijn config zet. PHPStans uitvoer noemt de map, zodat aan het
|
|
30
|
+
* antwoord te zien is wat er precies geleegd is.
|
|
31
|
+
*/
|
|
32
|
+
export async function clearResultCache(project, options = {}) {
|
|
33
|
+
const binary = requireBinary(project);
|
|
34
|
+
throwIfAborted(project.path, options.signal);
|
|
35
|
+
return enqueue(project.path, () => withSlot(async () => {
|
|
36
|
+
throwIfAborted(project.path, options.signal);
|
|
37
|
+
const args = ['clear-result-cache', '--no-ansi'];
|
|
38
|
+
if (options.config !== undefined)
|
|
39
|
+
args.push(`--configuration=${options.config}`);
|
|
40
|
+
const execution = await execute(binary, args, project.path, options.timeoutMs ?? DEFAULT_TIMEOUT_MS, options.signal);
|
|
41
|
+
const output = execution.stdout.trim();
|
|
42
|
+
if (execution.code !== 0 || output === '') {
|
|
43
|
+
throw new PhpstanError(`PHPStan kon de resultcache van ${project.path} niet legen (exit code ${execution.code ?? '?'}).\n\n` +
|
|
44
|
+
(execution.stderr.trim() || output || 'Geen output op stdout of stderr.'));
|
|
45
|
+
}
|
|
46
|
+
return { project: project.path, output };
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Laat PHPStan een baseline schrijven: alle huidige fouten worden erin gezet, zodat
|
|
51
|
+
* een volgende analyse alleen meldt wat er nieuw bij komt.
|
|
52
|
+
*
|
|
53
|
+
* Dit schrijft een bestand in het project — de enige tool die dat doet, en daarom
|
|
54
|
+
* alleen bereikbaar als de server met schrijfrechten gestart is.
|
|
55
|
+
*/
|
|
56
|
+
export async function generateBaseline(project, options) {
|
|
57
|
+
const binary = requireBinary(project);
|
|
58
|
+
throwIfAborted(project.path, options.signal);
|
|
59
|
+
const installed = { ...project, binary };
|
|
60
|
+
return enqueue(project.path, () => withSlot(async () => {
|
|
61
|
+
throwIfAborted(project.path, options.signal);
|
|
62
|
+
const execution = await execute(binary, buildBaselineArgs(installed, options), project.path, options.timeoutMs ?? DEFAULT_TIMEOUT_MS, options.signal);
|
|
63
|
+
// Op de tekst afgaan en niet op de exit code, om dezelfde reden als bij een
|
|
64
|
+
// analyse: PHPStan meldt "niets te schrijven" met exit 1 én met een bruikbare
|
|
65
|
+
// uitleg erbij, en die uitleg is meer waard dan een eigen foutmelding.
|
|
66
|
+
const output = (execution.stdout.trim() || execution.stderr.trim()).slice(0, 2000);
|
|
67
|
+
const match = /Baseline generated with (\d+) error/i.exec(output);
|
|
68
|
+
if (match === null) {
|
|
69
|
+
throw new PhpstanError(`PHPStan heeft geen baseline geschreven in ${project.path}.\n\n` +
|
|
70
|
+
(output === '' ? 'Geen output op stdout of stderr.' : output));
|
|
71
|
+
}
|
|
72
|
+
return { project: project.path, file: options.file, errors: Number(match[1]), output };
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
/** Weigert een project zonder PHPStan met de melding die zegt wat er wél kan. */
|
|
76
|
+
function requireBinary(project) {
|
|
77
|
+
if (project.binary === null) {
|
|
78
|
+
throw new PhpstanError(`PHPStan is niet geïnstalleerd in ${project.path} (vendor/bin/phpstan ontbreekt). ` +
|
|
79
|
+
'Draai daar eerst `composer install`.');
|
|
80
|
+
}
|
|
81
|
+
return project.binary;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Draait `phpstan diagnose` in één project: PHP- en PHPStan-versie, de configs die
|
|
85
|
+
* Composer-pakketten meebrengen, en of de turbo-extensie aanstaat. Geen analyse, dus
|
|
86
|
+
* geen bevindingen — dit is wat je wil weten als een project zich vreemd gedraagt.
|
|
87
|
+
*
|
|
88
|
+
* Wel door de semafoor en niet door de queue per project: dit is een PHPStan-proces
|
|
89
|
+
* dat de machine belast, maar het schrijft geen resultcache waar een analyse
|
|
90
|
+
* overheen zou kunnen lopen.
|
|
91
|
+
*/
|
|
92
|
+
export async function diagnose(project, options = {}) {
|
|
93
|
+
const binary = requireBinary(project);
|
|
94
|
+
throwIfAborted(project.path, options.signal);
|
|
95
|
+
return withSlot(async () => {
|
|
96
|
+
throwIfAborted(project.path, options.signal);
|
|
97
|
+
const execution = await execute(binary, ['diagnose', '--no-ansi'], project.path, options.timeoutMs ?? DEFAULT_TIMEOUT_MS, options.signal);
|
|
98
|
+
if (execution.spawnError !== null) {
|
|
99
|
+
throw new PhpstanError(`PHPStan kon niet gestart worden in ${project.path}: ${execution.spawnError.message}`);
|
|
100
|
+
}
|
|
101
|
+
if (execution.signal !== null) {
|
|
102
|
+
throw new PhpstanError(execution.reason === 'geannuleerd'
|
|
103
|
+
? `De diagnose van ${project.path} is afgebroken omdat het verzoek geannuleerd is.`
|
|
104
|
+
: `De diagnose van ${project.path} is afgebroken (signaal ${execution.signal}).`);
|
|
105
|
+
}
|
|
106
|
+
// diagnose zet zijn rapport op stdout en alleen de configuratieregel op stderr.
|
|
107
|
+
// Een lege stdout betekent dus dat er iets anders mis is; dan is PHPStans eigen
|
|
108
|
+
// uitleg bruikbaarder dan een zelfbedachte melding.
|
|
109
|
+
const output = execution.stdout.trim();
|
|
110
|
+
if (output === '') {
|
|
111
|
+
throw new PhpstanError(`PHPStan gaf geen diagnose terug in ${project.path} (exit code ${execution.code ?? '?'}).\n\n` +
|
|
112
|
+
(execution.stderr.trim() || 'Geen output op stdout of stderr.'));
|
|
113
|
+
}
|
|
114
|
+
return { project: project.path, output };
|
|
115
|
+
});
|
|
116
|
+
}
|
|
23
117
|
/**
|
|
24
118
|
* Draait PHPStan in één project en levert de bevindingen.
|
|
25
119
|
*
|
|
@@ -28,13 +122,8 @@ export class PhpstanError extends Error {
|
|
|
28
122
|
* overheen. Verschillende projecten draaien wél parallel.
|
|
29
123
|
*/
|
|
30
124
|
export async function analyse(project, options = {}) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
'Draai daar eerst `composer install`.');
|
|
34
|
-
}
|
|
35
|
-
// Na de null-check is binary een string; dit maakt dat expliciet zodat run()
|
|
36
|
-
// er geen cast voor nodig heeft.
|
|
37
|
-
const installed = { ...project, binary: project.binary };
|
|
125
|
+
// requireBinary levert de string op, zodat run() er geen cast voor nodig heeft.
|
|
126
|
+
const installed = { ...project, binary: requireBinary(project) };
|
|
38
127
|
// Vóór de queue: een verzoek dat al afgebroken is hoeft niet eens in de rij.
|
|
39
128
|
throwIfAborted(installed.path, options.signal);
|
|
40
129
|
return enqueue(installed.path, () => withSlot(() => run(installed, options)));
|
|
@@ -81,7 +170,33 @@ export function loadDefaultMemoryLimit(env = process.env) {
|
|
|
81
170
|
return configured;
|
|
82
171
|
}
|
|
83
172
|
function buildArgs(project, options) {
|
|
84
|
-
|
|
173
|
+
return [
|
|
174
|
+
'analyse',
|
|
175
|
+
'--error-format=json',
|
|
176
|
+
...QUIET_FLAGS,
|
|
177
|
+
...flags(options),
|
|
178
|
+
...targets(project, options),
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Dezelfde aanroep, maar met `--generate-baseline` in plaats van een errorformat:
|
|
183
|
+
* PHPStan schrijft dan een bestand en rapporteert in tekst hoeveel het er waren.
|
|
184
|
+
*/
|
|
185
|
+
function buildBaselineArgs(project, options) {
|
|
186
|
+
return [
|
|
187
|
+
'analyse',
|
|
188
|
+
...QUIET_FLAGS,
|
|
189
|
+
`--generate-baseline=${options.file}`,
|
|
190
|
+
...(options.allowEmpty === true ? ['--allow-empty-baseline'] : []),
|
|
191
|
+
...flags(options),
|
|
192
|
+
...targets(project, options),
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
/** Vlaggen die er altijd bij horen, zodat de uitvoer machineleesbaar blijft. */
|
|
196
|
+
const QUIET_FLAGS = ['--no-progress', '--no-interaction', '--no-ansi'];
|
|
197
|
+
/** De vlaggen die uit de opties komen, in de volgorde die PHPStan zelf aanhoudt. */
|
|
198
|
+
function flags(options) {
|
|
199
|
+
const args = [];
|
|
85
200
|
// Vóór de rest, zoals PHPStan het zelf ook documenteert: de config bepaalt wat de
|
|
86
201
|
// overige vlaggen overrulen.
|
|
87
202
|
if (options.config !== undefined)
|
|
@@ -92,14 +207,17 @@ function buildArgs(project, options) {
|
|
|
92
207
|
const memoryLimit = options.memoryLimit ?? loadDefaultMemoryLimit();
|
|
93
208
|
if (memoryLimit !== undefined)
|
|
94
209
|
args.push(`--memory-limit=${memoryLimit}`);
|
|
210
|
+
return args;
|
|
211
|
+
}
|
|
212
|
+
/** De paden die geanalyseerd worden, met de controle die PHPStan zelf niet uitlegt. */
|
|
213
|
+
function targets(project, options) {
|
|
95
214
|
// Zonder config én zonder paden weet PHPStan niet wat het moet doen; dan is een
|
|
96
215
|
// duidelijke melding beter dan PHPStans eigen usage-tekst.
|
|
97
216
|
const paths = options.paths ?? [];
|
|
98
217
|
if (paths.length === 0 && project.config === null) {
|
|
99
218
|
throw new PhpstanError(`${project.path} heeft geen phpstan.neon(.dist). Geef expliciet paths mee, of maak een config aan.`);
|
|
100
219
|
}
|
|
101
|
-
|
|
102
|
-
return args;
|
|
220
|
+
return paths;
|
|
103
221
|
}
|
|
104
222
|
/** Hoe lang een gedode procesgroep de tijd krijgt voordat SIGKILL volgt. */
|
|
105
223
|
const KILL_GRACE_MS = 5_000;
|
|
@@ -115,7 +233,19 @@ const KILL_GRACE_MS = 5_000;
|
|
|
115
233
|
function execute(binary, args, cwd, timeoutMs, signal) {
|
|
116
234
|
return new Promise((resolve) => {
|
|
117
235
|
// Geen `timeout`-optie van spawn: die doodt alleen het proces zelf.
|
|
118
|
-
const child = spawn(binary, args, {
|
|
236
|
+
const child = spawn(binary, args, {
|
|
237
|
+
cwd,
|
|
238
|
+
shell: false,
|
|
239
|
+
detached: true,
|
|
240
|
+
// PAO_DISABLE hoort bij --no-progress en --no-ansi: allemaal om PHPStans
|
|
241
|
+
// eigen, machineleesbare uitvoer te krijgen. laravel/pao hangt zich via
|
|
242
|
+
// autoload.files in de autoloader van het project, ziet aan variabelen als
|
|
243
|
+
// CLAUDECODE dat er een agent draait, en vervangt de uitvoer dan door zijn
|
|
244
|
+
// eigen formaat ({"tool":"phpstan","result":"passed"}). Dat parseert hier
|
|
245
|
+
// niet, dus zonder deze regel is zo'n project onanalyseerbaar — en de server
|
|
246
|
+
// erft die agent-variabelen juist altijd, want de client start hem.
|
|
247
|
+
env: { ...process.env, PAO_DISABLE: '1' },
|
|
248
|
+
});
|
|
119
249
|
const stdout = [];
|
|
120
250
|
const stderr = [];
|
|
121
251
|
let spawnError = null;
|