{"id":13616257,"url":"https://github.com/staabm/phpstan-baseline-analysis","last_synced_at":"2025-04-12T21:19:54.888Z","repository":{"id":38373381,"uuid":"392663293","full_name":"staabm/phpstan-baseline-analysis","owner":"staabm","description":"Analyzes PHPStan baseline files and creates aggregated error trend-reports","archived":false,"fork":false,"pushed_at":"2024-10-14T05:11:08.000Z","size":161,"stargazers_count":75,"open_issues_count":10,"forks_count":9,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-30T00:33:34.552Z","etag":null,"topics":["hacktoberfest","phpstan"],"latest_commit_sha":null,"homepage":"https://staabm.github.io/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/staabm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["staabm"]}},"created_at":"2021-08-04T11:30:36.000Z","updated_at":"2024-10-14T05:11:11.000Z","dependencies_parsed_at":"2023-09-28T08:06:59.077Z","dependency_job_id":"141c1413-d496-481d-8481-81471ae29c59","html_url":"https://github.com/staabm/phpstan-baseline-analysis","commit_stats":{"total_commits":151,"total_committers":12,"mean_commits":"12.583333333333334","dds":"0.49006622516556286","last_synced_commit":"475925061b4dfd8ce60de7f8b947e81e54820dc5"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-baseline-analysis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-baseline-analysis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-baseline-analysis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-baseline-analysis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/staabm","download_url":"https://codeload.github.com/staabm/phpstan-baseline-analysis/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248632141,"owners_count":21136630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","phpstan"],"created_at":"2024-08-01T20:01:25.949Z","updated_at":"2025-04-12T21:19:54.865Z","avatar_url":"https://github.com/staabm.png","language":"PHP","funding_links":["https://github.com/sponsors/staabm"],"categories":["PHP"],"sub_categories":[],"readme":"Analyzes phpstan baseline files\n-------------------------------\n\nAnalyzes PHPStan baseline files and creates aggregated error trend-reports.\n\n[Read more in the Blog post.](https://staabm.github.io/2022/07/04/phpstan-baseline-analysis.html)\n\nYou need at least one of the supported PHPStan RuleSets/Rules configured in your project, to get meaningful results.\n\n## Installation\n\n```\ncomposer require staabm/phpstan-baseline-analysis --dev\n```\n\n## Supported Rules\n\n### PHPStan RuleSets\n- https://github.com/phpstan/phpstan-deprecation-rules\n\n### PHPStan Rules\n- PHPStan\\Rules\\PhpDoc\\InvalidPhpDocTagValueRule\n\n### [Symplify PHPStan Rules](https://github.com/symplify/phpstan-rules)\n- Symplify\\PHPStanRules\\Rules\\Explicit\\NoMixedMethodCallerRule\n- Symplify\\PHPStanRules\\Rules\\Explicit\\NoMixedPropertyFetcherRule\n\n### [tomasvotruba/cognitive-complexity](https://github.com/TomasVotruba/cognitive-complexity) Rules\n- TomasVotruba\\CognitiveComplexity\\Rules\\ClassLikeCognitiveComplexityRule\n\n### [tomasvotruba/type-coverage](https://github.com/TomasVotruba/type-coverage) Rules\n- TomasVotruba\\TypeCoverage\\Rules\\ParamTypeCoverageRule\n- TomasVotruba\\TypeCoverage\\Rules\\PropertyTypeCoverageRule\n- TomasVotruba\\TypeCoverage\\Rules\\ReturnTypeCoverageRule\n\n### [tomasvotruba/unused-public](https://github.com/TomasVotruba/unused-public) Rules\n- TomasVotruba\\UnusedPublic\\Rules\\UnusedPublicClassConstRule\n- TomasVotruba\\UnusedPublic\\Rules\\UnusedPublicClassMethodRule\n- TomasVotruba\\UnusedPublic\\Rules\\UnusedPublicPropertyRule\n\n\n## example report\n\nStarting from the current directory, the command will recursively search for files matching the glob pattern and report a summary for each baseline found.\n\n```\n$ phpstan-baseline-analyze *phpstan-baseline.neon\nAnalyzing app/portal/phpstan-baseline.neon\n  Overall-Errors: 41\n  Classes-Cognitive-Complexity: 70\n  Deprecations: 2\n  Invalid-Phpdocs: 5\n  Unknown-Types: 1\n  Anonymous-Variables: 4\n  Native-Property-Type-Coverage: 1\n  Native-Param-Type-Coverage: 27\n  Native-Return-Type-Coverage: 4\n  Unused-Symbols: 3\n```\n\n## example error filtering\n\nFilter a existing baseline and output only errors NOT matching the given filter key:\n\n\u003e [!TIP]\n\u003e This can be helpful to remove a class of errors out of an existing baseline, so PHPStan will start reporting them again.\n\n```\n$ phpstan-baseline-filter *phpstan-baseline.neon --exclude=Unknown-Types\n```\n\nFilter a existing baseline and output only errors matching the given filter key:\n```\n$ phpstan-baseline-filter *phpstan-baseline.neon --include=Invalid-Phpdocs\n```\n\n[Currently supported filter keys](https://github.com/staabm/phpstan-baseline-analysis/blob/1e8ea32a10e1a50c3fd21396201495a1ae1a5d1d/lib/ResultPrinter.php#L42-L51) can be found in the source.\n\n## example graph analysis\n\n```\n$ git clone ...\n\n$ phpstan-baseline-analyze *phpstan-baseline.neon --json \u003e now.json\n\n$ git checkout `git rev-list -n 1 --before=\"1 week ago\" HEAD`\n$ phpstan-baseline-analyze '*phpstan-baseline.neon' --json \u003e 1-week-ago.json\n\n$ git checkout `git rev-list -n 1 --before=\"2 week ago\" HEAD`\n$ phpstan-baseline-analyze '*phpstan-baseline.neon' --json \u003e 2-weeks-ago.json\n\n$ php phpstan-baseline-graph '*.json' \u003e result.html\n```\n\n![PHPStan baseline analysis graph](https://github.com/staabm/phpstan-baseline-analysis/assets/120441/ea5abe25-21e8-43f2-9118-0967a75517c6)\n\n\n## example trend analysis\n\nthe following example shows the evolution of errors in your phpstan baselines.\nsee the trend between 2 different points in time like:\n\n```\n$ git clone ...\n\n$ phpstan-baseline-analyze '*phpstan-baseline.neon' --json \u003e now.json\n\n$ git checkout `git rev-list -n 1 --before=\"1 week ago\" HEAD`\n\n$ phpstan-baseline-analyze '*phpstan-baseline.neon' --json \u003e reference.json\n\n$ phpstan-baseline-trend reference.json now.json\nAnalyzing Trend for app/portal/phpstan-baseline.neon\n  Overall-Errors: 30 -\u003e 17 =\u003e improved\n  Classes-Cognitive-Complexity: 309 -\u003e 177 =\u003e improved\n  Deprecations: 1 -\u003e 2 =\u003e worse\n  Invalid-Phpdocs: 3 -\u003e 1 =\u003e good\n  Unknown-Types: 5 -\u003e 15 =\u003e worse\n  Anonymous-Variables: 4 -\u003e 3 =\u003e good\n  Unused-Symbols: 1 -\u003e 1 =\u003e good\n  Native-Return-Type-Coverage: 20 -\u003e 2 =\u003e worse\n  Native-Property-Type-Coverage: 3 -\u003e 3 =\u003e good\n  Native-Param-Type-Coverage: 4 -\u003e 40 =\u003e improved\n```\n\n## Usage example in a scheduled GitHub Action with Mattermost notification\n\nCopy the following workflow into your repository. Make sure to adjust as needed:\n- adjust the cron schedule pattern\n- actions/checkout might require a token - e.g. for private repos\n- adjust the comparison period, as you see fit\n- adjust the notification to your needs - e.g. use Slack, Discord, E-Mail,..\n\n```\nname: Trends Analyse\n\non:\n  workflow_dispatch:\n  schedule:\n    - cron: '0 8 * * 4'\n\njobs:\n\n  behat:\n    name: Trends\n    runs-on: ubuntu-latest\n    timeout-minutes: 10\n\n    steps:\n      - run: \"composer global require staabm/phpstan-baseline-analysis\"\n      - run: echo \"$(composer global config bin-dir --absolute --quiet)\" \u003e\u003e $GITHUB_PATH\n\n      - uses: actions/checkout@v2\n        with:\n          fetch-depth: 50 # fetch the last X commits.\n\n      - run: \"phpstan-baseline-analyze '*phpstan-baseline.neon' --json \u003e ../now.json\"\n\n      - run: git checkout `git rev-list -n 1 --before=\"1 week ago\" HEAD`\n\n      - run: \"phpstan-baseline-analyze '*phpstan-baseline.neon' --json \u003e ../reference.json\"\n\n      - name: analyze trend\n        shell: php {0}\n        run: |\n          \u003c?php\n          exec('phpstan-baseline-trend ../reference.json ../now.json \u003e ../trend.txt', $output, $exitCode);\n          $project = '${{ github.repository }}';\n\n          if ($exitCode == 0) {\n            # improvements\n            file_put_contents(\n              'mattermost.json',\n              json_encode([\"username\" =\u003e \"github-action-trend-bot\", \"text\" =\u003e $project .\" :tada:\\n\". file_get_contents(\"../trend.txt\")])\n            );\n          }\n          elseif ($exitCode == 1) {\n            # steady\n            file_put_contents(\n              'mattermost.json',\n              json_encode([\"username\" =\u003e \"github-action-trend-bot\", \"text\" =\u003e $project .\" :green_heart:\\n\". file_get_contents(\"../trend.txt\")])\n            );\n          }\n          elseif ($exitCode == 2) {\n            # got worse\n            file_put_contents(\n              'mattermost.json',\n              json_encode([\"username\" =\u003e \"github-action-trend-bot\", \"text\" =\u003e $project .\" :broken_heart:\\n\". file_get_contents(\"../trend.txt\")])\n            );\n          }\n\n      - run: 'curl -X POST -H \"Content-Type: application/json\" -d @mattermost.json ${{ secrets.MATTERMOST_WEBHOOK_URL }}'\n        if: always()\n\n```\n\n## 💌 Give back some love\n\n[Consider supporting the project](https://github.com/sponsors/staabm), so we can make this tool even better even faster for everyone.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstaabm%2Fphpstan-baseline-analysis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstaabm%2Fphpstan-baseline-analysis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstaabm%2Fphpstan-baseline-analysis/lists"}