First Mutation-CRAP refactoring. - `HomeNewestBuildView` / `RepoNewestBuildView` decide once whether a repository has built; card and entry read `newest.*`. - `UiFormats.runningTag` / `failedTag`: one wording of activity. - Tests for every card field, tint and counter. - Local PIT: HomeCardView.from 224 -> C 1, HomeTexts.meta 66 -> 3.2, RepoOverviewView.from 18 -> 2, toneOf 18 -> 5. - AGENTS.md: 15 hard limit, red from 12 an urgent warning. - Ratchet stays at 650 (BuildExecutor.execute is still the max). PR-doc: `docs/prs/2026-10-04-PR#105-home-card-newest-build.md` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: mhoennig <michael@hoennig.de> Reviewed-on: #105
5.1 KiB
WARNING: This document describes only the change applied in this PR. It may already be outdated once the next PR is merged. Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.
The Problem
The first full Mutation-CRAP report (PR#104) put the home page's repository card second and third:
| Method | Mutation-CRAP | Complexity | Killed / eligible |
|---|---|---|---|
HomeCardView.from |
224.48 | 21 | 5 / 22 |
HomeTexts.meta |
65.89 | 9 | 2 / 18 |
RepoOverviewView.from |
18.00 | 18 | 17 / 18 |
HomeCardView.toneOf |
17.79 | 5 | 1 / 5 |
Two causes, both of the card's own making.
Seven fields each asked whether the repository has a newest build at all (entry.newest?.…), and every ?. is a branch, so a card that only copies fields reached a complexity of 21.
And almost nothing tested the card: one test looked at its pull request.
The Repositories page's entry had the same seven questions, and the words "N running" and "N failed" were written out in five places.
Non-Goals
- No change for users: every card and every entry reads as before.
- The ratchet stays at 650:
BuildExecutor.execute(647.55) is still the highest score; its PR lowers it.
The Scenarios
Feature: The home page's repository card
Scenario#105.01: A card says which repository, how it is doing, what it built last, and how its builds went
So that every field the reader sees is held by a test.
- Given a repository with a failed newest build, two running builds, three recent failures and two recent builds
- When its card is made
- Then it carries the name, link, status, build count, both tags, the newest build's branch, commit, duration and start, and the bar strip
Verified by
- UiViewsUnitTest — Scenario#105.01
Scenario#105.02: A card before the first build says unknown and nothing else about a build
So that "no build yet" is one case, decided once.
- Given a repository that never built
- When its card is made
- Then its status is
unknown, its newest build is the empty one, it has no tags and no tint, and its strip is empty
Verified by
- UiViewsUnitTest — Scenario#105.02
Scenario#105.03: A card's tint: private before failed before running
So that a private repository never lights up, and a failure outweighs activity.
- Given cards quiet, running, running with a failure, and private with both
- When their tint is decided
- Then it is none,
run,bad, andghost
Verified by
- UiViewsUnitTest — Scenario#105.03
Scenario#105.04: The counter over the cards counts running builds and cards with a recent failure
So that the counter and the cards use the same words, and the difference between summing builds and counting cards is held.
- Given sets of cards with and without running builds and recent failures
- When the counter is written
- Then running builds are summed, failing cards are counted, and nothing is written for a quiet page
Verified by
- UiViewsUnitTest — Scenario#105.04
The Solution
- A card is made of three parts, as the reader takes it in: which repository and how it is doing, what it built last, and how its recent builds went.
HomeNewestBuildViewholds what the card says about the newest build;ofdecides once whether there is one, andNONEis the card of a repository that has not built. The card'sstatuscomes from it.RepoNewestBuildViewdoes the same for the Repositories page, with the pull request as a link and the longer commit.UiFormats.runningTagandfailedTagare the one wording of activity, used by the card, the counter and the Repositories page.home.htmlandrepos.htmlread the newest build throughcard.newestandentry.newest.
Measured with PIT on these classes:
| Method | Before | After |
|---|---|---|
HomeCardView.from |
224.48 | complexity 1, no mutant |
HomeNewestBuildView.of |
— | 5 (5 / 5 killed) |
HomeCardView.toneOf |
17.79 | 5 (5 / 5 killed) |
HomeTexts.meta |
65.89 | 3.24 |
RepoOverviewView.from |
18.00 | 2 |
RepoNewestBuildView.of |
— | 2 |
Additional Changes
AGENTS.mdwords the limits as meant: 15 is the hard limit, red from 12 an urgent warning; PR#104 had made 12 a limit for every new or changed method.- Version 1.34.2 with its release note.
Follow-up PRs
BuildExecutor.execute, split into the admission, the run and the settlement of a build; it lowers the ratchet.