Imported from ysoftwareab/sane.mk (
SKILL.md). Install upstream withnpx skills add ysoftwareab/sane.mk. Copyright stays with the author.
sane.mk
Quick model
- Choose the smallest entrypoint:
sane.mk,sane.std.mk,sane.extra.mk, ortemplate/sane.tf.mk. - Extend behavior by appending leaf targets to
SANE_*variables such asSANE_DEPS,SANE_CHECK,SANE_TEST, andSANE_SYSTEM. - Keep top-level verbs declarative; put real work in
deps/*,check/*,test/*,system/*,debug/*.
Validation entrypoints
In a sane.mk repo, NEVER invoke linters/formatters/test runners directly
(e.g. markdownlint, ruff, yamllint, shellcheck, pytest). Always use:
make check— lint, format, static analysis, secret scanningmake test— testsmake all— buildmake clean— clean generated files
Makefile.lazy resolves tool paths and the repo's config files (e.g.
.markdownlint.jsonc, .ruff.toml) are wired into these targets. Direct
invocation bypasses that wiring and runs a strict subset of the checks.
Repo rules
##comments feedmake help.- Target names use
/; keep.PHONYon its own line. - Make vars use
$(VAR); bash vars use$${VAR}. - Resolve tools with
$(call which,NAME,gname name)into ALL_CAPS variables. - Prefer wrappers like
$(MKDIR),$(CP),$(LN),$(RM)and lazy helpers like$(call make-lazy-once,VAR).
Common tasks
- Add a checker:
Use real tab characters in actual recipe lines.
SANE_CHECK += \
check/foo \
.PHONY: check/foo
check/foo: ## Check foo.
<TAB>$(FOO) --check .
- Add a system dependency:
# Brewfile
brew "shellcheck"
Run make system or make test/system/brewfile.
- Add a generated file or folder:
SANE_DEPS_FILES += config/generated.env
SANE_DEPS_FOLDERS += deps/folders/tmp
config/generated.env:
<TAB>$(TOUCH) $@
Guardrails
- Do not reimplement
all,deps,check,build,test,dist,ci,clean,debug, orsystemunless changing the framework itself. - Preserve formatting and comment conventions;
helpoutput depends on them.
