{"id":15525117,"url":"https://github.com/staabm/phpstan-todo-by","last_synced_at":"2025-05-15T10:01:40.951Z","repository":{"id":212535956,"uuid":"731628119","full_name":"staabm/phpstan-todo-by","owner":"staabm","description":"Todo comments with expiration","archived":false,"fork":false,"pushed_at":"2025-03-31T19:24:30.000Z","size":263,"stargazers_count":183,"open_issues_count":7,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-14T16:53:43.479Z","etag":null,"topics":["comment","expiration","extension","phpstan"],"latest_commit_sha":null,"homepage":"https://staabm.github.io/2023/12/17/phpstan-todo-by-published.html","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,"zenodo":null},"funding":{"github":["staabm"]}},"created_at":"2023-12-14T14:04:19.000Z","updated_at":"2025-04-14T11:05:43.000Z","dependencies_parsed_at":"2024-01-08T21:48:15.931Z","dependency_job_id":"ee25f55a-9547-48de-a7ac-9b0102423666","html_url":"https://github.com/staabm/phpstan-todo-by","commit_stats":{"total_commits":146,"total_committers":8,"mean_commits":18.25,"dds":"0.12328767123287676","last_synced_commit":"a167158855ac7e2e1c5a64c324065175ee3121b4"},"previous_names":["staabm/phpstan-todo-by"],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-todo-by","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-todo-by/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-todo-by/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/staabm%2Fphpstan-todo-by/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/staabm","download_url":"https://codeload.github.com/staabm/phpstan-todo-by/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319715,"owners_count":22051072,"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":["comment","expiration","extension","phpstan"],"created_at":"2024-10-02T10:54:51.067Z","updated_at":"2025-05-15T10:01:40.166Z","avatar_url":"https://github.com/staabm.png","language":"PHP","funding_links":["https://github.com/sponsors/staabm"],"categories":[],"sub_categories":[],"readme":"# phpstan-todo-by: comments with expiration\n\nPHPStan extension to check for `TODO/FIXME/XXX` comments with expiration.\nInspired by [parker-codes/todo-by](https://github.com/parker-codes/todo_by).\n\n\n## Examples\n\nThe main idea is, that comments within the source code will be turned into PHPStan errors when a condition is satisfied, e.g. a date reached, a version met, a issue tracker ticket is closed.\n\n```php\n\u003c?php\n\n// TODO: 2023-12-14 This comment turns into a PHPStan error as of 14th december 2023\nfunction doFoo() { /* ... */ }\n\n// TODO https://github.com/staabm/phpstan-todo-by/issues/91 fix me when this GitHub issue is closed\nclass FooClass {}\n\n// TODO: \u003c1.0.0 This has to be in the first major release of this repo\nfunction doBar() { /* ... */ }\n\n// FIXME: phpunit/phpunit:5.3 This has to be fixed when updating phpunit to 5.3.x or higher\nfunction doFooBar() { /* ... */ }\n\n// XXX: php:8 drop this polyfill when php 8.x is required\n\n// TODO: APP-2137 A comment which errors when the issue tracker ticket gets resolved\nfunction doBaz() { /* ... */ }\n\n```\n\n\n## Supported todo formats\n\nA todo comment can also consist of just a constraint without any text, like `// @todo 2023-12-14`.\nWhen a text is given after the date, this text will be picked up for the PHPStan error message.\n\n- the `todo`, `TODO`, `tOdO`, `FIXME`, `XXX` keyword is case-insensitive\n- the `todo` keyword can be suffixed or prefixed by a `@` character\n- a username might be included after the `todo@`\n- the comment might be mixed with `:` or `-` characters\n- multi line `/* */` and `/** */` comments are supported\n\n**Out of the box** comments can expire by different constraints:\n- by date with format of `YYYY-MM-DD` matched against the [reference-time](https://github.com/staabm/phpstan-todo-by#reference-time)\n- by a full github issue url\n- by a semantic version constraint matched against a Composer dependency (via `composer.lock`)\n\nThere are more builtin constraints, but these **require additional configuration**:\n- by a semantic version constraint matched against the projects [reference-version config](https://github.com/staabm/phpstan-todo-by#reference-version)\n- by a semantic version constraint matched against a Composer dependency (via [`virtualPackages config`](https://github.com/staabm/phpstan-todo-by#virtual-packages))\n- by ticket reference, matched against the status of a ticket (e.g. in [github.com or JIRA via config](https://github.com/staabm/phpstan-todo-by#issue-tracker-key-support))\n\nsee examples of different comment variants which are supported:\n\n```php\n// todo 2023-12-14\n// @todo: 2023-12-14 fix it\n// @todo 2023-12-14: fix it\n// XXX - 2023-12-14 fix it\n// FIXME 2023-12-14 - fix it\n\n// TODO@staabm 2023-12-14 - fix it\n// TODO@markus: 2023-12-14 - fix it\n\n// TODO https://github.com/staabm/phpstan-todo-by/issues/91 fix me when this GitHub issue is closed\n\n/*\n * other text\n *\n * @todo 2023-12-14 classic multi line comment\n *   more comment data\n */\n\n// TODO: \u003c1.0.0 This has to be in the first major release\n// TODO \u003e123.4: Must fix this or bump the version\n\n// TODO: phpunit/phpunit:\u003c5 This has to be fixed before updating to phpunit 5.x\n// TODO@markus: phpunit/phpunit:5.3 This has to be fixed when updating phpunit to 5.3.x or higher\n\n// TODO: APP-123 fix it when this Jira ticket is closed\n// TODO: #123 fix it when this GitHub issue is closed\n// TODO: GH-123 fix it when this GitHub issue is closed\n// TODO: some-organization/some-repo#123 change me if this GitHub pull request is closed\n```\n\n## Configuration\n\n\n### Non-ignorable errors\n\nErrors emitted by the extension are non-ignorable by default, so they cannot accidentally be put into the baseline.\nYou can change this behaviour with a configuration option within your `phpstan.neon`:\n\n```neon\nparameters:\n    todo_by:\n        nonIgnorable: false # default is true\n```\n\n\n### Reference time\n\nBy default date-todo-comments are checked against todays date.\n\nYou might be interested, which comments will expire e.g. within the next 7 days, which can be configured with the `referenceTime` option.\nYou need to configure a date parsable by `strtotime`.\n\n```neon\nparameters:\n    todo_by:\n        # any strtotime() compatible string\n        referenceTime: \"now+7days\"\n```\n\nIt can be especially handy to use a env variable for it, so you can pass the reference date e.g. via the CLI:\n\n```neon\nparameters:\n    todo_by:\n        referenceTime: %env.TODOBY_REF_TIME%\n```\n\n`TODOBY_REF_TIME=\"now+7days\" vendor/bin/phpstan analyze`\n\n\n### Reference version\n\nBy default version-todo-comments are checked against `\"nextMajor\"` version.\nIt is determined by fetching the latest local available git tag and incrementing the major version number.\n\nThe behaviour can be configured with the `referenceVersion` option.\nPossible values are `\"nextMajor\"`, `\"nextMinor\"`, `\"nextPatch\"` - which will be computed based on the latest local git tag - or any other version string like `\"1.2.3\"`.\n\n```neon\nparameters:\n    todo_by:\n        # \"nextMajor\", \"nextMinor\", \"nextPatch\" or a version string like \"1.2.3\"\n        referenceVersion: \"nextMinor\"\n```\n\nAs shown in the \"Reference time\"-paragraph above, you might even use a env variable instead.\n\n\u003e [!NOTE]\n\u003e The reference version is not applied to package-version-todo-comments which are matched against `composer.lock` instead.\n\n#### Prerequisite\n\nMake sure tags are available within your git clone, e.g. by running `git fetch --tags origin` - otherwise you are likely running into a 'Could not determine latest git tag' error.\n\nIn a GitHub Action this can be done like this:\n\n```yaml\n    -   name: Checkout\n        uses: actions/checkout@v4\n\n    -   name: Get tags\n        run: git fetch --tags origin\n```\n\n\n#### Multiple GIT repository support\n\nBy default the latest git tag to calculate the reference version is fetched once for all files beeing analyzed.\n\nThis behaviour can be configured with the `singleGitRepo` option.\n\nIn case you are using git submodules, or the analyzed codebase consists of multiple git repositories,\nset the `singleGitRepo` option to `false` which resolves the reference version for each directory beeing analyzed.\n\n\n#### Virtual packages\n\nWithin the PHPStan config file you can define additional packages, to match against package-version-todo-comments.\n\n```neon\nparameters:\n    todo_by:\n        virtualPackages:\n            'staabm/mypackage': '2.1.0'\n            'staabm/my-api': '3.1.0'\n```\n\nReference these virtual packages like any other package in your todo-comments:\n\n`// TODO staabm/mypackage:2.2.0 remove the following function once staabm/mypackage is updated to 2.2.0`\n\n\n### Issue tracker key support\n\nOptionally you can configure this extension to analyze your comments with issue tracker ticket keys.\nThe extension fetches issue tracker API for issue status. If the remote issue is resolved, the comment will be reported.\n\nCurrently, Jira, GitHub and YouTrack are supported.\n\nThis feature is disabled by default. To enable it, you must set `ticket.enabled` parameter to `true`.\nYou also need to set these parameters:\n\n```yaml\nparameters:\n    todo_by:\n        ticket:\n            enabled: true\n\n            # one of: jira, github (case-sensitive)\n            tracker: jira\n\n            # a case-sensitive list of status names.\n            # only tickets having any of these statuses are considered resolved.\n            # supported trackers: jira. Other trackers ignore this parameter.\n            resolvedStatuses:\n                - Done\n                - Resolved\n                - Declined\n\n            # if your ticket key is FOO-12345, then this value should be [\"FOO\"].\n            # multiple key prefixes are allowed, e.g. [\"FOO\", \"APP\"].\n            # only comments with keys containing this prefix will be analyzed.\n            # supported trackers: jira, youtrack. Other trackers ignore this parameter.\n            keyPrefixes:\n                - FOO\n\n            jira:\n                # e.g. https://your-company.atlassian.net\n                server: https://acme.atlassian.net\n\n                # see below for possible formats.\n                # if this value is empty, credentials file will be used instead.\n                credentials: %env.JIRA_TOKEN%\n\n                # path to a file containing Jira credentials.\n                # see below for possible formats.\n                # if credentials parameter is not empty, it will be used instead of this file.\n                # this file must not be committed into the repository!\n                credentialsFilePath: .secrets/jira-credentials.txt\n\n            github:\n                # The account owner of referenced repositories.\n                defaultOwner: your-name\n\n                # The name of the repository without the .git extension.\n                defaultRepo: your-repository\n\n                # GitHub Access Token\n                # if this value is empty, credentials file will be used instead.\n                credentials: null\n\n                # path to a file containing GitHub Access Token.\n                # if credentials parameter is not empty, it will be used instead of this file.\n                # this file must not be committed into the repository!\n                credentialsFilePath: null\n\n            youtrack:\n                # e.g. https://your-company.youtrack.cloud\n                server: https://acme.youtrack.cloud\n\n                # YouTrack permanent token\n                # if this value is empty, credentials file will be used instead.\n                credentials: %env.YOUTRACK_TOKEN%\n\n                # path to a file containing a YouTrack permanent token\n                # if credentials parameter is not empty, it will be used instead of this file.\n                # this file must not be committed into the repository!\n                credentialsFilePath: .secrets/youtrack-credentials.txt\n```\n\n#### Jira Credentials\n\nThis extension uses Jira's REST API to fetch ticket's status. If your board is not public, you need to configure valid credentials.\nThese authentication methods are supported:\n- [OAuth 2.0 Access Tokens](https://confluence.atlassian.com/adminjiraserver/jira-oauth-2-0-provider-api-1115659070.html)\n- [Personal Access Tokens](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html)\n- [Basic Authentication](https://developer.atlassian.com/server/jira/platform/basic-authentication/)\n\nWe recommend you use OAuth over basic authentication, especially if you use phpstan in CI.\nThere are multiple ways to pass your credentials to this extension.\nYou should choose one of them - if you define both parameters, only `credentials` parameter is considered and the file is ignored.\n\n##### Pass credentials in environment variable\n\nConfigure `credentials` parameter to [read value from environment variable](https://phpstan.org/config-reference#environment-variables):\n```yaml\nparameters:\n    todo_by:\n        ticket:\n            jira:\n                credentials: %env.JIRA_TOKEN%\n```\n\nDepending on chosen authentication method its content should be:\n* Access Token for token based authentication, e.g. `JIRA_TOKEN=ATATT3xFfGF0Gv_pLFSsunmigz8wq5Y0wkogoTMgxDFHyR...`\n* `\u003cusername\u003e:\u003cpasswordOrApiKey\u003e` for basic authentication, e.g. `JIRA_TOKEN=john.doe@example.com:p@ssword`\n\n##### Pass credentials in text file\n\nCreate text file in your project's directory (or anywhere else on your computer) and put its path into configuration:\n\n```yaml\nparameters:\n    todo_by:\n        ticket:\n            jira:\n                credentialsFilePath: path/to/file\n```\n\n**Remember not to commit this file to repository!**\nDepending on chosen authentication method its value should be:\n* Access Token for token based authentication, e.g. `JATATT3xFfGF0Gv_pLFSsunmigz8wq5Y0wkogoTMgxDFHyR...`\n* `\u003cusername\u003e:\u003cpasswordOrApiKey\u003e` for basic authentication, e.g. `john.doe@example.com:p@ssword`\n\n#### GitHub\nBoth issues and pull requests are supported. The comment will be reported if the referenced issue/PR is closed.\nThere are multiple ways to reference GitHub issue/PR:\n\n##### Only number\n```php\n// TODO: #123 - fix me\n// TODO: GH-123 - fix me\n```\nIf the `defaultOwner` is set to `acme` and `defaultRepo` is set to `hello-world`, the referenced issue is resolved to `acme/hello-world#123`.\n\n##### Owner + repository name + number\n```php\n// TODO: acme/hello-world#123 - fix me\n```\n\n## Installation\n\nTo use this extension, require it in [Composer](https://getcomposer.org/):\n\n```\ncomposer require --dev staabm/phpstan-todo-by\n```\n\nIf you also install [phpstan/extension-installer](https://github.com/phpstan/extension-installer) then you're all set!\n\n\u003cdetails\u003e\n  \u003csummary\u003eManual installation\u003c/summary\u003e\n\nIf you don't want to use `phpstan/extension-installer`, include extension.neon in your project's PHPStan config:\n\n```\nincludes:\n    - vendor/staabm/phpstan-todo-by/extension.neon\n```\n\n\u003c/details\u003e\n\n## FAQ\n\n### Unexpected '\"php\" version requirement \"\u003e=XXX\" satisfied' error\n\nIf you get this errors too early, it might be caused by wrong version constraints in your `composer.json` file.\nA `php` version constraint of e.g. `^7.4` means `\u003e=7.4.0 \u0026\u0026 \u003c= 7.999999.99999`,\nwhich means comments like `// TODO \u003e7.5` will emit an error.\n\nFor the `php` declaration, it is recommended to use a version constraint with a fixed upper bound, e.g. `7.4.*` or `^7 || \u003c8.3`.\n\n### 'Could not determine latest git tag' error\n\nThis error is thrown, when no git tags are available within your git clone.\nFetch git tags, as described in the [\"Reference version\"-chapter](https://github.com/staabm/phpstan-todo-by#reference-version) above.\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-todo-by","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstaabm%2Fphpstan-todo-by","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstaabm%2Fphpstan-todo-by/lists"}