ab92a370

By: Tom Sydney Kerckhove <syd@cs-syd.eu>

Suppress a finding, and turn a rule off

Stacked on the envelope. Adds CommentBareTodo from comments.md, and with it the
two things that make a checker adoptable at all.

The keystone is that a suppression which answers for nothing is an error. That
is what makes on-by-default with unlimited local escapes safe: one that has
outlived its finding, one that answers for more than one finding at once, one
naming a rule nothing answers to, one with no reason, and one written where it
cannot attach are all failures in their own right. Suppressions cannot
accumulate in silence, so there is no need for a config file of exceptions
nobody reads.

A suppression the report offers must be one the parser accepts. The report says
what to write and where; if the next run rejected it, the tool would have lied.

Which rules run is a file at the repository root rather than a flag, and there
is no flag anywhere, so the answer cannot differ between a shell and CI. Every
way of getting that file wrong is refused rather than ignored, because each one
reads as a rule turned off and behaves as a rule still running: a key nobody
has heard of, a name that is not a rule id, a rule nothing answers to, and
anything that is not a mapping.

The comment attachment pass is what all of this stands on, and it is computed
here in an explicit pass over spans rather than taken from where exact-print
annotations put a comment. That placement answers "where must this be
reprinted", not "what is this about". The most consequential decision in it: a
blank line between a comment and the code below means the comment is not
attached to that code.

A suppression in a file no cabal component claims is watched by nobody, so it
is reported rather than left to rot.

Still one level, still no fact store, and nothing reads what the compiler wrote
down, because neither rule needs any of it. weeder removed readChoicesFrom on
the way in: the flag it exists for belongs to a command that does not exist
yet.

Its errors are types with renderers, like the envelope's. ChoicesError is the
four things hopinion.yaml can be wrong about, and it no longer carries the path:
the caller has that, and renderChoicesError takes it, so a file read from two
places cannot name itself two ways. AnnotationError is the nine ways a comment
that means to be a suppression is not one, and one of those is that it is not a
suppression at all, which is what every other comment answers. Failure gains
the two kinds this PR introduces: what this repository asked for that is
refused, and why the rules a run was asked for are not a set.

Suite timing

Time to Start Worker time Duration Time to finish Idle
Config 11s 1s 1s 13s 11s
Eval 2m06s 12s 12s 2m19s 1m53s
Build 2m18s 5s 5m51s 8m10s 5m45s
Suite 11s 18s 7m58s 8m10s 7m51s

Timeline

0s2m10s8m10s