ci(client): lint:dup holds copied code to a baseline that only shrinks

Most features have a desktop view and a phone view, and each carried its
own copy of the feature's logic, so SonarCloud's duplication condition
was the gate a pull request touching both failed most often, and only
after a scan of twenty minutes. lint:dup finds the same copies before
the push.

It runs jscpd's detector (@jscpd/core with @jscpd/tokenizer) over the
source files under src/ at the thresholds the SonarCloud gate applies to
TypeScript, 100 tokens over at least 10 lines, and counts per file the
lines inside a block that repeats elsewhere or in the same file. Tests
and declaration files are left out as Sonar leaves them out, and .ts and
.tsx are read as one language, so a hook that repeats a view's code is a
copy too. The files are read sorted and with readText, so every machine
counts the same. scripts/dup-baseline.json holds the files that still
hold copies with their count; a file may hold no more than its entry, a
file without an entry none, and an entry above its file or for a file
that is gone fails until --update lowers it. --list prints every block
with its other side.

The engine packages are used instead of the jscpd command, which walks
the tree in file system order, skips files past its size limits without
a word and drops every result once it meets a file it has no format for.
This commit is contained in:
Maurice
2026-10-08 20:54:53 +00:00
parent 2ccdba78d6
commit 88d196bae8
10 changed files with 404 additions and 4 deletions
+7
View File
@@ -349,6 +349,13 @@ jobs:
# mutation queue.
run: cd client && npm run lint:offline
- name: Duplication check
# A file may hold no more lines inside a block of code that repeats
# elsewhere than scripts/dup-baseline.json allows, counted at the
# thresholds of the SonarCloud gate, so the logic a desktop view and
# its phone twin share stays in one hook (scripts/dup-lint.mjs).
run: cd client && npm run lint:dup
- name: Skipped and focused tests check
run: cd client && npm run lint:skips