Skip to content

tests/test_repo_hygiene.py: the one-line-install check offers the exclusion set only to a .md in the notes directory that is no release's v*.md, a test reads its message, and every line of the release notes that runs the install holds the one line, with nothing or the pinned version after it (#931) - #959

Merged
brettheap merged 4 commits into
mainfrom
fix/931-one-line-install-message
Oct 18, 2026

Conversation

@brettheap

@brettheap brettheap commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Lane: openreposhape-1 (openRepoShape-1)
Claim: #931 (comment)

A v1.2.0 draft on main 64464d31. It follows #887 (#885), whose head lane 5 found READY with three NITs. Those NITs are #931. It changes tests/test_repo_hygiene.py only.

What

  1. The message offers the exclusion set only where it works.
    • The failure text is now a module-level _one_line_install_failure(name).
    • Its "or, if it is not a release's notes, name 'X' in RELEASE_NOTES_WITHOUT_THE_ONE_LINE_INSTALL" clause goes only to a .md in docs/release-notes/ whose name does not match v*.md, on its own line after the indented install line.
    • Before, a mistyped line in a release's own notes (mutant M5) was told to name the file in the set, which the second test then refuses.
    • The comment above the set now says "a v*.md other than v1.0.0.md named here fails the second test below".
  2. A test reads the message. test_the_one_line_install_message_offers_the_set_only_where_it_works asks it for docs/release-notes/v9.9.9.md, docs/release-notes/README.md and README.md. It holds that:
    • the install line is in all three;
    • the clause is in the second alone;
    • the line comes before the clause.
  3. Every line of the notes that runs the install carries the one line. test_every_release_notes_line_that_installs_holds_the_one_line_install reads every v*.md but v1.0.0.md.
    • A line holding both curl and download/install.sh must contain ONE_LINE_INSTALL.
    • What follows it must be nothing, or the pinned form -s -- v<major>.<minor>.<patch>, which is install.sh's own usage, with only a closing backtick and punctuation after it.
    • Each failure names the file, the line number and the line.
    • The test also holds a count per file (v1.0.1.md at least 2, the others at least 1), so a rule that matches nothing fails.

M10. Lane 5 left it open whether to hold the text after the line. This takes the pinned form, measured first: the four lines today (v1.0.1.md:12 and :45, v1.1.0.md:49, v1.1.1.md:132) all match it, and | bash -s -- --yes or -s -- main does not.

Mutants

Round 1, at a6597405, run with -k one_line_install (11 tests then):

Mutant Change Result
M1 | bsh at v1.1.0.md:49 caught
M5 | bsh at v1.1.1.md:132 caught, and its message has no clause
M6 v1.1.1.md added to the set caught
M7 | bsh at v1.0.1.md:12 caught (new)
M8 a scratch docs/release-notes/README.md caught, and its message has the clause
M10 | bash -s -- --yes at v1.1.1.md:132 caught (new)
X3 the message's if comparison turned around caught (new)
X3b, X3c, X4, X5 the clause's condition broken four more ways caught
X6 the rule's curl test made to match nothing caught
-s -- main at v1.0.1.md:45 caught

Rounds 2 and 3 (a1649ef6, daf0376d), from r959's NITs:

Tests

Run with /usr/bin/python3 -m pytest, a stub gh first on PATH, a bogus GH_TOKEN, an empty GH_CONFIG_DIR, GIT_CONFIG_GLOBAL=/dev/null and GIT_SSH_COMMAND=false, on main 64464d31:

  • tests/test_repo_hygiene.py, tests/test_release_workflow.py and tests/test_workflow_concurrency.py: 170 passed at daf0376d (151 before);
  • -k one_line_install: 28 passed at daf0376d (9 before).

No added line is over 79 columns, the change is ASCII, and there is no compound assert.

Known limit: the version in the pinned form is not read, so -s -- v9.9.9 passes in any release's notes.

Written by lane 1's writer w931 on #887's head 96422b98, then cherry-picked onto main once #887 landed. The patch-id is unchanged.

Closes #931

🤖 Generated with Claude Code

Summary by Sourcery

Strengthen repository hygiene checks for one-line installation commands and ensure their failure guidance is accurate and actionable.

Bug Fixes:

  • Prevent release-note hygiene failures from suggesting an exclusion-list workaround that the same test rejects.
  • Detect mistyped or malformed one-line install commands on every applicable release-notes line, including invalid trailing arguments.

Enhancements:

  • Add focused validation of failure-message guidance and accepted install-command suffixes.
  • Require release notes to contain the expected minimum number of install-command examples so the hygiene rule cannot pass without matching any lines.

Tests:

  • Expand repository hygiene tests to cover message guidance, valid and invalid command endings, typo detection, and per-line release-note validation.

…t in RELEASE_NOTES_WITHOUT_THE_ONE_LINE_INSTALL" only to a `.md` in the notes directory that is no release's `v*.md`, after the install line, a test reads the message for a release's notes, another `.md` there and a file elsewhere, and every line of the release notes that holds both `curl` and `download/install.sh` holds the one line and, after it, nothing or the pinned form (#931)

The message. A mistyped copy in a release's own notes (`| bsh` at
v1.1.1.md:132) was told to name itself in the set, which the second test
refuses. The `or, if it is not a release's notes, name ... in
RELEASE_NOTES_WITHOUT_THE_ONE_LINE_INSTALL` clause now goes only to a file
in docs/release-notes/ whose name does not match `v*.md`, and it follows the
indented install line, so it no longer reads as part of the line. The comment
above the set says a `v*.md` other than v1.0.0.md named there fails the
second test.

A test reads the message. It is a module-level
`_one_line_install_failure(name)` now, which the parametrised test uses, and
`test_the_one_line_install_message_offers_the_set_only_where_it_works` calls
it for docs/release-notes/v9.9.9.md, docs/release-notes/README.md and
README.md. The install line is in all three, the clause in the second alone
and after the line. Turning the `if` around, or dropping either half of its
condition, now fails a test.

Every line that runs the install. The new
`test_every_release_notes_line_that_installs_holds_the_one_line_install`
reads every `v*.md` but v1.0.0.md. A line with both `curl` and
`download/install.sh` must hold the one line, and what follows it must be
nothing or ` -s -- v<major>.<minor>.<patch>`, then only a closing backtick,
punctuation and blanks. Each failure names the file, the line number and the
line. The rule picks 4 lines today (v1.0.1.md:12 and :45, v1.1.0.md:49,
v1.1.1.md:132) and passes on all 4, and the test asks for at least those per
file (2, 1, 1) so a rule that matches nothing cannot pass; the counts are per
file, not per line number, so an edit above a line does not fail it. M10 is
held by the pinned-form rule (choice (a)): it passes today on all 4 lines and
catches M10 with no list of special cases. What it does not read is the
version in the pinned form, so ` -s -- v9.9.9` passes in any notes.

Mutants, each made by hand, run with `-k one_line_install` (11 tests), and
restored; the ones that edit the test file were restored from a copy and
compared with `cmp`.

| Mutant | Change | Result |
|---|---|---|
| M1 | `\| bsh` at v1.1.0.md:49 | caught (2 failed) |
| M5 | `\| bsh` at v1.1.1.md:132 | caught (2 failed), message has no `or` clause |
| M6 | v1.1.1.md added to the set | caught (1 failed) |
| M7 | `\| bsh` at v1.0.1.md:12 | caught (1 failed, new test only) |
| M8 | scratch docs/release-notes/README.md | caught (1 failed), message has the clause |
| M10 | `\| bash -s -- --yes` at v1.1.1.md:132 | caught (1 failed, new test only) |
| X3 | `if path.parent == RELEASE_NOTES` turned to `!=` | caught (1 failed, new test) |
| X3b | `not path.match("v*.md")` turned to `path.match("v*.md")` | caught (1 failed, new test) |
| X3c | the clause never offered | caught (1 failed, new test) |
| X4 | the clause offered to every file | caught (1 failed, new test) |
| X6 | the rule's `curl` test matches nothing | caught (1 failed, new test) |
| extra | `-s -- main` at v1.0.1.md:45 | caught (1 failed, new test only) |

Tests: tests/test_repo_hygiene.py + tests/test_release_workflow.py +
tests/test_workflow_concurrency.py 153 passed (151 at the base, +2);
`-k one_line_install` 11 passed (9 at the base). Tests only: no tool and no
notes change.

Lane: openreposhape-1 (openRepoShape-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@brettheap brettheap added this to the v1.2.0 milestone Oct 18, 2026
@sourcery-ai

sourcery-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR hardens one-line-install hygiene tests by making failure guidance context-aware and adding mutation-resistant checks that every executable release-note install line contains the exact command with only an allowed pinned suffix.

File-Level Changes

Change Details Files
Centralize and correct the one-line-install failure guidance so the exclusion set is suggested only for eligible non-release notes.
  • Added a reusable failure-message builder with conditional exclusion guidance.
  • Updated the exclusion-set comment and migrated the existing test to use the builder.
  • Added coverage for release-note, non-release-note, and outside-directory message variants and clause ordering.
tests/test_repo_hygiene.py
Strengthen release-note hygiene checks to validate every executable install line, including permitted pinned arguments.
  • Scan all applicable v*.md files and identify lines containing both curl and download/install.sh.
  • Require the canonical install command on each matching line and restrict trailing text to the pinned version form or punctuation.
  • Report file, line number, and source line for violations, while enforcing per-file minimum match counts to prevent vacuous passes.
tests/test_repo_hygiene.py

Assessment against linked issues

Issue Objective Addressed Explanation
#931 Offer the exclusion-set remedy only for Markdown files in the release-notes directory whose names are not release-style v*.md, and place it after the required install line in the failure message. ✅
#931 Add a test that reads the failure message and verifies the exclusion-set clause appears only for an eligible non-release notes file, with the install line preceding it. ✅
#931 Check every release-notes line that runs the install so it contains the exact one-line install, catching mistyped copies even when another correct copy exists; constrain any trailing text to the permitted pinned-version form. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

…s tested on its own, so a looser pinned-form rule fails, a `v` inside a name is no release's `v*.md`, and a failing count says what it found and wanted (#931)

The review of #959 found the pinned-form rule's rejecting side had no case of
its own: the notes pass today, so a regex loosened to ` -s -- .*` or `.*`, to
`v[\d.]+`, a `match` for the `fullmatch`, or the "does not hold the line"
branch turned off passed every test.

- `_one_line_install_fault(line)` returns "" or the reason, and the loop uses
  it. Three tests hold it: the tails the notes end the line with, the tails
  they may not, and a mistyped line (`| bsh`).
- The message test asks for `docs/release-notes/draft-v1.2.0.md`, so a name
  that merely holds a `v` is told it may be named in the set.
- The docstrings say "other than v1.0.0.md", the comment names the six
  characters the regex allows after the line, "that test" names the test, and
  the count assert says what was found and what was wanted.

Lane: openreposhape-1 (openRepoShape-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@brettheap

brettheap commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor Author

(lane openRepoShape-1, 2026-10-18T17:58:24Z) Independent review of #959 at a6597405, by lane 1's reviewer r959 (sonnet), who is not its writer: READY, with no MUST and no SHOULD. Lane 1 makes its three NITs before marking the PR ready.

  • tests/test_repo_hygiene.py: the one-line-install check offers its exclusion set to a release's own notes, which the second test refuses, no test reads its message, and two mistyped copies still pass (follow-up to #887) #931's three points hold.

    1. The clause goes to a .md in docs/release-notes/ that does not match v*.md, and to no other file. It sits on its own line after the install line. With "README.md" added to the set, the 11 tests pass, so the clause's advice works.
    2. A test reads the message, for v9.9.9.md, a README.md in the notes directory and the root README.md. Every variant of the clause's condition that r959 broke was caught (X3, X3b, X3c, X3d).
    3. Every notes line: the rule picks exactly four lines (v1.0.1.md:12 and :45, v1.1.0.md:49, v1.1.1.md:132), and all pass. | bsh at each of them, -s -- --yes and -s -- main are all caught, and the message gives the file, the line number and the line.
  • Tests: the three files (test_repo_hygiene.py, test_release_workflow.py, test_workflow_concurrency.py): 153 passed, against 151 with main's file. -k one_line_install: 11 passed.

  • NIT 1: the pinned-form rule's rejecting side has no case of its own. All five of these survive:

    • Y1, the regex loosened to -s -- .*;
    • Y1c and Y1d;
    • Y4, fullmatch changed to match;
    • Y5, the "does not hold the line" branch switched off.

    The fix r959 tried is a per-line _one_line_install_fault(line), with tests of accepted tails, rejected tails and bsh. It gives 24 passed and kills all five.

  • NIT 2: the v*.md boundary is tested by one stray name only, so a "contains v" test (Y3, Y3e) survives. Fix: assert the clause for docs/release-notes/draft-v1.2.0.md.

  • NIT 3, wording:

    • "a release's v*.md" does not say "other than v1.0.0.md";
    • it says "punctuation" where the regex allows six characters;
    • one antecedent is unclear;
    • a bare assert all(...) prints a dict and assert False.
  • Known limit, not a defect: the rule fails, with a clear message, on prose after the closing backtick on the install line's own line, and on a one-line curl ... download/install.sh -o install.sh. Today's verify blocks avoid it by wrapping.

Lane 1's writer w959n has made NITs 1 to 3 at a1649ef6.

  • -k one_line_install: 24 passed. The three files: 166 passed.
  • Y1, Y1c, Y1d, Y4, Y5, Y3 and Y3e now each fail.

r959 re-checks that head now. Then lane 1 marks #959 ready and gates it.

Lane: openreposhape-1 (openRepoShape-1)

…lude `;`, `:`, `)` and a pinned form of two-digit parts, so a trailing class that drops one of them or a `\d` for the `\d+` fails, and the message test's docstring says what the name's form separates (#931)

The re-check of #959 named two things left.

- The accepted-tail list held no case for three of the six characters the
  trailing class allows, so a class without `;`, `:` or `)` passed, and none
  for a pinned form longer than one digit a part, so `\d` for `\d+` passed.
  The list now has `;`, `:`, `)` and ` -s -- v10.20.30`.
- "The line between them" had no antecedent. It now reads "The line between
  a release's notes and any other `.md` there is the name's form".

Lane: openreposhape-1 (openRepoShape-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@brettheap

Copy link
Copy Markdown
Contributor Author

(lane openRepoShape-1, 2026-10-18T18:03:14Z) Re-check of #959 at daf0376d, by r959 (sonnet), who is not its writer: READY, with no MUST, SHOULD or NIT left.

  • Round 2 (a1649ef6) made NITs 1 to 3:

    • the per-line verdict, _one_line_install_fault(line), with tests of its own;
    • the stray draft-v1.2.0.md;
    • the wording.

    All seven mutants that had survived (Y1, Y1c, Y1d, Y4, Y5, Y3, Y3e) now fail.

  • Round 3 (daf0376d) makes r959's last two asks:

    • The accepted tails gain ;, :, ) and -s -- v10.20.30. So a trailing class that drops one of them fails, as does \d in place of \d+.
    • The docstring's antecedent is fixed.
  • Tests: -k one_line_install: 28 passed. The three files: 170 passed.

  • Style: the widest line is 79 columns, the text is ASCII only, and git diff --check is clean.

Lane 1 marks #959 ready for review now. Once its tests are green, lane 1 asks for a turn, gated over main as it then stands.

Lane: openreposhape-1 (openRepoShape-1)

@brettheap
brettheap marked this pull request as ready for review October 18, 2026 18:03
@sourcery-ai

sourcery-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 6 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sonarqubecloud

Copy link
Copy Markdown

@brettheap
brettheap merged commit 66177b6 into main Oct 18, 2026
5 checks passed
@brettheap
brettheap deleted the fix/931-one-line-install-message branch October 18, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant