Skip to main content

todo-linter

Ensure to-do items in your code have an owner and an issue.

This is inspired by the todo_linter.py I wrote several years ago for ISARA.

todo-linter searches for various "TODO" tags in the given files, and complains if they don't include an owner and a reference to an issue or task describing the deferred work:

// TODO(chrish@pobox.com https://worktree.ca/taffer/todo-linter/issues/1): a short
// description

or:

# TODO(chrish@pobox.com https://worktree.ca/taffer/todo-linter/issues/1): a short
# description

or:

<!--
TODO(chrish@pobox.com https://worktree.ca/taffer/todo-linter/issues/1): a short
description
-->

The idea here is that future you, or someone else, will know where to get more context for the task, so they can actually address it at some point. The linter makes no attempt to verify the user email or the issue URL, so these can be whatever makes sense for your project.

You can run todo-linter against any file, as long as it's valid UTF-8.

To-do items

By default, todo-linter looks lines containing these tags: TODO, FIXME, XXX, followed by a user identifier, space, and URL inside of parentheses.

You can adjust these with the --delimiter, --issue-reference, --todo-tags, and --user-identifier arguments:

  • --delimiter - Character to use as a delimiter between the user identifier and the issue reference. Defaults to space.
  • --issue-reference - One of these values, such as --issue-reference url:
    • number - An issue number in your repo, such as #14. This is nice and short, but doesn't provide a clickable link like url does.
    • other - Free-form.
    • unsafe-url - Like url but for http://hostname/path type strings.
    • url - Matches https://hostname/path type strings.
  • --todo-tags - A comma-separated list of to-do tags, such as --todo-tags To-do or --todo-tags TODO,FIXME,XXX (the default).
  • --user-identifier - One of these values, such as --user-identifier email:
    • at-tag - Matches @user type strings, frequently found in Discord, Mastodon, Mattermost, Slack, etc.
    • bare - Matches any user.
    • email - Matches user@hostname type strings. (Default)

Again, todo-linter doesn't validate issue references or user identifiers.

You can also set these in a .todo-linter.toml file in the current directory (or anywhere is you use the --config argument).

Ignoring problems

You can tell todo-linter to ignore an invalid to-do item by adding an inline comment with todo-linter: ignore:

// I don't want to correct my linter errors:
//
// TODO: I hate writing real TODO items. todo-linter: ignore
# This one isn't actually an error:
#
# This is a big TODO. todo-linter: ignore

You can disable (and re-enable) the linter for larger blocks (or entire files) using todo-linter: disable and todo-linter: enable comments:

# todo-linter: disable
#
# Any TODO, FIXME, XXX, etc. in this block will be ignored by the linter.
# You can put todo-linter: disable at the top of a file to exclude it entirely.
#
# Use this to reactivate the linter:
#
# todo-linter: enable

Because todo-linter isn't parsing your code at all, these can appear anywhere in your comments (or even your code if that's your thing).

If it comes up, todo-linter: ignore takes precedent over disable/enable.

Installation

If you're using todo-linter with pre-commit, you can skip this.

To install todo-linter, use pipx:

$ pipx install todo-linter
  installed package todo-linter 1.0.10, installed using Python 3.14.6
  These apps are now available
    - todo-linter
done! ✨ 🌟 ✨

Using it with pre-commit

pre-commit is handy, you should try it!

To use todo-linter with your project, add this - repo stanza to your .pre-commit-config.yaml's repos: section:

repos:
  - repo: https://worktree.ca/taffer/todo-linter
    rev: {release}
    hooks:
      - id: todo-linter

Where {release} is the version tag you want to use, such as v1.0.10 or a commit hash.

Credits

Repo icon by Delapoutie on game-icons.net, licensed under the Creative Commons BY 3.0 license.

License

todo-linter is Creative Commons BY-NC-SA 4.0; see LICENSE.md for details.

No, you cannot train your LLM on this repo. Yes, I know you're going to ignore that, you slop-generating scum.

Metadata

Release files for todo-linter 1.0.11

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for todo-linter 1.0.11
File Size Uploaded
todo_linter-1.0.11.tar.gz 14.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for todo-linter 1.0.11
File Interpreter ABI Platform
todo_linter-1.0.11-py3-none-any.whl Python 3 none any Details

Total release size: 27.7 kB

Release files / todo_linter-1.0.11.tar.gz

Download URL todo_linter-1.0.11.tar.gz
Size 14.4 kB
Tags Source
SHA-256 checksum
How to use checksums
7bcc1596fc62f3fbe5fcd4d162e4461f92b4476fcc07c6d01830670eec350c2e
BLAKE2b-256 checksum
How to use checksums
e0e3850e8faeb8342c71bea2694df428a7eaade384f970f98637a04e2f8e383a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / todo_linter-1.0.11-py3-none-any.whl

Download URL todo_linter-1.0.11-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c65bca0dd06a37c022f9585bde972f13475b64cc8eb95a8600c4223a8eb35e23
BLAKE2b-256 checksum
How to use checksums
182989d8ecd74884963c940675e63d32e473ede615a5870c21249dde4f7a0215
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"EndeavourOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.0.11 This release

2 release files

1.0.10

2 release files

1.0.9

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page