build(psalm): Configure unstable namespace

Signed-off-by: provokateurin <kate@provokateurin.de>
pull/49224/head
provokateurin 5 months ago
parent 17659d327a
commit 72571a19dd
No known key found for this signature in database
  1. 26
      .github/workflows/static-code-analysis.yml
  2. 1
      build/files-checker.php
  3. 122
      build/psalm/NcuExperimentalChecker.php
  4. 1
      composer.json
  5. 21
      psalm-ncu.xml
  6. 1
      psalm-ocp.xml

@ -111,3 +111,29 @@ jobs:
- name: Show potential changes in Psalm baseline
if: always()
run: git diff --exit-code -- . ':!lib/composer'
static-code-analysis-ncu:
runs-on: ubuntu-latest
if: ${{ github.event_name != 'push' && github.repository_owner != 'nextcloud-gmbh' }}
steps:
- name: Checkout
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
with:
submodules: true
- name: Set up php
uses: shivammathur/setup-php@c541c155eee45413f5b09a52248675b1a2575231 #v2.31.1
with:
php-version: '8.1'
extensions: ctype,curl,dom,fileinfo,gd,imagick,intl,json,mbstring,openssl,pdo_sqlite,posix,sqlite,xml,zip
coverage: none
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Composer install
run: composer i
- name: Psalm
run: composer run psalm:ncu -- --threads=1 --monochrome --no-progress --output-format=github

@ -69,6 +69,7 @@ $expectedFiles = [
'ocs-provider',
'package-lock.json',
'package.json',
'psalm-ncu.xml',
'psalm-ocp.xml',
'psalm.xml',
'public.php',

@ -0,0 +1,122 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\ClassLike;
use Psalm\CodeLocation;
use Psalm\DocComment;
use Psalm\Exception\DocblockParseException;
use Psalm\FileSource;
use Psalm\Issue\InvalidDocblock;
use Psalm\IssueBuffer;
use Psalm\Plugin\EventHandler\Event\AfterClassLikeVisitEvent;
class NcuExperimentalChecker implements Psalm\Plugin\EventHandler\AfterClassLikeVisitInterface {
public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event): void {
$stmt = $event->getStmt();
$statementsSource = $event->getStatementsSource();
self::checkClassComment($stmt, $statementsSource);
foreach ($stmt->getMethods() as $method) {
self::checkMethodOrConstantComment($method, $statementsSource, 'method');
}
foreach ($stmt->getConstants() as $constant) {
self::checkMethodOrConstantComment($constant, $statementsSource, 'constant');
}
}
private static function checkClassComment(ClassLike $stmt, FileSource $statementsSource): void {
$docblock = $stmt->getDocComment();
if ($docblock === null) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
'PHPDoc is required for classes/interfaces in NCU.',
new CodeLocation($statementsSource, $stmt)
)
);
return;
}
try {
$parsedDocblock = DocComment::parsePreservingLength($docblock);
} catch (DocblockParseException $e) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
$e->getMessage(),
new CodeLocation($statementsSource, $stmt)
)
);
return;
}
if (!isset($parsedDocblock->tags['experimental'])) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
'@experimental is required for classes/interfaces in NCU.',
new CodeLocation($statementsSource, $stmt)
)
);
}
if (isset($parsedDocblock->tags['depreacted'])) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
'Typo in @deprecated for classes/interfaces in NCU.',
new CodeLocation($statementsSource, $stmt)
)
);
}
}
private static function checkMethodOrConstantComment(Stmt $stmt, FileSource $statementsSource, string $type): void {
$docblock = $stmt->getDocComment();
if ($docblock === null) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
'PHPDoc is required for ' . $type . 's in NCU.',
new CodeLocation($statementsSource, $stmt)
),
);
return;
}
try {
$parsedDocblock = DocComment::parsePreservingLength($docblock);
} catch (DocblockParseException $e) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
$e->getMessage(),
new CodeLocation($statementsSource, $stmt)
)
);
return;
}
if (!isset($parsedDocblock->tags['experimental'])) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
'@experimental is required for ' . $type . 's in NCU.',
new CodeLocation($statementsSource, $stmt)
)
);
}
if (isset($parsedDocblock->tags['depreacted'])) {
IssueBuffer::maybeAdd(
new InvalidDocblock(
'Typo in @deprecated for ' . $type . ' in NCU.',
new CodeLocation($statementsSource, $stmt)
)
);
}
}
}

@ -61,6 +61,7 @@
"lint": "find . -name \\*.php -not -path './lib/composer/*' -not -path './build/stubs/*' -print0 | xargs -0 -n1 php -l",
"psalm": "psalm --no-cache --threads=$(nproc)",
"psalm:ocp": "psalm --no-cache --threads=$(nproc) -c psalm-ocp.xml",
"psalm:ncu": "psalm --no-cache --threads=$(nproc) -c psalm-ncu.xml",
"psalm:security": "psalm --no-cache --threads=$(nproc) --taint-analysis --use-baseline=build/psalm-baseline-security.xml",
"psalm:update-baseline": "psalm --no-cache --threads=$(nproc) --update-baseline",
"serve": [

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<psalm
errorLevel="1"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config"
findUnusedBaselineEntry="false"
findUnusedCode="false"
>
<plugins>
<plugin filename="build/psalm/NcuExperimentalChecker.php"/>
</plugins>
<projectFiles>
<directory name="lib/unstable"/>
</projectFiles>
</psalm>

@ -19,7 +19,6 @@
</plugins>
<projectFiles>
<directory name="lib/public"/>
<directory name="lib/unstable"/>
<ignoreFiles>
<directory name="lib/composer/bin"/>
</ignoreFiles>

Loading…
Cancel
Save