Files
werkator/docs/prs/2026-10-05-PR#126-repo-status-line-split.md
miandmhoennig 87d40f34da
werkator build succeeded after 02:20
werkator/deploy build succeeded after 00:09
werkator/mutation build failed after 66:07
The Repositories page's status line split by status, gate at the target of 15 (v1.37.7) (#126)
> Historic PR-documentation is not maintained along with new PRs — treat it as a snapshot, not as current documentation.

## The Problem

`UiFormats.repoStatusLine` is the last method above the Kotlin target of 15:

| Method                     | Mutation-CRAP | Complexity | Mutation score |
|----------------------------|---------------|------------|----------------|
| `UiFormats.repoStatusLine` | 16.03         | 16         | 0.95           |

It words the second line of a Repositories page entry for a running, a pending and a finished newest build in one method.
Its complexity alone is above 15, so tests cannot bring it down; it needs the split.

## Non-Goals

- No change in behaviour: every line reads as before, and `werkator.js` (`repoStatusLine`) is untouched.

## The Scenarios

### Feature: the status line names what there is

#### Scenario#126.01: the status line names only what there is

So that a line never ends in a separator or names a count of zero.

- **Given** a pending newest build with no other build running
- **Then** the line reads `waiting 2:14`
- **Given** a running newest build with no other build pending
- **Then** the line reads `running for 2:14`
- **Given** a finished build with a permalink and no artifact
- **Then** the line reads `4:51 · permalink`
- **Given** a finished build with an artifact and no duration
- **Then** the line reads `artifact`

##### Verified by

- [UiViewsUnitTest](../../src/test/kotlin/de/hoennig/werkator/server/UiViewsUnitTest.kt) `the status line names only what there is: no other builds, no duration, no artifact (Scenario#126.01)`, and `the status line says what the newest build's status means in numbers (Scenario#37.02)`

## The Solution

`repoStatusLine` picks the line by the newest build's status:

- `activeLine` words a running and a pending build alike: how long it has been at it, and the builds of the other kind beside it;
- `finishedLine` words the duration and what the build left.

This follows the shape of the script's `repoStatusLine`, which already handles the two active states alike.

A local PIT run of `UiFormats` afterwards:

| Method                     | Mutation-CRAP | Complexity | Mutation score |
|----------------------------|---------------|------------|----------------|
| `UiFormats.repoStatusLine` | 5             | 5          | 1.00           |
| `UiFormats.activeLine`     | 3             | 3          | 1.00           |
| `UiFormats.finishedLine`   | 10            | 10         | 1.00           |

The highest score left in `UiFormats` is `swapLevel` at 12.05.
No method of the project is above 15 any more; the highest is `ConfigLoader.checkRestartsInstance` at exactly 15.00, with complexity 15 and every mutant killed.
So the gate goes down from 17 to the target of 15.
The gate refuses a method that exceeds the limit, so 15.00 passes; but a single surviving mutant in `checkRestartsInstance` would now fail the nightly build.

## Additional Changes

- `maxMutationCrap` in `build.gradle.kts` lowered from 17 to 15, and its comment says the ratchet has reached the target.
- Version 1.37.7 with its entry in `releases.html`.

## Prerequisite PRs

- PR#104: the target of 15 and the first gate.
- PR#111 to PR#125: the refactorings that brought the gate down from 35.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: mhoennig <michael@hoennig.de>
Reviewed-on: #126
2026-10-05 20:19:38 +02:00

3.5 KiB

PR#126: The Repositories Page's Status Line Split by Status

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

UiFormats.repoStatusLine is the last method above the Kotlin target of 15:

Method Mutation-CRAP Complexity Mutation score
UiFormats.repoStatusLine 16.03 16 0.95

It words the second line of a Repositories page entry for a running, a pending and a finished newest build in one method. Its complexity alone is above 15, so tests cannot bring it down; it needs the split.

Non-Goals

  • No change in behaviour: every line reads as before, and werkator.js (repoStatusLine) is untouched.

The Scenarios

Feature: the status line names what there is

Scenario#126.01: the status line names only what there is

So that a line never ends in a separator or names a count of zero.

  • Given a pending newest build with no other build running
  • Then the line reads waiting 2:14
  • Given a running newest build with no other build pending
  • Then the line reads running for 2:14
  • Given a finished build with a permalink and no artifact
  • Then the line reads 4:51 · permalink
  • Given a finished build with an artifact and no duration
  • Then the line reads artifact
Verified by
  • UiViewsUnitTest the status line names only what there is: no other builds, no duration, no artifact (Scenario#126.01), and the status line says what the newest build's status means in numbers (Scenario#37.02)

The Solution

repoStatusLine picks the line by the newest build's status:

  • activeLine words a running and a pending build alike: how long it has been at it, and the builds of the other kind beside it;
  • finishedLine words the duration and what the build left.

This follows the shape of the script's repoStatusLine, which already handles the two active states alike.

A local PIT run of UiFormats afterwards:

Method Mutation-CRAP Complexity Mutation score
UiFormats.repoStatusLine 5 5 1.00
UiFormats.activeLine 3 3 1.00
UiFormats.finishedLine 10 10 1.00

The highest score left in UiFormats is swapLevel at 12.05. No method of the project is above 15 any more; the highest is ConfigLoader.checkRestartsInstance at exactly 15.00, with complexity 15 and every mutant killed. So the gate goes down from 17 to the target of 15. The gate refuses a method that exceeds the limit, so 15.00 passes; but a single surviving mutant in checkRestartsInstance would now fail the nightly build.

Additional Changes

  • maxMutationCrap in build.gradle.kts lowered from 17 to 15, and its comment says the ratchet has reached the target.
  • Version 1.37.7 with its entry in releases.html.

Prerequisite PRs

  • PR#104: the target of 15 and the first gate.
  • PR#111 to PR#125: the refactorings that brought the gate down from 35.

🤖 Generated with Claude Code