diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 000000000..c67259c91 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,26 @@ +name: Static analysis + +on: [push, pull_request] + +jobs: + static-psalm-analysis: + runs-on: ubuntu-latest + strategy: + matrix: + ocp-version: [ 'dev-master', 'v20.0.1' ] + name: Nextcloud ${{ matrix.ocp-version }} + steps: + - name: Checkout + uses: actions/checkout@master + - name: Set up php + uses: shivammathur/setup-php@master + with: + php-version: 7.4 + tools: composer:v1 + coverage: none + - name: Install dependencies + run: composer i + - name: Install dependencies + run: composer require --dev christophwurst/nextcloud:${{ matrix.ocp-version }} + - name: Run coding standards check + run: composer run psalm diff --git a/composer.json b/composer.json index 50df95eec..57655fbbb 100644 --- a/composer.json +++ b/composer.json @@ -13,11 +13,12 @@ }, "require-dev": { "roave/security-advisories": "dev-master", - "christophwurst/nextcloud": "^17", - "jakub-onderka/php-parallel-lint": "^1.0.0", + "christophwurst/nextcloud": "^20", "phpunit/phpunit": "^8", "nextcloud/coding-standard": "^0.4.0", - "symfony/event-dispatcher": "^4.0" + "symfony/event-dispatcher": "^4.0", + "vimeo/psalm": "^4.3", + "php-parallel-lint/php-parallel-lint": "^1.2" }, "config": { "optimize-autoloader": true, @@ -26,6 +27,8 @@ "scripts": { "lint": "find . -name \\*.php -not -path './vendor/*' -print0 | xargs -0 -n1 php -l", "cs:check": "php-cs-fixer fix --dry-run --diff", - "cs:fix": "php-cs-fixer fix" + "cs:fix": "php-cs-fixer fix", + "psalm": "psalm", + "psalm:fix": "psalm --alter --issues=InvalidReturnType,InvalidNullableReturnType,MismatchingDocblockParamType,MismatchingDocblockReturnType,MissingParamType,InvalidFalsableReturnType" } } diff --git a/composer.lock b/composer.lock index 70a3be9b9..0f37ef988 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1b2adbde885ddcf16d72cf6ecadf2823", + "content-hash": "4a3d65807490679a4de897a8643385bb", "packages": [ { "name": "cogpowered/finediff", @@ -64,26 +64,186 @@ ], "packages-dev": [ { - "name": "christophwurst/nextcloud", - "version": "v17.0.6", + "name": "amphp/amp", + "version": "v2.5.1", "source": { "type": "git", - "url": "https://github.com/ChristophWurst/nextcloud_composer.git", - "reference": "5977d037f9d885713312016db3a9019ed6853955" + "url": "https://github.com/amphp/amp.git", + "reference": "ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/5977d037f9d885713312016db3a9019ed6853955", - "reference": "5977d037f9d885713312016db3a9019ed6853955", + "url": "https://api.github.com/repos/amphp/amp/zipball/ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c", + "reference": "ecdc3c476b3ccff02f8e5d5bcc04f7ccfd18751c", "shasum": "" }, "require": { - "php": "^7.1" + "php": ">=7" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6.0.9 | ^7", + "psalm/phar": "^3.11@dev", + "react/promise": "^2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "17.0.0-dev" + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\": "lib" + }, + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "http://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.5.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2020-11-03T16:23:45+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "f0c20cf598a958ba2aa8c6e5a71c697d652c7088" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/f0c20cf598a958ba2aa8c6e5a71c697d652c7088", + "reference": "f0c20cf598a958ba2aa8c6e5a71c697d652c7088", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.4", + "friendsofphp/php-cs-fixer": "^2.3", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6 || ^7 || ^8", + "psalm/phar": "^3.11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\ByteStream\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/master" + }, + "time": "2020-06-29T18:35:05+00:00" + }, + { + "name": "christophwurst/nextcloud", + "version": "v20.0.4", + "source": { + "type": "git", + "url": "https://github.com/ChristophWurst/nextcloud_composer.git", + "reference": "a207b55848d1ac4c83a954eac90c07714bbdaaed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/a207b55848d1ac4c83a954eac90c07714bbdaaed", + "reference": "a207b55848d1ac4c83a954eac90c07714bbdaaed", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "20.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -99,9 +259,82 @@ "description": "Composer package containing Nextcloud's public API (classes, interfaces)", "support": { "issues": "https://github.com/ChristophWurst/nextcloud_composer/issues", - "source": "https://github.com/ChristophWurst/nextcloud_composer/tree/v17.0.6" + "source": "https://github.com/ChristophWurst/nextcloud_composer/tree/v20.0.4" }, - "time": "2020-04-27T12:43:22+00:00" + "time": "2020-12-23T12:42:07+00:00" + }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.1", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", + "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2020-11-11T10:22:58+00:00" }, { "name": "composer/semver", @@ -247,6 +480,43 @@ ], "time": "2020-11-13T08:04:11+00:00" }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, { "name": "doctrine/annotations", "version": "1.11.1", @@ -471,6 +741,107 @@ ], "time": "2020-05-25T17:44:05+00:00" }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "0ed363f8de17d284d479ec813c9ad3f6834b5c40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/0ed363f8de17d284d479ec813c9ad3f6834b5c40", + "reference": "0ed363f8de17d284d479ec813c9ad3f6834b5c40", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0", + "php": ">=7.0", + "phpdocumentor/reflection-docblock": "^4.0.0 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/master" + }, + "time": "2020-03-11T15:21:41+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "85e83cacd2ed573238678c6875f8f0d7ec699541" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/85e83cacd2ed573238678c6875f8f0d7ec699541", + "reference": "85e83cacd2ed573238678c6875f8f0d7ec699541", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.0" + }, + "time": "2020-10-23T13:55:30+00:00" + }, { "name": "friendsofphp/php-cs-fixer", "version": "v2.17.3", @@ -575,59 +946,6 @@ ], "time": "2020-12-24T11:14:44+00:00" }, - { - "name": "jakub-onderka/php-parallel-lint", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Parallel-Lint.git", - "reference": "04fbd3f5fb1c83f08724aa58a23db90bd9086ee8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Parallel-Lint/zipball/04fbd3f5fb1c83f08724aa58a23db90bd9086ee8", - "reference": "04fbd3f5fb1c83f08724aa58a23db90bd9086ee8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "jakub-onderka/php-console-highlighter": "~0.3", - "nette/tester": "~1.3", - "squizlabs/php_codesniffer": "~2.7" - }, - "suggest": { - "jakub-onderka/php-console-highlighter": "Highlight syntax in code snippet" - }, - "bin": [ - "parallel-lint" - ], - "type": "library", - "autoload": { - "classmap": [ - "./" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "ahoj@jakubonderka.cz" - } - ], - "description": "This tool check syntax of PHP files about 20x faster than serial check.", - "homepage": "https://github.com/JakubOnderka/PHP-Parallel-Lint", - "support": { - "issues": "https://github.com/JakubOnderka/PHP-Parallel-Lint/issues", - "source": "https://github.com/JakubOnderka/PHP-Parallel-Lint/tree/master" - }, - "abandoned": "php-parallel-lint/php-parallel-lint", - "time": "2018-02-24T15:31:20+00:00" - }, { "name": "myclabs/deep-copy", "version": "1.10.2", @@ -686,6 +1004,57 @@ ], "time": "2020-11-13T09:40:50+00:00" }, + { + "name": "netresearch/jsonmapper", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/e0f1e33a71587aca81be5cffbb9746510e1fe04e", + "reference": "e0f1e33a71587aca81be5cffbb9746510e1fe04e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.6" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.35 || ~5.7 || ~6.4 || ~7.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/master" + }, + "time": "2020-04-16T18:48:43+00:00" + }, { "name": "nextcloud/coding-standard", "version": "v0.4.0", @@ -727,6 +1096,115 @@ }, "time": "2020-12-14T07:22:40+00:00" }, + { + "name": "nikic/php-parser", + "version": "v4.10.4", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.4" + }, + "time": "2020-12-20T10:01:03+00:00" + }, + { + "name": "openlss/lib-array2xml", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nullivex/lib-array2xml.git", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "LSS": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bryan Tong", + "email": "bryan@nullivex.com", + "homepage": "https://www.nullivex.com" + }, + { + "name": "Tony Butler", + "email": "spudz76@gmail.com", + "homepage": "https://www.nullivex.com" + } + ], + "description": "Array2XML conversion library credit to lalit.org", + "homepage": "https://www.nullivex.com", + "keywords": [ + "array", + "array conversion", + "xml", + "xml conversion" + ], + "support": { + "issues": "https://github.com/nullivex/lib-array2xml/issues", + "source": "https://github.com/nullivex/lib-array2xml/tree/master" + }, + "time": "2019-03-29T20:06:56+00:00" + }, { "name": "phar-io/manifest", "version": "2.0.1", @@ -893,6 +1371,63 @@ }, "time": "2020-10-14T08:39:05+00:00" }, + { + "name": "php-parallel-lint/php-parallel-lint", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git", + "reference": "474f18bc6cc6aca61ca40bfab55139de614e51ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/474f18bc6cc6aca61ca40bfab55139de614e51ca", + "reference": "474f18bc6cc6aca61ca40bfab55139de614e51ca", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.4.0" + }, + "replace": { + "grogy/php-parallel-lint": "*", + "jakub-onderka/php-parallel-lint": "*" + }, + "require-dev": { + "nette/tester": "^1.3 || ^2.0", + "php-parallel-lint/php-console-highlighter": "~0.3", + "squizlabs/php_codesniffer": "~3.0" + }, + "suggest": { + "php-parallel-lint/php-console-highlighter": "Highlight syntax in code snippet" + }, + "bin": [ + "parallel-lint" + ], + "type": "library", + "autoload": { + "classmap": [ + "./" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "ahoj@jakubonderka.cz" + } + ], + "description": "This tool check syntax of PHP files about 20x faster than serial check.", + "homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint", + "support": { + "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues", + "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/master" + }, + "time": "2020-04-04T12:18:32+00:00" + }, { "name": "phpdocumentor/reflection-common", "version": "2.2.0", @@ -4149,6 +4684,111 @@ ], "time": "2020-07-12T23:59:07+00:00" }, + { + "name": "vimeo/psalm", + "version": "4.3.1", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "2feba22a005a18bf31d4c7b9bdb9252c73897476" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/2feba22a005a18bf31d4c7b9bdb9252c73897476", + "reference": "2feba22a005a18bf31d4c7b9bdb9252c73897476", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.1", + "amphp/byte-stream": "^1.5", + "composer/package-versions-deprecated": "^1.8.0", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^1.1", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.3", + "felixfbecker/language-server-protocol": "^1.4", + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0", + "nikic/php-parser": "^4.10.1", + "openlss/lib-array2xml": "^1.0", + "php": "^7.1|^8", + "sebastian/diff": "^3.0 || ^4.0", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0", + "webmozart/path-util": "^2.3" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "amphp/amp": "^2.4.2", + "bamarni/composer-bin-plugin": "^1.2", + "brianium/paratest": "^4.0.0", + "ext-curl": "*", + "php": "^7.3|^8", + "phpdocumentor/reflection-docblock": "^5", + "phpmyadmin/sql-parser": "5.1.0", + "phpspec/prophecy": ">=1.9.0", + "phpunit/phpunit": "^9.0", + "psalm/plugin-phpunit": "^0.13", + "slevomat/coding-standard": "^5.0", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^4.3", + "weirdan/prophecy-shim": "^1.0 || ^2.0" + }, + "suggest": { + "ext-igbinary": "^2.0.5" + }, + "bin": [ + "psalm", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor", + "psalter" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev", + "dev-3.x": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\": "src/Psalm/" + }, + "files": [ + "src/functions.php", + "src/spl_object_id.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php" + ], + "support": { + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm/tree/4.3.1" + }, + "time": "2020-12-03T16:44:10+00:00" + }, { "name": "webmozart/assert", "version": "1.9.1", @@ -4201,6 +4841,56 @@ "source": "https://github.com/webmozart/assert/tree/master" }, "time": "2020-07-08T17:02:28+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, + "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], diff --git a/lib/AppInfo/Application20.php b/lib/AppInfo/Application20.php index 8f75799c2..11fbf6619 100644 --- a/lib/AppInfo/Application20.php +++ b/lib/AppInfo/Application20.php @@ -214,7 +214,7 @@ class Application20 extends App implements IBootstrap { } ); $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareNew', function (Event $e) { + '\OCA\Deck\Board::onShareNew', function (Event $e) use ($server) { $fullTextSearchService = $server->get(FullTextSearchService::class); $fullTextSearchService->onBoardShares($e); } diff --git a/lib/Db/AssignmentMapper.php b/lib/Db/AssignmentMapper.php index 1abe144ec..bce0db4e8 100644 --- a/lib/Db/AssignmentMapper.php +++ b/lib/Db/AssignmentMapper.php @@ -91,7 +91,7 @@ class AssignmentMapper extends QBMapper implements IPermissionMapper { * Check if user exists before assigning it to a card * * @param Entity $entity - * @return null|Assignment + * @return Assignment * @throws NotFoundException */ public function insert(Entity $entity): Entity { diff --git a/lib/Db/StackMapper.php b/lib/Db/StackMapper.php index 8cf28918a..fc2f6c715 100644 --- a/lib/Db/StackMapper.php +++ b/lib/Db/StackMapper.php @@ -39,9 +39,8 @@ class StackMapper extends DeckMapper implements IPermissionMapper { /** * @param $id - * @return \OCP\AppFramework\Db\Entity if not found - * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException - * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws MultipleObjectsReturnedException + * @throws DoesNotExistException */ public function find($id): Stack { $sql = 'SELECT * FROM `*PREFIX*deck_stacks` ' . diff --git a/lib/Provider/DeckProvider.php b/lib/Provider/DeckProvider.php index e886ed2f3..72e0e623c 100644 --- a/lib/Provider/DeckProvider.php +++ b/lib/Provider/DeckProvider.php @@ -128,10 +128,8 @@ class DeckProvider implements IFullTextSearchProvider { } - /** - * @return ISearchTemplate - */ public function getSearchTemplate(): ISearchTemplate { + /** @psalm-var ISearchTemplate */ $template = new SearchTemplate('icon-deck', 'icons'); return $template; @@ -204,6 +202,7 @@ class DeckProvider implements IFullTextSearchProvider { * @throws MultipleObjectsReturnedException */ public function updateDocument(IIndex $index): IIndexDocument { + /** @psalm-var IIndexDocument */ $document = new IndexDocument(DeckProvider::DECK_PROVIDER_ID, $index->getDocumentId()); $document->setIndex($index); diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index b5e60a625..f49a5e706 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -24,6 +24,7 @@ namespace OCA\Deck\Service; +use OC\EventDispatcher\SymfonyAdapter; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Activity\ChangeSet; use OCA\Deck\AppInfo\Application; @@ -46,7 +47,6 @@ use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; use OCP\IUserManager; use OCA\Deck\BadRequestException; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; class BoardService { @@ -64,7 +64,6 @@ class BoardService { private $groupManager; private $userId; private $activityManager; - /** @var EventDispatcherInterface */ private $eventDispatcher; private $changeHelper; @@ -84,7 +83,7 @@ class BoardService { IUserManager $userManager, IGroupManager $groupManager, ActivityManager $activityManager, - EventDispatcherInterface $eventDispatcher, + SymfonyAdapter $eventDispatcher, ChangeHelper $changeHelper, $userId ) { diff --git a/lib/Service/FullTextSearchService.php b/lib/Service/FullTextSearchService.php index 3362ea162..dc56073ec 100644 --- a/lib/Service/FullTextSearchService.php +++ b/lib/Service/FullTextSearchService.php @@ -161,6 +161,7 @@ class FullTextSearchService { * @return IIndexDocument */ public function generateIndexDocumentFromCard(Card $card): IIndexDocument { + /** @psalm-var IIndexDocument */ $document = new IndexDocument(DeckProvider::DECK_PROVIDER_ID, (string)$card->getId()); return $document; @@ -193,6 +194,7 @@ class FullTextSearchService { public function generateDocumentAccessFromCardId(int $cardId): IDocumentAccess { $board = $this->getBoardFromCardId($cardId); + /** @psalm-var IDocumentAccess */ return new DocumentAccess($board->getOwner()); } diff --git a/lib/Service/PermissionService.php b/lib/Service/PermissionService.php index ce0088258..05c393786 100644 --- a/lib/Service/PermissionService.php +++ b/lib/Service/PermissionService.php @@ -106,7 +106,7 @@ class PermissionService { /** * Get current user permissions for a board * - * @param Board|Entity $board + * @param Board $board * @return array|bool * @internal param $boardId */ @@ -170,10 +170,9 @@ class PermissionService { try { $board = $this->boardMapper->find($boardId); return $board && $userId === $board->getOwner(); - } catch (DoesNotExistException $e) { - } catch (MultipleObjectsReturnedException $e) { - return false; + } catch (DoesNotExistException | MultipleObjectsReturnedException $e) { } + return false; } /** diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index b5dc22213..6bca4a4ce 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -24,6 +24,7 @@ namespace OCA\Deck\Service; +use OC\EventDispatcher\SymfonyAdapter; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Activity\ChangeSet; use OCA\Deck\BadRequestException; @@ -36,7 +37,6 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; use OCA\Deck\StatusException; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; class StackService { @@ -50,8 +50,7 @@ class StackService { private $assignedUsersMapper; private $attachmentService; private $activityManager; - /** @var EventDispatcherInterface */ - private $eventDispatcher; + private $symfonyAdapter; private $changeHelper; public function __construct( @@ -65,7 +64,7 @@ class StackService { AssignmentMapper $assignedUsersMapper, AttachmentService $attachmentService, ActivityManager $activityManager, - EventDispatcherInterface $eventDispatcher, + SymfonyAdapter $eventDispatcher, ChangeHelper $changeHelper ) { $this->stackMapper = $stackMapper; @@ -78,7 +77,7 @@ class StackService { $this->assignedUsersMapper = $assignedUsersMapper; $this->attachmentService = $attachmentService; $this->activityManager = $activityManager; - $this->eventDispatcher = $eventDispatcher; + $this->symfonyAdapter = $eventDispatcher; $this->changeHelper = $changeHelper; } @@ -226,7 +225,7 @@ class StackService { ); $this->changeHelper->boardChanged($boardId); - $this->eventDispatcher->dispatch( + $this->symfonyAdapter->dispatch( '\OCA\Deck\Stack::onCreate', new GenericEvent(null, ['id' => $stack->getId(), 'stack' => $stack]) ); @@ -260,7 +259,7 @@ class StackService { $this->changeHelper->boardChanged($stack->getBoardId()); $this->enrichStackWithCards($stack); - $this->eventDispatcher->dispatch( + $this->symfonyAdapter->dispatch( '\OCA\Deck\Stack::onDelete', new GenericEvent(null, ['id' => $id, 'stack' => $stack]) ); @@ -315,7 +314,7 @@ class StackService { ); $this->changeHelper->boardChanged($stack->getBoardId()); - $this->eventDispatcher->dispatch( + $this->symfonyAdapter->dispatch( '\OCA\Deck\Stack::onUpdate', new GenericEvent(null, ['id' => $id, 'stack' => $stack]) ); diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 000000000..04840bad9 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml new file mode 100644 index 000000000..9e0a0aa93 --- /dev/null +++ b/tests/psalm-baseline.xml @@ -0,0 +1,690 @@ + + + + + $message !== null + + + getArchived + getBoardId + getBoardId + getBoardId + getBoardId + getCardId + getCardId + getStackId + getTitle + getTitle + + + + + (int)$subjectParams['comment'] + + + + + Application + + + + + IBootstrap + + + + + listen + listen + + + + + getAcl + getOwner + getTitle + getTitle + + + + + void + + + $this->boardMapper + $this->stackMapper + + + $this->boardMapper + $this->stackMapper + + + + + $modified === null + $modified === null + + + Util + + + $this->userId + + + $this->userId + + + + + \OCP\Deck\DB\Board + + + + + $cardId + $cardId + $cardId + $commentId + $commentId + $parentId + + + + + Application + Application + Application + + + + + $modified !== null + + + Util + + + + + Job + + + + + Job + + + + + Job + + + + + ExternalCalendar + + + + + IACL + ICalendarObject + + + + + ICalendarProvider + + + + + NotFound + + + + + IWidget + + + + + getPermissionEdit + getPermissionManage + getPermissionShare + + + + + $aclId + + + + + $cardId + + + getParticipant + getParticipant + getParticipant + getParticipant + getParticipant + getParticipant + getType + getType + getType + + + + + getCardId + getCardId + + + $query + + + + + getLastModified + + + + + $boardId + + + \OCA\Circles\Api\v1\Circles + + + setAcl + setLabels + + + + + VCalendar + VCalendar + + + getArchived + getArchived + getDescription + getLabels + getLabels + getLastModified + getLastModified + getStackId + getTitle + + + + + $qb->createNamedParameter($boardIds, IQueryBuilder::PARAM_INT_ARRAY) + + + $entity->getId() + + + $cardId + + + getDescription + getDescription + getDuedate + setCreatedAt + setDatabaseType + setDatabaseType + setDescription + setDescription + setLabels + setLastModified + setLastModified + setNotified + setNotified + + + + + $this->cache + $this->request + $this->userId + + + $this->cache + $this->cache + $this->cache + $this->cache + $this->request + $this->userId + + + + + \OCA\Circles\Model\Circle + + + $this->object + $this->object + $this->object + $this->object + \OCA\Circles\Model\Circle + + + + + getLastModified + + + + + $labelId + + + setLastModified + setLastModified + + + + + getETag + + + + + VCalendar + VCalendar + + + getLastModified + getTitle + + + + + $stackId + + + getBoardId + + + + + BeforeTemplateRenderedEvent + + + + + getParticipant + getParticipant + getType + getType + + + + + $board->getId() + + + Application + + + getTitle + getTitle + getTitle + getTitle + + + + + (string) $l->t('%s has mentioned you in a comment on "%s".', [$dn, $params[0]]) + (string) $l->t('The board "%s" has been shared with you by %s.', [$params[0], $dn]) + (string) $l->t('The card "%s" on "%s" has been assigned to you by %s.', [$params[0], $params[1], $dn]) + (string) $l->t('The card "%s" on "%s" has reached its due date.', $params) + (string) $l->t('{user} has assigned the card "%s" on "%s" to you.', [$params[0], $params[1]]) + (string) $l->t('{user} has mentioned you in a comment on "%s".', [$params[0]]) + (string) $l->t('{user} has shared the board %s with you.', [$params[0]]) + + + + + [] + + + IndexDocument + SearchTemplate + + + + + SearchResultEntry + + + + + SearchResultEntry + + + + + IProvider + + + + + $cardId + $cardId + + + getParticipant + getParticipant + getParticipant + getType + getType + getType + setCardId + setParticipant + setType + + + $this->currentUser + + + $this->currentUser + + + + + Application + + + getCardId + getCardId + getCardId + getData + getType + getType + setCardId + setCreatedAt + setCreatedBy + setData + setLastModified + setLastModified + setType + + + + + '\OCA\Deck\Board::onCreate' + '\OCA\Deck\Board::onDelete' + '\OCA\Deck\Board::onDelete' + '\OCA\Deck\Board::onShareEdit' + '\OCA\Deck\Board::onUpdate' + '\OCA\Deck\Board::onUpdate' + + + Application + Application + Application + + + findAll + findAll + + + getAcl + getAcl + getAcl + getBoardId + getBoardId + getBoardId + getBoardId + getParticipant + getType + setBoardId + setBoardId + setBoardId + setBoardId + setColor + setColor + setColor + setColor + setColor + setLabels + setOwner + setOwner + setParticipant + setPermissionEdit + setPermissionEdit + setPermissionManage + setPermissionManage + setPermissionShare + setPermissionShare + setPermissions + setPermissions + setPermissions + setPermissions + setSettings + setTitle + setTitle + setTitle + setTitle + setTitle + setTitle + setType + + + + + findAssignedCards + + + \OCP\AppFramework\Db\ + + + getArchived + getArchived + getArchived + getArchived + getArchived + getDescription + getDescription + getDescription + getDescriptionPrev + getDescriptionPrev + getLastEditor + getLastEditor + getLastEditor + getOrder + setArchived + setArchived + setArchived + setAssignedUsers + setAssignedUsers + setAttachmentCount + setAttachments + setCommentsUnread + setDeletedAt + setDeletedAt + setDescription + setDescription + setDescriptionPrev + setDescriptionPrev + setDuedate + setDuedate + setLabels + setLastEditor + setOrder + setOrder + setOwner + setOwner + setStackId + setStackId + setStackId + setTitle + setTitle + setTitle + setType + setType + + + + + \OCA\Circles\Api\v1\Circles + \OCA\Circles\Api\v1\Circles + + + + + Application + Application + Application + Application + Application + + + $this->cardMapper + $this->permissionService + + + $this->cardMapper + $this->cardMapper + $this->cardMapper + $this->cardMapper + $this->permissionService + $this->permissionService + $this->permissionService + $this->permissionService + + + + + (int)$value + + + Application + Application + Application + Application + Application + Application + Application + + + + + Application + Application + + + $color === false || $color === null + $color === null + $title === false || $title === null + $title === null + $userId === false || $userId === null + $userId === null + + + $color === false + $title === false + $userId === false + + + + + $this->rootFolder + IRootFolder + + + is_resource($content) + is_resource($content) + + + getCardId + getCardId + getCardId + getData + getData + setData + setData + setDeletedAt + setExtendedData + setLastModified + + + + + DocumentAccess + IndexDocument + + + getDescription + getDescription + getTitle + getTitle + + + + + getBoardId + getBoardId + getBoardId + setBoardId + setColor + setColor + setTitle + setTitle + + + + + setAssignedUsers + setAttachmentCount + setCommentsUnread + setLabels + + + + + \OCA\Circles\Api\v1\Circles + \OCA\Circles\Api\v1\Circles + + + getAcl + getParticipant + getParticipant + getParticipant + getParticipant + getType + getType + getType + getType + getType + getType + + + + + '\OCA\Deck\Stack::onCreate' + '\OCA\Deck\Stack::onDelete' + '\OCA\Deck\Stack::onUpdate' + + + BadRquestException + + + getBoardId + getBoardId + getBoardId + getBoardId + getOrder + setBoardId + setBoardId + setCards + setDeletedAt + setDeletedAt + setOrder + setOrder + setTitle + setTitle + + + diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index 909eb5c21..146c08bc0 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -23,6 +23,7 @@ namespace OCA\Deck\Service; +use OC\EventDispatcher\SymfonyAdapter; use OC\L10N\L10N; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Db\Acl; @@ -90,7 +91,7 @@ class BoardServiceTest extends TestCase { $this->groupManager = $this->createMock(IGroupManager::class); $this->activityManager = $this->createMock(ActivityManager::class); $this->changeHelper = $this->createMock(ChangeHelper::class); - $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class); + $this->eventDispatcher = $this->createMock(SymfonyAdapter::class); $this->service = new BoardService( $this->boardMapper, diff --git a/tests/unit/Service/StackServiceTest.php b/tests/unit/Service/StackServiceTest.php index e40d8e93c..36f8a5463 100644 --- a/tests/unit/Service/StackServiceTest.php +++ b/tests/unit/Service/StackServiceTest.php @@ -23,6 +23,7 @@ namespace OCA\Deck\Service; +use OC\EventDispatcher\SymfonyAdapter; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\Card; @@ -84,7 +85,7 @@ class StackServiceTest extends TestCase { $this->labelMapper = $this->createMock(LabelMapper::class); $this->activityManager = $this->createMock(ActivityManager::class); $this->changeHelper = $this->createMock(ChangeHelper::class); - $this->eventDispatcher = $this->createMock(EventDispatcherInterface::class); + $this->eventDispatcher = $this->createMock(SymfonyAdapter::class); $this->stackService = new StackService( $this->stackMapper,