Contract specification

Environment Doctor

make doctor reports which required tools and repository files are present or missing — a standalone diagnostic, never a prerequisite of other targets.

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

  1. 01
    Modules register needs with DOCTOR_TOOLS, DOCTOR_FILES, and DOCTOR_SNIPPETS instead of editing the doctor.
  2. 02
    Every check runs, and all results print, before the exit status is decided.
  3. 03
    Each tool is reported with the path it resolved to, or as missing.
  4. 04
    A custom snippet is a single shell line in doctor-snippet-<name> that prints its own result.
  5. 05
    make config shows 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.

Flowmake doctor
  1. 01 Tools command -v for each sorted DOCTOR_TOOLS entry: ok: <tool> -> <path> or missing: <tool>
  2. 02 Files [ -f ] for each sorted DOCTOR_FILES entry
  3. 03 Snippets Each doctor-snippet-<name> runs in a subshell and prints its own result
  4. 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