Skip to main content

Detect expiring todo comments with PHPStan

· 3 min read
Stephan Hochdörfer
Head of IT Business Operations

Being a huge fan of PHPStan I regularly check what extensions exist and how they can help us to improve our code.

Last month, my friend Markus Staab released a new extension for PHPStan to check TODO comments and their expiration dates.

The new extension for PHPStan quickly improved and can now detect not only date strings in the TODO message but also Composer package names and versions, as well as the version of the application you are developing. I think this allows for some pretty interesting use cases.

The following expiration formats are currently supported:

<?php

// TODO: 2023-12-14 This comment turns into a PHPStan error as of 14th december 2023
function doFoo() { /* ... */ }

// TODO: <1.0.0 This has to be in the first major release of this repo
function doBar() { /* ... */ }

// TODO: phpunit/phpunit:5.3 This has to be fixed when updating phpunit to 5.3.x or higher
function doFooBar() { /* ... */ }

// TODO: php:8 drop this polyfill when php 8.x is required
function doBaz() { /* ... */ }

Quite recently, Markus also added a connector for JIRA so that the extension can check if referenced JIRA tickets are still open and, if not, complain that the TODO note is potentially outdated:

// TODO: APP-2137 A comment which errors when the issue tracker ticket gets resolved
function doJIRA() { /* ... */ }

By default, the feature is disabled and needs a bunch of configuration options to enable the JIRA connection:

parameters:
todo_by:
ticket:
enabled: true

# a case-sensitive list of status names.
# only tickets having any of these statuses are considered resolved.
resolvedStatuses:
- Done
- Resolved
- Declined

# if your ticket key is FOO-12345, then this value should be ["FOO"].
# multiple key prefixes are allowed, e.g. ["FOO", "APP"].
# only comments with keys containing this prefix will be analyzed.
keyPrefixes:
- FOO

jira:
# e.g. https://your-company.atlassian.net
server: https://acme.atlassian.net

# see below for possible formats.
# if this value is empty, credentials file will be used instead.
credentials: %env.JIRA_TOKEN%

# path to a file containing Jira credentials.
# see below for possible formats.
# if credentials parameter is not empty, it will be used instead of this file.
# this file must not be commited into the repository!
credentialsFilePath: .secrets/jira-credentials.txt

Pretty cool, I think. Hopefully, a connector for GitLab will be added soon. January looks super busy for me again, but maybe I can find the time to contribute something...