Environment Doctor
make doctor reports which required tools and repository files are present or missing — a standalone diagnostic, never a prerequisite of other targets.
- Kind
- Contract
- Domain
- Environment & Tooling
- Applies at
scripts/build/- Status
- Stable
01 Defines
A diagnostic target that checks every registered command, file, and custom snippet, prints ok: or missing: for each, and exits non-zero if anything is missing.
02 Applies when
- Someone needs to know whether the environment can run the repository’s commands.
- Several modules each depend on different tools.
- A fresh container or runner needs a quick check before real work starts.
03 Boundaries
- The doctor reports problems; it does not install or fix anything.
- Other targets do not depend on it, and each check fails on its own when a tool is missing.
Expected behaviour
- 01Modules register needs with
DOCTOR_TOOLS,DOCTOR_FILES, andDOCTOR_SNIPPETSinstead of editing the doctor. - 02Every check runs, and all results print, before the exit status is decided.
- 03Each tool is reported with the path it resolved to, or as missing.
- 04A custom snippet is a single shell line in
doctor-snippet-<name>that prints its own result. - 05
make configshows the explicit component lists alongside the diagnostics.
Behaviour#
The Development Container is responsible for provisioning the tools. The doctor is how anyone checks that it did. It walks three registries, reports each entry, and only then exits — with status 1 if anything was missing.
- 01
Tools
command -vfor each sortedDOCTOR_TOOLSentry:ok: <tool> -> <path>ormissing: <tool> - 02
Files
[ -f ]for each sortedDOCTOR_FILESentry - 03
Snippets
Each
doctor-snippet-<name>runs in a subshell and prints its own result - 04 Exit 0 when everything was found; 1 otherwise
The registries are expanded inside the recipe, so registrations from any module
are seen regardless of include order. Each module adds only what it needs, often
conditionally — the Hugo module registers hugo only when the repository
declares a site.
A diagnostic, not a gate#
validate depends on the checks themselves, not on doctor. When a tool is
missing, the check that needs it fails with its own clear error, and the doctor
stays something you run on purpose to see the whole picture.
Examples#
Requirements are registered by the modules that have them:
DOCTOR_FILES += .linter/ignore # 20-doctor.mk
DOCTOR_TOOLS += shellcheck shfmt hadolint actionlint editorconfig-checker codespell # 30-repo.mk
DOCTOR_TOOLS += terraform tflint # 53-terraform.mk
DOCTOR_TOOLS += aws # 81-deploy.mk
An excerpt of the output from a container without the shell linters installed:
missing: actionlint
ok: aws -> /usr/local/bin/aws
missing: codespell
ok: hugo -> /usr/local/hugo/bin/hugo
ok: node -> /usr/local/bin/node
missing: shellcheck
ok: terraform -> /usr/local/bin/terraform
ok: .linter/ignore
Connections