Java Guild course · The Rebuild

Reference · the whole submission, commit by commit

The Rebuild

Thirty-one commits from the starter project to the finished submission. Each one is a single idea, each one builds and passes, and each decision is recorded in an ADR at the moment it was taken.

How each commit is written up

Not a diff to interpret — a numbered list to work through:

  1. Why — the defect or the pressure that makes this commit necessary.
  2. The edits — every file to create, given in full; every file to change, given as find this exact text / replace it with this. The “find” block is the code as it stands after the previous commit.
  3. Re-approve — where behaviour changed, with the diff command to read before you accept it.
  4. Verify — mvn clean test, and the exact test count you should see.
  5. Commit — the full message as a copy-pasteable heredoc.
Every step here was executed and verified

This is not a plan. The sequence was built end to end against the real starter project, and all 31 commits were checked out one at a time and built clean — mvn clean test, 31 for 31, no failures. The test counts in the tables below are the real ones.

Every step on these pages is generated from that repository, so the instructions and the code cannot drift apart.

The shape of it

Five phases. The order is the whole argument: you cannot safely change code whose behaviour you have not written down, so the first eleven commits add no production code at all.

The rules this history follows

Rules

Setup

cd ~/Desktop/java-guild-candidate-test-intermediate-main
git init -b main
git config user.name  "Tom Spencer"
git config user.email "tomspencerlondon@gmail.com"

export JAVA_HOME=$(/usr/libexec/java_home -v 25)
alias mvn=~/.local/maven/bin/mvn

All thirty-one

Phase 1 · Baseline and build hygiene
1choreadd the starter project exactly as supplied
2buildreplace the placeholder groupId
3buildcompile with --release 11
4buildadd a Maven wrapper pinned to 3.9.16
5choreignore the state file the application writes
Phase 2 · The safety net
6testpin the add-and-list journey with a golden master
7testextend the golden master to every menu option
8testextend the golden master across a restart
9testextend the golden master to unparseable menu input
10testcharacterise Book
11testcharacterise the library as a collection of books
Phase 3 · Exceptions and the domain API
12fixreport a failed borrow or return instead of crashing
13refactorgive the domain exceptions a common supertype
14fixsignal a missing book with BookNotFoundException
15fixdistinguish an already-borrowed book from a missing one
16fixdistinguish a book that was never borrowed from a missing one
17refactordrop the boolean returns no caller can act on
18refactorreturn Optional from searchBook
19refactorderive borrow and return from a shared requireBook
Phase 4 · Persistence and structure
20fixstop a separator in a title from corrupting the saved file
21fixreport a truncated state file instead of crashing on an index
22fixkeep the library intact when the state file will not parse
23fixraise LibraryStorageException from save and load
24refactorextract LibraryRepository from Library
25refactormove the domain types into a domain package
Phase 5 · The console, and the write-up
26refactorextract LibraryConsole from Main
27testdrive the console through its injected streams
28refactorreplace the menu constants with a MenuOption enum
29fixkeep serving the user when the menu choice is not a number
30docscorrect a stale cross-reference in ADR 0006
31docsdocument the approach, decisions and deviations

The decisions

Eight ADRs, each committed with the change it justifies. Read them in full →