Configure prettier and make fmt-check cover markdown (closes #69)
All checks were successful
check / check (push) Successful in 38s
All checks were successful
check / check (push) Successful in 38s
script/fmt ran prettier with default settings over root-level *.md and *.json, swallowing every failure with `|| true`, while script/fmt-check checked gofmt only. The formatter and the gate therefore disagreed silently: `make fmt` rewrote markdown that `make check` never looked at, including REPO_POLICIES.md, which is a verbatim copy of an authoritative upstream document that local tooling must not touch. Configuration: - .prettierrc pins the two policy deviations from prettier defaults, four-space indents and proseWrap: always. Nothing else. - .prettierignore excludes REPO_POLICIES.md so no local run can drift it from upstream again, plus .golangci.yml (user-owned, and listed even though the current file set does not reach it) and node_modules, vendor, bin. One canonical file set: - New script/prettier takes --write or --check and applies the same patterns in both modes, so script/fmt and script/fmt-check cannot drift apart by construction. The patterns are repo-wide (**/*.md, **/*.json) rather than root-only, so markdown in subdirectories such as a future docs/ is covered. - No `|| true` anywhere, and no --no-error-on-unmatched-pattern: both patterns always match tracked files, so an empty match means the glob broke and prettier should say so instead of passing vacuously. A missing prettier is a hard error naming script/bootstrap, not a silent skip. Pinned prettier: - package.json/yarn.lock pin prettier 3.9.6; the lockfile carries the integrity hash, and --frozen-lockfile enforces it. script/prettier prefers node_modules/.bin/prettier and warns on stderr when it has to fall back to a PATH prettier of unknown version. - script/bootstrap now installs node, yarn, and the locked JS deps. Its NODE_VERSION and YARN_VERSION pins already existed. Docker gate: - The golangci-lint image has no node, so the lint stage runs the new script/fmt-check-go (the Go half of fmt-check, extracted) instead of the whole thing. - The markdown half gets its own stage on a digest-pinned node image shipping exactly the node and yarn versions bootstrap pins. The builder stage takes a COPY --from dependency on it, so BuildKit cannot skip it and a markdown violation fails `docker build .` rather than being skipped somewhere nobody looks. Markdown files other than REPO_POLICIES.md are reformatted here for the first time under the policy settings.
This commit is contained in:
@@ -130,9 +130,13 @@ main() {
|
||||
if missing make; then pkg_install gnumake make make make; fi
|
||||
|
||||
# ---- JS / docs repos ----
|
||||
# ensure_node
|
||||
# ensure_yarn
|
||||
# install_js_deps
|
||||
# This is a Go repo, but node and yarn are required anyway: prettier
|
||||
# formats the Markdown and JSON, and script/fmt-check verifies it.
|
||||
# The version is pinned by package.json/yarn.lock, whose integrity
|
||||
# hashes --frozen-lockfile enforces.
|
||||
ensure_node
|
||||
ensure_yarn
|
||||
install_js_deps
|
||||
|
||||
# ---- Go repos ----
|
||||
if missing go; then pkg_install go golang go go; fi
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
# script/fmt: format all files (writes).
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
# Regenerate mfer/mf.pb.go from mfer/mf.proto if it is missing or stale
|
||||
# (mirrors the old Makefile prerequisite; the generated file is
|
||||
@@ -19,9 +20,8 @@ main() {
|
||||
ensure_pb
|
||||
gofumpt -l -w mfer internal cmd
|
||||
golangci-lint run --fix
|
||||
# prettier is best-effort, as in the old Makefile (- prefix)
|
||||
prettier -w *.json || true
|
||||
prettier -w *.md || true
|
||||
# Markdown and JSON, over the same file set script/fmt-check verifies.
|
||||
"$SCRIPT_DIR/prettier" --write
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -1,28 +1,14 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check: check formatting (read-only). Same scope as
|
||||
# script/fmt, but fails instead of writing.
|
||||
# script/fmt, but fails instead of writing: Go via script/fmt-check-go,
|
||||
# Markdown and JSON via script/prettier.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
# Regenerate mfer/mf.pb.go from mfer/mf.proto if it is missing or stale
|
||||
# (mirrors the old Makefile prerequisite; the generated file is
|
||||
# committed, so this is normally a no-op).
|
||||
ensure_pb() {
|
||||
if [ ! -f mfer/mf.pb.go ] ||
|
||||
[ -n "$(find mfer/mf.proto -newer mfer/mf.pb.go 2>/dev/null)" ]; then
|
||||
(cd mfer && go generate .)
|
||||
fi
|
||||
}
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
ensure_pb
|
||||
if [ -n "$(gofmt -l .)" ]; then
|
||||
echo "gofmt: files need formatting:" >&2
|
||||
gofmt -l . >&2
|
||||
exit 1
|
||||
fi
|
||||
"$SCRIPT_DIR/fmt-check-go"
|
||||
"$SCRIPT_DIR/prettier" --check
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
29
script/fmt-check-go
Executable file
29
script/fmt-check-go
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check-go: check Go formatting (read-only). Split out from
|
||||
# script/fmt-check so the Docker lint stage, whose image has no node and
|
||||
# therefore no prettier, can run the Go half on its own.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
# Regenerate mfer/mf.pb.go from mfer/mf.proto if it is missing or stale
|
||||
# (mirrors the old Makefile prerequisite; the generated file is
|
||||
# committed, so this is normally a no-op).
|
||||
ensure_pb() {
|
||||
if [ ! -f mfer/mf.pb.go ] ||
|
||||
[ -n "$(find mfer/mf.proto -newer mfer/mf.pb.go 2>/dev/null)" ]; then
|
||||
(cd mfer && go generate .)
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
ensure_pb
|
||||
if [ -n "$(gofmt -l .)" ]; then
|
||||
echo "gofmt: files need formatting:" >&2
|
||||
gofmt -l . >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
main "$@"
|
||||
69
script/prettier
Executable file
69
script/prettier
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
# script/prettier: run prettier over this repo's canonical file set.
|
||||
#
|
||||
# Takes exactly one mode argument, --write or --check, and applies the
|
||||
# same patterns in both modes. script/fmt and script/fmt-check both go
|
||||
# through here, so the set of files that get formatted and the set that
|
||||
# get verified cannot drift apart.
|
||||
#
|
||||
# Failures are never swallowed: a missing prettier is an error, not a
|
||||
# silent skip. A formatter that quietly does nothing is worse than one
|
||||
# that fails loudly.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
usage() {
|
||||
echo "usage: script/prettier --write|--check" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# Prefer the version pinned by package.json/yarn.lock so that CI and
|
||||
# developer machines format identically. Fall back to a prettier on PATH,
|
||||
# but say so, because a different version formats differently.
|
||||
find_prettier() {
|
||||
if [ -x "$ROOT/node_modules/.bin/prettier" ]; then
|
||||
printf '%s\n' "$ROOT/node_modules/.bin/prettier"
|
||||
return 0
|
||||
fi
|
||||
if command -v prettier >/dev/null 2>&1; then
|
||||
echo "prettier: node_modules/.bin/prettier is absent; using the" \
|
||||
"prettier on PATH, which may be a different version than the" \
|
||||
"one pinned in package.json. Run script/bootstrap to install" \
|
||||
"the pinned version." >&2
|
||||
command -v prettier
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
main() {
|
||||
[ "$#" -eq 1 ] || usage
|
||||
case "$1" in
|
||||
--write | --check) mode="$1" ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
|
||||
cd "$ROOT"
|
||||
|
||||
if ! prettier_bin="$(find_prettier)"; then
|
||||
echo "prettier: not found." >&2
|
||||
echo " Install it with: script/bootstrap" >&2
|
||||
echo " (installs the version pinned in package.json/yarn.lock)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Markdown and JSON, repo-wide rather than root-only, so files in
|
||||
# subdirectories (docs/, once it exists) are covered too. Exclusions
|
||||
# live in .prettierignore; REPO_POLICIES.md is excluded there because
|
||||
# it is a verbatim copy of an upstream document.
|
||||
#
|
||||
# --no-error-on-unmatched-pattern is deliberately NOT used: both
|
||||
# patterns always match at least one tracked file (README.md,
|
||||
# package.json), so an empty match means the glob broke, and prettier
|
||||
# erroring out is exactly what we want rather than a vacuous pass.
|
||||
"$prettier_bin" "$mode" "**/*.md"
|
||||
"$prettier_bin" "$mode" "**/*.json"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user