Repository navigation
Expand file tree
/
Copy pathphpstan.neon
More file actions
124 lines (114 loc) · 5.92 KB
/
Copy pathphpstan.neon
File metadata and controls
124 lines (114 loc) · 5.92 KB
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# PHPStan configuration for fogproject.
#
# The gate is on NEW errors only. Everything the tree reports today is captured
# in phpstan-baseline.neon, so this fails a pull request when it ADDS a problem
# and stays quiet about the ones already there. Regenerate the baseline with:
#
# composer install # root, not packages/web -- see composer.json
# vendor/bin/phpstan analyse --memory-limit=2G --generate-baseline
#
# PHPStan is a ROOT dev dependency on purpose. packages/web/vendor is committed
# and installed --no-dev, so putting a static analyser in it would ship one to
# every FOG server. The repo root is never deployed -- copybacktrunk.sh rsyncs
# packages/web/ and the installer does not read the root -- so this arrangement
# makes that impossible by construction rather than by remembering a flag.
#
# The version is pinned EXACTLY (2.2.9, not ^2.2) with composer.lock committed.
# PHPStan adds rules in minor releases, so a floating constraint would turn an
# unrelated pull request red with findings nobody introduced.
parameters:
level: 5
# Without this, FIXING a baselined error fails the build: PHPStan reports
# `ignore.unmatched` for the baseline entry that no longer matches, which is
# the exact opposite of "the number can only go down". Verified 2026-08-27 by
# deleting the duplicate array key in src/Items/Image.php -- exit 1 with the
# default, exit 0 with this.
#
# The cost is that an entry for an already-fixed error lingers silently, so
# the baseline drifts above reality until it is regenerated. That is the
# right trade: a stale-but-passing baseline beats a build that punishes fixes.
reportUnmatchedIgnoredErrors: false
# A RANGE, not a single target, because FOG has to run on all of it: the
# floor is 7.4 (packages/web/composer.json pins platform.php, commons/init.php
# documents it) and servers run 8.1-8.3. PHPStan reports anything that is a
# problem on ANY version in the range.
#
# Neither endpoint alone is right, and the difference is not cosmetic:
# - only an 8.x target sees the ftp_*() resource-to-object change (PHP 8.1),
# which is eight real findings in src/Net/FOGFTP.php on every running server
# - only a 7.4 target reports ini_set() with a non-string and spl_object_id()
# on a curl resource, both of which PHP 8 made correct
phpVersion:
min: 70400
max: 80300
paths:
- packages/web/src
- packages/web/lib
- packages/web/commons
- packages/web/api
- packages/web/management
- packages/web/client
- packages/web/maintenance
- packages/web/status
- packages/web/index.php
- packages/service
- bin
# Made KNOWN here, not analysed here. bin/upgrade-rehearsal.php requires
# this class at runtime, but it lives under tests/ so that
# tests/all-classes-load.test.php's rule -- every class in a tracked .php
# outside vendor/ and tests/ must autoload -- stays absolute; a class in a
# CLI script that exits during argument parsing can never satisfy it.
# scanFiles rather than paths because phpstan-tests.neon is what analyses
# the file, and analysing it twice under two configs is how the two drift.
scanFiles:
- tests/lib/rehearsal-runner.php
# tests/ is analysed by phpstan-tests.neon, not here. It needs two
# ignoreErrors rules this config must not carry -- see that file's header
# for why eval()'d fixtures and per-file global helpers make a shared
# config the wrong shape.
ignoreErrors:
# bin/upgrade-rehearsal.php boots a DIFFERENT FOG tree -- a lab copy
# whose path is an argument -- and replays commons/schema.php inside
# it. Three findings follow from that and all three are artifacts of
# analysing a bootstrapper for an application that is not here:
#
# include.fileNotFound the schema file it includes lives under
# the tree being rehearsed, not this repo.
# notIdentical.alwaysTrue build/phpstan/constants.stub.php declares
# deadCode.unreachable DATABASE_NAME as a literal '', so the
# guard that checks the lab tree actually
# honored REHEARSAL_DB reads as always
# true, and everything after it as dead.
#
# Ignored by identifier and scoped to the one file, following
# phpstan-tests.neon's precedent: these are permanent properties of
# what the file does, not a backlog. The guard they misread is real
# and load-bearing -- a rehearsal pointed at the wrong database is the
# one outcome that must fail loudly.
-
identifier: include.fileNotFound
path: bin/upgrade-rehearsal.php
-
identifier: notIdentical.alwaysTrue
path: bin/upgrade-rehearsal.php
-
identifier: deadCode.unreachable
path: bin/upgrade-rehearsal.php
excludePaths:
analyseAndScan:
# The shipped application's dependencies. Analysing them reports
# other people's code and would swamp the baseline.
- packages/web/vendor
# Gitignored staging directory that bin/fetch-plugins.sh fills from
# the fog-plugins release (ADR 0009). A fresh clone does not have it,
# so it MUST be marked optional with (?) or PHPStan refuses to start
# rather than skipping a missing exclude.
- packages/web/lib/plugins (?)
bootstrapFiles:
# Gives PHPStan the vendored classes (firebase/php-jwt, ifsnop/mysqldump)
# without it having to analyse them.
- packages/web/vendor/autoload.php
# The constants FOG defines at runtime -- see the file's own header.
- build/phpstan/constants.stub.php
includes:
- phpstan-baseline.neon