From 72571a19dd664c5cc79171369700d412d46c0e52 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Tue, 12 Nov 2024 11:39:56 +0100 Subject: [PATCH] build(psalm): Configure unstable namespace Signed-off-by: provokateurin --- .github/workflows/static-code-analysis.yml | 26 +++++ build/files-checker.php | 1 + build/psalm/NcuExperimentalChecker.php | 122 +++++++++++++++++++++ composer.json | 1 + psalm-ncu.xml | 21 ++++ psalm-ocp.xml | 1 - 6 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 build/psalm/NcuExperimentalChecker.php create mode 100644 psalm-ncu.xml diff --git a/.github/workflows/static-code-analysis.yml b/.github/workflows/static-code-analysis.yml index f2efe3ea70e6e..c259a2b086898 100644 --- a/.github/workflows/static-code-analysis.yml +++ b/.github/workflows/static-code-analysis.yml @@ -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 diff --git a/build/files-checker.php b/build/files-checker.php index 3d3ec923eae59..3231334efc331 100644 --- a/build/files-checker.php +++ b/build/files-checker.php @@ -69,6 +69,7 @@ 'ocs-provider', 'package-lock.json', 'package.json', + 'psalm-ncu.xml', 'psalm-ocp.xml', 'psalm.xml', 'public.php', diff --git a/build/psalm/NcuExperimentalChecker.php b/build/psalm/NcuExperimentalChecker.php new file mode 100644 index 0000000000000..d5c24333d9ed4 --- /dev/null +++ b/build/psalm/NcuExperimentalChecker.php @@ -0,0 +1,122 @@ +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) + ) + ); + } + } +} diff --git a/composer.json b/composer.json index f11ced48b6780..ff381015d7b06 100644 --- a/composer.json +++ b/composer.json @@ -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": [ diff --git a/psalm-ncu.xml b/psalm-ncu.xml new file mode 100644 index 0000000000000..f7577435b8893 --- /dev/null +++ b/psalm-ncu.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/psalm-ocp.xml b/psalm-ocp.xml index de4741aa2ddce..e49f7fd929b50 100644 --- a/psalm-ocp.xml +++ b/psalm-ocp.xml @@ -19,7 +19,6 @@ -