-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy path.sonarcloud.properties
More file actions
227 lines (224 loc) · 13.9 KB
/
Copy path.sonarcloud.properties
File metadata and controls
227 lines (224 loc) · 13.9 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# SonarCloud AutoScan analysis scope
#
# READ THIS BEFORE EDITING THE SUPPRESSIONS BELOW.
#
# Automatic Analysis reads only a fixed set of keys from this file:
# sonar.sources / sonar.exclusions / sonar.inclusions, sonar.tests and its
# in/exclusions, sonar.sourceEncoding, sonar.cpd.exclusions, and the
# language-version keys. `sonar.issue.ignore.multicriteria` is NOT among them —
# it belongs in the project's Administration > General Settings > Analysis
# Scope, and until 2026-09-18 the entries below had no effect at all: 121 of
# the 396 open code smells on `main` were covered by an entry here and reported
# anyway, including two file-scoped ones (php:S101 on migrations/**, php:S107 on
# BulkEntryAction.php) that rule out a pattern mistake. The path exclusions in
# this file did work, which is what made the gap easy to miss.
#
# So this file is the VERSIONED SOURCE and the project settings are the
# EFFECTIVE COPY. After changing the multicriteria block here, push it to the
# settings with the script below. It fails closed at every step, because the
# failure mode this whole file documents is a write that looks like it worked:
#
# set -euo pipefail
# python3 - <<'PY' > /tmp/fv.txt
# import json
# p={}
# for l in open('.sonarcloud.properties'):
# l=l.strip()
# if l.startswith('#') or '=' not in l: continue
# k,v=l.split('=',1); p[k.strip()]=v.strip()
# ids=[e.strip() for e in p['sonar.issue.ignore.multicriteria'].split(',')]
# for e in ids:
# print(json.dumps({"ruleKey":p[f'sonar.issue.ignore.multicriteria.{e}.ruleKey'],
# "resourceKey":p[f'sonar.issue.ignore.multicriteria.{e}.resourceKey']},
# separators=(',',':')))
# PY
# want=$(grep -c . /tmp/fv.txt); test "$want" -gt 0
# args=(); while IFS= read -r l; do args+=(--data-urlencode "fieldValues=$l"); done < /tmp/fv.txt
# test "${#args[@]}" -eq $((want * 2))
#
# # The token goes in on stdin, not in argv: curl scrubs --user from the
# # process list on most platforms, but only after it has started.
# # --fail-with-body turns a 4xx/5xx into a non-zero exit (plain curl does not).
# printf 'user = "%s:"\n' "$SONAR_TOKEN" | curl -sS --fail-with-body --config - \
# -X POST https://sonarcloud.io/api/settings/set \
# --data-urlencode component=netresearch_timetracker \
# --data-urlencode key=sonar.issue.ignore.multicriteria "${args[@]}"
#
# # The write answers 204 whatever it stored, so read it back and compare.
# printf 'user = "%s:"\n' "$SONAR_TOKEN" | curl -sS --fail-with-body --config - \
# "https://sonarcloud.io/api/settings/values?component=netresearch_timetracker&keys=sonar.issue.ignore.multicriteria" \
# | WANT="$want" python3 -c 'import json,os,sys; fv=json.load(sys.stdin)["settings"][0]["fieldValues"]; \
# want=int(os.environ["WANT"]); print(len(fv), "live,", want, "wanted"); \
# sys.exit(0 if len(fv)==want else 1)'
#
# The entries are kept here rather than deleted because a CI-based scanner would
# honour them, and because the reasoning below is the reviewable record.
# Generated/fixture SQL and generated docs are not ours to fix; excluding
# them removes duplicate-literal noise from schema/fixture dumps and
# findings in generated output.
sonar.exclusions=public/docs/swagger/**,sql/**,fixtures/**
# Doctrine migrations are inherently repetitive DDL — up()/down() mirror each
# other and multi-index changes repeat the same CREATE/DROP shape per index. That
# structural repetition is not real duplication to refactor away, so exclude
# migrations from the copy-paste-detector (they already skip S101 renaming rules).
sonar.cpd.exclusions=migrations/**
# Verified false positives — cannot be "fixed" without breaking behaviour:
# - php:S2003 on Kernel.php, public/index.php and tests/parallel-bootstrap.php:
# all three `require`/`include` a file for its RETURN VALUE (the bundle array,
# .env.local.php's array). require_once/include_once return true on a repeat,
# and registerBundles() re-runs on every kernel reboot in functional tests.
# - php:S1848 in TokenEncryptionServiceTest: instantiating to assert the
# constructor throws is the behaviour under test, not a dropped object;
# S1848 fires on the bare `new` regardless of context.
# - php:S836 in ExportServiceTest: dataflow false positive inside the Jira
# API mock builder (the stdClass is initialised before use).
# - typescript:S4325: these non-null/`as` assertions are required by strict
# noUncheckedIndexedAccess and nullable DOM-query/return types; removing them
# breaks the type-check, so they are not actually redundant.
# - typescript:S6551: the coerced values are structurally scalar (form fields,
# scalar admin columns); object default-stringification cannot occur.
# - typescript:S1128 (unused import) in frontend/**: `gridNav` is used as a
# Solid directive, `use:gridNav={{…}}`, which the compiler turns into a call.
# MEASURED 2026-09-18: removing the import in Auswertung.tsx passes both tsc
# and the Vite build, and fails three tests with "ReferenceError: gridNav is
# not defined". ESLint covers genuinely unused imports in this tree.
# - php:S1488 (return the expression directly) in the repositories: each temp
# variable carries a `/** @var list<T> */` that narrows Doctrine's
# getResult(): mixed for PHPStan level 10, and PHP has no such annotation on
# a return statement. MEASURED: inlining
# UserRepository::findPersonioExportEnabled() yields "should return
# list<App\Entity\User> but returns mixed".
# - php:S1172 (unused parameter) in tests/**: the signatures are dictated by
# the interface or callback being doubled, so the parameter has to exist.
#
# Style choices — where SonarCloud enforces one of two equally-valid styles, we
# declare the project's choice here rather than churn the code:
# - typescript:S7764 (prefer globalThis over window): browser-only SPA; `window`
# is correct, and lib/settings.ts uses window.localStorage deliberately to
# avoid Node 22's global-localStorage shadowing under the test runner.
# - typescript:S6759 (mark props read-only): Solid props are reactive accessors;
# the Readonly<> wrapper is a React convention not used here.
# - typescript:S7718 (catch param must be `error_`): we name caught errors
# `caught`/`error`.
# - typescript:S7735 (negated condition): a readability preference; the existing
# forms are clear in context.
# - typescript:S1301 (switch->if) in a test mock: the switch is clearer.
# - typescript:S3358 / php:S3358 (nested ternary): permitted as a concise style.
# - php:S1155 (use empty()): we avoid empty()'s loose semantics in favour of
# explicit count()/[] comparisons.
# - php:S1135 (TODO comments): intentional tracked markers (INFO).
# - php:S1192 (duplicated literal) in tests/**: a test states its own data.
# Hoisting the repeated query fragments and fixture strings into constants
# moves them away from the assertion that explains them. The five in src/
# stay flagged.
# - php:S1142 (more than three returns): early returns are this project's
# style, and rewriting 51 methods to satisfy a threshold of three makes them
# harder to read, not easier. Where a method is genuinely doing too much,
# php:S3776 (cognitive complexity) still fires on it and stays active - six
# of the 51 overlap with it and are being refactored on that basis.
# - php:S112 (generic exception) in tests/**: a throwaway exception in a
# fixture or a test double needs no dedicated class. The six in src/ stay
# flagged.
# - shelldre:S7679 on docker/php/docker-entrypoint.sh: that script is
# `#!/bin/sh` and `local` is not POSIX. The bash sibling in
# scripts/schema-drift-check.sh was fixed instead.
#
# Would break something if "fixed":
# - php:S101 on migrations: Doctrine migration class names are tracked in the
# doctrine_migration_versions table by FQCN; renaming risks re-running them.
# - php:S1448 / php:S107 (class/method/param counts): cohesive services,
# repositories, the interface stub and the bulk-entry action signature.
# - php:S1313 (hardcoded IP): localhost (127.0.0.1) in dev/test LDAP config.
# - php:S107 (too many parameters): seven of the twelve are MCP tool
# signatures - the parameter list IS the tool's argument schema, so a
# parameter object would change the tool's public interface. The rest are
# cohesive service methods and the bulk-entry action.
# - php:S116 (field naming) in src/Dto/**: `$ticket_system_id`, `$jira_id` and
# `$customer_id` are REQUEST PAYLOAD KEYS, not internal names - verified in
# frontend/src/api/worklogSync.ts, which sends exactly those. Renaming them
# breaks the API unless every one gains a #[SerializedName].
# - typescript:S7761 (prefer .dataset over getAttribute): the two are not
# interchangeable here. getAttribute returns null, dataset returns undefined.
# MEASURED: Number(null) is 0 and Number(undefined) is NaN, so the four
# `Number(cell.getAttribute('data-row-id'))` sites would turn a missing row
# id into NaN; and `undefined === null` is false, so any === null check
# behind one stops matching. dataset also needs an HTMLElement where two of
# the sites hold an Element from querySelector. frontend/AGENTS.md names
# these data attributes as load-bearing focus guards.
# - docker:S7031: the two RUN layers are deliberately separate concerns (base
# system deps vs a scoped tool install); merging is a build-cache micro-opt
# better validated with a full image build than changed blind.
# - typescript:S6819 / Web:S6819 (use a native element instead of an ARIA
# role): the role="status"/role="group" uses are valid ARIA. Swapping a
# <div role="status"> for <output> changes the element's default display and
# would need every affected layout re-checked, so this is deferred rather
# than changed during an unrelated pass. Tracked, not waived forever.
#
# Removed 2026-09-18: php:S5122 on src/Model/Response.php. The wildcard CORS
# headers it excused are gone (the class no longer overrides send()), so the
# entry excused nothing and its rationale — "the API is intended to be freely
# consumed cross-origin" — contradicted the code. If a wildcard is ever added
# back there, the rule should fire.
sonar.issue.ignore.multicriteria=e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31
sonar.issue.ignore.multicriteria.e1.ruleKey=php:S2003
sonar.issue.ignore.multicriteria.e1.resourceKey=src/Kernel.php
sonar.issue.ignore.multicriteria.e2.ruleKey=php:S2003
sonar.issue.ignore.multicriteria.e2.resourceKey=public/index.php
sonar.issue.ignore.multicriteria.e3.ruleKey=php:S2003
sonar.issue.ignore.multicriteria.e3.resourceKey=tests/parallel-bootstrap.php
sonar.issue.ignore.multicriteria.e4.ruleKey=php:S1848
sonar.issue.ignore.multicriteria.e4.resourceKey=tests/Service/Security/TokenEncryptionServiceTest.php
sonar.issue.ignore.multicriteria.e5.ruleKey=php:S836
sonar.issue.ignore.multicriteria.e5.resourceKey=tests/Service/ExportServiceTest.php
sonar.issue.ignore.multicriteria.e6.ruleKey=typescript:S4325
sonar.issue.ignore.multicriteria.e6.resourceKey=**/*
sonar.issue.ignore.multicriteria.e7.ruleKey=typescript:S6551
sonar.issue.ignore.multicriteria.e7.resourceKey=**/*
sonar.issue.ignore.multicriteria.e8.ruleKey=typescript:S7764
sonar.issue.ignore.multicriteria.e8.resourceKey=**/*
sonar.issue.ignore.multicriteria.e9.ruleKey=typescript:S6759
sonar.issue.ignore.multicriteria.e9.resourceKey=**/*
sonar.issue.ignore.multicriteria.e10.ruleKey=typescript:S7718
sonar.issue.ignore.multicriteria.e10.resourceKey=**/*
sonar.issue.ignore.multicriteria.e11.ruleKey=typescript:S7735
sonar.issue.ignore.multicriteria.e11.resourceKey=**/*
sonar.issue.ignore.multicriteria.e12.ruleKey=typescript:S1301
sonar.issue.ignore.multicriteria.e12.resourceKey=frontend/src/pages/Admin.test.tsx
sonar.issue.ignore.multicriteria.e13.ruleKey=*:S3358
sonar.issue.ignore.multicriteria.e13.resourceKey=**/*
sonar.issue.ignore.multicriteria.e14.ruleKey=php:S1155
sonar.issue.ignore.multicriteria.e14.resourceKey=**/*
sonar.issue.ignore.multicriteria.e15.ruleKey=php:S1135
sonar.issue.ignore.multicriteria.e15.resourceKey=**/*
sonar.issue.ignore.multicriteria.e16.ruleKey=php:S101
sonar.issue.ignore.multicriteria.e16.resourceKey=migrations/**
sonar.issue.ignore.multicriteria.e17.ruleKey=php:S1448
sonar.issue.ignore.multicriteria.e17.resourceKey=**/*
sonar.issue.ignore.multicriteria.e18.ruleKey=php:S1313
sonar.issue.ignore.multicriteria.e18.resourceKey=**/*Ldap*
sonar.issue.ignore.multicriteria.e19.ruleKey=docker:S7031
sonar.issue.ignore.multicriteria.e19.resourceKey=Dockerfile
sonar.issue.ignore.multicriteria.e20.ruleKey=typescript:S6819
sonar.issue.ignore.multicriteria.e20.resourceKey=**/*
sonar.issue.ignore.multicriteria.e21.ruleKey=Web:S6819
sonar.issue.ignore.multicriteria.e21.resourceKey=**/*
sonar.issue.ignore.multicriteria.e22.ruleKey=php:S1192
sonar.issue.ignore.multicriteria.e22.resourceKey=tests/**
sonar.issue.ignore.multicriteria.e23.ruleKey=php:S1142
sonar.issue.ignore.multicriteria.e23.resourceKey=**/*
sonar.issue.ignore.multicriteria.e24.ruleKey=typescript:S7761
sonar.issue.ignore.multicriteria.e24.resourceKey=**/*
sonar.issue.ignore.multicriteria.e25.ruleKey=php:S107
sonar.issue.ignore.multicriteria.e25.resourceKey=**/*
sonar.issue.ignore.multicriteria.e26.ruleKey=php:S1172
sonar.issue.ignore.multicriteria.e26.resourceKey=tests/**
sonar.issue.ignore.multicriteria.e27.ruleKey=php:S112
sonar.issue.ignore.multicriteria.e27.resourceKey=tests/**
sonar.issue.ignore.multicriteria.e28.ruleKey=php:S1488
sonar.issue.ignore.multicriteria.e28.resourceKey=**/*
sonar.issue.ignore.multicriteria.e29.ruleKey=php:S116
sonar.issue.ignore.multicriteria.e29.resourceKey=src/Dto/**
sonar.issue.ignore.multicriteria.e30.ruleKey=typescript:S1128
sonar.issue.ignore.multicriteria.e30.resourceKey=frontend/**
sonar.issue.ignore.multicriteria.e31.ruleKey=shelldre:S7679
sonar.issue.ignore.multicriteria.e31.resourceKey=docker/php/docker-entrypoint.sh