Jelmer Vernooij: Remove-after Annotations for Debian Files
deb-scrub-obsolete is a tool in the debian-codemods suite that tries to
identify and remove cruft automatically. It knows about dummy
transitional packages, superseded alternatives, and similar patterns it can
detect by querying the archive. But some workarounds are too
project-specific for a generic tool to recognise on its own.
Developers can leave structured comments in their packaging files that tell
deb-scrub-obsolete when a particular line or block can be removed.
The Debian Janitor regularly
runs various codemods like deb-scrub-obsolete on all
vcs-accessible Debian packages. This means that if you
leave a “remove-after: trixie” annotation in your package, you will
automatically get a pull request to remove the annotated code once trixie has
been released, without needing to remember to do it yourself.
The Comment Format
The annotations take the form of specially-formatted comments. For shell files
(and by extension most maintainer scripts), a line-level annotation looks like this:
install -m 755 compat-wrapper /usr/lib/foo/ # remove-after: trixie
When trixie has been released, deb-scrub-obsolete will remove that line
entirely. The comment can appear anywhere on the line — before or after other
comments — and additional explanatory text can follow:
blah # Trixie comes with blah built in # remove-after: trixie
For larger sections, block-level annotations bracket the code to remove:
# begin-remove-after: trixie alternatives --add foo bar alternatives --add foo bar1 # end-remove-after
These blocks can be nested, which is useful when one outer condition wraps
several inner ones with finer-grained timing.
Expressions
The initial set of supported expressions is deliberately small. The main one
is a Debian release name: remove-after: trixie means “once trixie has
been released”. The condition is checked against distro-info <https://manpages.debian.org/trixie/distro-info/distro-info.1.en.html>_, the same data
source that other Debian tooling uses to track release status.
The expression language is designed to be monotonic — conditions should only
ever go from false to true, not back. A workaround that needs to be
re-introduced after removal belongs in a new commit, not in an annotation. If
deb-scrub-obsolete cannot parse an annotation it finds in a file, it
leaves all annotations in that file untouched, to avoid a situation where
related blocks are only partially removed.
Annotations can also carry a marker name — an arbitrary label with no spaces,
commas, or the word “after” — which can then be passed to
deb-scrub-obsolete on the command line. This makes it possible to trigger
removal of a named set of annotations together, useful for coordinated
transitions where several packages need to be cleaned up at the same time.
Future Extensions
The initial expression set is minimal; the design leaves room for richer
conditions. Some candidates under consideration:
- Whether a particular suite has a new enough version of a package (removing
a Build-Depends version constraint once it is satisfied everywhere) - Whether a package has been removed from the archive
- Whether all currently-supported releases contain a new enough version
- Whether a Debian transition
has completed
Compound expressions using “and” / “or” are also on the list, for cases where
removal depends on multiple conditions being true simultaneously.
Status
The annotation format is specified but not yet implemented in
deb-scrub-obsolete – it is planned for a future release. If you maintain
Debian packages and have opinions on the annotation format or the expression
language, feedback is welcome. The specification lives in
scrub-obsolete/doc/scrub-annotations.md
in the lintian-brush repository. Many thanks to Helmut Grohne for the initial
suggestion and feedback on the design.




