From 9ed7ebab91f0d9d0b5bbac38ab862492fd91b33a Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 28 Oct 2026 21:45:15 +0100 Subject: [PATCH] fetch vale styles in nix, pinned, and drop vale sync --- .forgejo/workflows/ci.yml | 8 ++++---- .gitignore | 2 -- .vale.ini | 12 +++-------- nix/devshell.nix | 8 +++----- nix/packages/default.nix | 4 ++++ nix/packages/vale-styles.nix | 40 ++++++++++++++++++++++++++++++++++++ nix/packages/vale.nix | 30 +++++++++++++++++++++++++++ scripts/pre-push | 6 ++++++ 8 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 nix/packages/vale-styles.nix create mode 100644 nix/packages/vale.nix diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index ed6ca70f..5ce13082 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -106,11 +106,11 @@ jobs: steps: - uses: actions/checkout@v3 - name: lint - # The vale binary comes from flake.lock (`--inputs-from .`), like the devshell's. - # Styles are fetched fresh from Vale Package Hub each run (not vendored). + # The vale binary is this flake's `.#vale`, the same one the devshell has. + # The package carries the pinned styles (nix/packages/vale.nix). # Not wired into branch protection — see prose-lint-errors below for the # error-only slice that is. - run: XDG_DATA_HOME="$PWD/.vale-data" nix shell --inputs-from . nixpkgs#vale --command sh -c 'vale sync && vale docs' + run: nix run --inputs-from . .#vale -- docs prose-lint-errors: name: prose lint (vale, errors) @@ -121,4 +121,4 @@ jobs: - name: lint # Error-level-only slice. Split out so this job alone can be a required # check without blocking merges on the warning/suggestion backlog. - run: XDG_DATA_HOME="$PWD/.vale-data" nix shell --inputs-from . nixpkgs#vale --command sh -c 'vale sync && vale --minAlertLevel=error docs' + run: nix run --inputs-from . .#vale -- --minAlertLevel=error docs diff --git a/.gitignore b/.gitignore index e14ccc85..b7ce58d6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,5 +4,3 @@ /.tmp /.claude/settings.local.json *.rlib -# `vale sync` fetches these fresh into place; not vendored (see .vale.ini). -/.vale-data diff --git a/.vale.ini b/.vale.ini index 161ba653..7a531f5c 100644 --- a/.vale.ini +++ b/.vale.ini @@ -1,13 +1,7 @@ -# `vale sync`'s destination isn't actually governed by this path -- it -# always writes under `$XDG_DATA_HOME/vale/styles` (undocumented, confirmed -# by testing: neither this file's discovery nor `--config` affects it). Set -# `XDG_DATA_HOME=$PWD/.vale-data` before running `vale sync`/`vale docs` so -# both commands agree on the same repo-local, gitignored location. -StylesPath = .vale-data/vale/styles +# `StylesPath` is not set here: the `vale` package in nix/packages/vale.nix +# prepends it, pointing at the pinned styles in nix/packages/vale-styles.nix. +# A style enabled below must also be listed there. MinAlertLevel = warning -# `vale sync` reads this to know what to fetch from the Hub at CI time -- -# styles are fetched fresh each run, not vendored into the repo. -Packages = Microsoft, alex, write-good [*.md] BasedOnStyles = Microsoft, alex, write-good diff --git a/nix/devshell.nix b/nix/devshell.nix index f48fd752..215b2736 100644 --- a/nix/devshell.nix +++ b/nix/devshell.nix @@ -24,11 +24,9 @@ rustc rustfmt shellcheck - # The two "prose lint (vale)" CI jobs run vale over docs/. `vale - # sync` must run once before `vale docs` and writes styles to - # $XDG_DATA_HOME, so point that at the repo like CI does: - # `XDG_DATA_HOME=$PWD/.vale-data nix develop -c sh -c 'vale sync && vale docs'`. - vale + # The pinned-styles `vale` the two "prose lint (vale)" CI jobs run + # (nix/packages/vale.nix), with the pinned styles built in. + (pkgs.callPackage ./packages/vale.nix { }) ]); # `cargo llvm-cov` shells out to `llvm-profdata` and `llvm-cov`, diff --git a/nix/packages/default.nix b/nix/packages/default.nix index c1a8ea74..22c7a0ec 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -276,6 +276,10 @@ in # is exposed too since it's independently useful/inspectable. inherit swagger-ui-dist swagger-ui-theme; + # `vale` preconfigured with .vale.ini and the pinned style packages + # (./vale.nix, ./vale-styles.nix); the prose-lint CI jobs and the devshell run it. + vale = pkgs.callPackage ./vale.nix { }; + # REA and the Ghidra it needs; consumed by nix/agent-modules/rea.nix. rea = pkgs.callPackage ./rea.nix { }; ghidra-12-1 = pkgs.callPackage ./ghidra-12-1.nix { }; diff --git a/nix/packages/vale-styles.nix b/nix/packages/vale-styles.nix new file mode 100644 index 00000000..d0cb626c --- /dev/null +++ b/nix/packages/vale-styles.nix @@ -0,0 +1,40 @@ +{ + lib, + fetchzip, + runCommand, +}: + +# The Vale style packages named in `.vale.ini`, fetched at build time and +# laid out as Vale expects a `StylesPath`: `//.yml`. +# Each is the release asset `vale sync` would download, pinned to a tag and +# hash so a lint run makes no network request and every caller sees the +# same rules. Bumping a style means changing its `tag` and `hash` here. +let + styles = { + Microsoft = { + tag = "v0.15.1"; + hash = "sha256-NqH69LL8aKMqyoo5qWi/hFAkYA4WL7OCfTpPwR907vU="; + }; + alex = { + tag = "v0.2.3"; + hash = "sha256-YvNfhjCg437wDMxnOqu9xTKq82KZfQt9HvCpoDfwsL4="; + }; + write-good = { + tag = "v0.4.1"; + hash = "sha256-XhvZtirGg9Vl/i73HMyZpK2iSoQoXv8OS7ckryveIdU="; + }; + }; + + fetch = + name: + { tag, hash }: + fetchzip { + url = "https://github.com/vale-cli/${name}/releases/download/${tag}/${name}.zip"; + inherit hash; + stripRoot = false; + }; +in +runCommand "vale-styles" { } '' + mkdir -p $out + ${lib.concatStrings (lib.mapAttrsToList (name: s: "ln -s ${fetch name s} $out/${name}\n") styles)} +'' diff --git a/nix/packages/vale.nix b/nix/packages/vale.nix new file mode 100644 index 00000000..daa6c17f --- /dev/null +++ b/nix/packages/vale.nix @@ -0,0 +1,30 @@ +{ + lib, + vale, + runCommand, + makeWrapper, + callPackage, +}: + +# `vale` with the repo's `.vale.ini` and the pinned styles from +# ./vale-styles.nix baked in, so `vale docs` works from the repo root without +# any setup step. CI, the devshell and local runs all +# take this one binary. `.vale.ini` carries no `StylesPath`; the wrapper's +# generated config prepends the store path to the file's contents. +let + styles = callPackage ./vale-styles.nix { }; + config = runCommand "vale.ini" { } '' + { echo "StylesPath = ${styles}"; cat ${../../.vale.ini}; } > $out + ''; +in +runCommand "vale-${vale.version}-hyperhive" + { + nativeBuildInputs = [ makeWrapper ]; + meta = { + description = "vale preconfigured with the repo's .vale.ini and pinned style packages"; + mainProgram = "vale"; + }; + } + '' + makeWrapper ${lib.getExe vale} $out/bin/vale --add-flags "--config ${config}" + '' diff --git a/scripts/pre-push b/scripts/pre-push index 7f36a492..167906d6 100755 --- a/scripts/pre-push +++ b/scripts/pre-push @@ -45,5 +45,11 @@ if ! sh "$repo_root/scripts/check-dashboard-service-names.sh"; then exit 1 fi +echo "pre-push: running prose lint (vale)..." >&2 +if ! (cd "$repo_root" && nix run --inputs-from . .#vale -- docs); then + echo "pre-push: prose lint FAILED — fix before pushing" >&2 + exit 1 +fi + echo "pre-push: lints passed ✓" >&2 exit 0