Skip to main content

Scan your codebase for TODO/FIXME/HACK/XXX/BUG comments and use git blame to show how old each one is and who wrote it. Flags tech debt older than N days. CI-friendly, zero dependencies.

Project description

todoage

How old is your tech debt? todoage scans your codebase for TODO / FIXME / HACK / XXX / BUG comments, then uses git blame to show how old each one is and who wrote it — and flags anything that's been rotting longer than your threshold.

Zero dependencies (pure standard library). Zero config. Read-only — it never writes to your repo.

pipx run todoage
AGE   TAG    LOCATION              AUTHOR          TEXT
418d  FIXME  app/auth/session.py:71  Alice Dev       refresh tokens before they expire
402d  TODO   app/billing/charge.py:12  Alice Dev     validate the amount before charging
311d  HACK   app/api/proxy.py:88    Bob Maintainer  works around the upstream 1.4 bug
9d    TODO   app/ui/cart.py:140     Carol           wire up the empty-cart state

summary:  4 markers · 3 older than 90d

The red rows are your stalest debt — the stuff that quietly became permanent.

Why it exists

tickgit (324★) promised exactly this — blame + age tracking for your TODOs — and then went quiet in 2020 having never shipped it. VS Code's todo-tree solves IDE visibility, but there's no small CLI that does the age + author part for a CI report or a Markdown summary.

So that's all todoage is: the missing CLI. It answers one question — which of these TODOs has been here so long it's basically a lie? — and answers it in a way you can drop into a CI gate.

How it works

It walks your tree (skipping .git, node_modules, .venv, dist, build artifacts and obvious binaries), matches comment markers in real comment contexts (#, //, /* */, <!-- -->, --, ;, leading *), and asks git blame for the author and author-date of each matching line. Age is whole days from the commit that introduced the line.

Markers are case-sensitive UPPER, so todomvc and fixme_helper don't trigger false positives — only an actual # TODO does.

Not in a git repo? It still lists every marker; age and author just show as ?.

Install

pipx run todoage           # no install, run on demand
pip install todoage        # or install the `todoage` command

There's an identical Node build too: npx todoage / npm i -g todoage (see todoage). Both ports are tested against the same vectors, so they produce byte-for-byte identical output.

Usage

todoage [path] [options]
Option Description
--max-age <days|90d> Staleness threshold (default 90). Suffixes: d w m y (e.g. 12w, 6m, 1y).
--tags <list> Comma-separated markers to scan for (default TODO,FIXME,HACK,XXX,BUG).
--author <substr> Only items whose blame author contains this substring.
--json Emit compact JSON instead of a table.
--fail-on-stale Exit 1 if any item is stale — a one-line CI gate.
--no-color Disable ANSI color. Also respects NO_COLOR.
-h, --help Show help.
-v, --version Print version.

Exit codes: 0 nothing stale · 1 stale found (with --fail-on-stale) · 2 usage error.

Examples

# fail CI if any TODO is older than a quarter
pipx run todoage --max-age 90d --fail-on-stale

# just the FIXMEs Alice left behind
todoage --tags FIXME --author alice

# feed a dashboard / Markdown summary
todoage --json | jq '.items[] | select(.stale)'

# scan one subtree, tighter threshold
todoage app/ --max-age 30d

Design notes

  • One pure core, two runtimes. scan_line, age_days, and is_stale are pure functions with no I/O, clock, or git — driven by a shared input→output vectors table that the Python and Node suites both run. That's what proves the two ports agree.
  • Age math never touches a datetime. It's integer milliseconds → whole days, so the result is deterministic and identical across languages.
  • Read-only. It blames, it prints, it exits. No state, no cache, no config file, nothing written to your tree.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

todoage-0.1.0.tar.gz (13.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

todoage-0.1.0-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file todoage-0.1.0.tar.gz.

File metadata

  • Download URL: todoage-0.1.0.tar.gz
  • Upload date:
  • Size: 13.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for todoage-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c45f0adea5f402336d3c12779e54c6afbf636f4c11f2f2387d944f50806d2c0d
MD5 5a8283a5696922b9b8bdcc1b008e7b50
BLAKE2b-256 e5bbc6afa541f8652a18d0dc04d0b0d8edba60231be5e5c5136d26e80ea81699

See more details on using hashes here.

File details

Details for the file todoage-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: todoage-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.7

File hashes

Hashes for todoage-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9c1c140452796e04da43f1477113fe30af5a20a913ab3265e83c071923de51b1
MD5 ae0c4a9dfefe5348e1a1a665ec9b9771
BLAKE2b-256 7b23deab8cbeefb367cc33bff315d1384e8d13c12fe5034220907a27aab8fccf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page