diff --git a/nix/packages/reference-docs.nix b/nix/packages/reference-docs.nix index b40aabb2..121a3ca8 100644 --- a/nix/packages/reference-docs.nix +++ b/nix/packages/reference-docs.nix @@ -1,6 +1,5 @@ { stdenv, - lib, self, optionsMd, }: @@ -34,22 +33,6 @@ let cargoToml = builtins.fromTOML (builtins.readFile ../../Cargo.toml); members = cargoToml.workspace.members; - - # A member-name relative link (`../`, no specific file — - # forge's browser renders that as a directory listing today) becomes a - # sibling crates/.md link once every crate README - # lives flat in the same directory. Built once, applied per file below, - # rather than a fresh `lib.concatMapStrings` per crate's own transform — - # every crate needs the exact same substitution list (every *other* - # member), so this only differs on the `member != other` filter. - siblingLinkFixups = - member: - lib.concatMapStrings ( - other: - lib.optionalString (other != member) '' - -e 's,\]\(\.\./${other}(/)?\),](./${other}.md),g' \ - '' - ) members; in stdenv.mkDerivation { pname = "hyperhive-docs"; @@ -63,11 +46,15 @@ stdenv.mkDerivation { # the alternative is hand-copying READMEs into docs/ and letting them # drift, which is the exact duplication this issue exists to avoid. src = ../../docs; - inherit self optionsMd; + inherit self optionsMd members; dontBuild = true; dontConfigure = true; + # The per-crate rewrite is a loop at build time, so this phase's text + # stays the same size as crates are added: each attribute reaches the + # builder as one environment variable, and Linux refuses to exec with + # a single one over 128 KiB. installPhase = '' runHook preInstall mkdir -p $out @@ -75,24 +62,24 @@ stdenv.mkDerivation { mkdir -p "$out/crates" cp -r "$optionsMd" "$out/options" - ${lib.concatMapStrings (member: '' - if [ -f "$self/${member}/README.md" ]; then - # Rewrite relative links that were correct from the crate's own - # position in the repo tree but aren't once the file is - # virtually one level under docs/ instead: - # ../docs/x.md (crate root -> repo docs/) -> ../x.md lint:allow (stand-in name) - # (crates/ -> docs/ is one directory shallower than - # / -> docs/ was, so the leading docs/ segment drops) - # ../ (that crate's own directory, no file) - # -> ./.md, once that sibling also has a - # crates page every crate README lives flat beside it. - sed -E \ - -e 's,\]\(\.\./docs/,](../,g' \ - ${siblingLinkFixups member} \ - "$self/${member}/README.md" \ - > "$out/crates/${member}.md" - fi - '') members} + for member in $members; do + [ -f "$self/$member/README.md" ] || continue + # Rewrite relative links that were correct from the crate's own + # position in the repo tree but aren't once the file is + # virtually one level under docs/ instead: + # ../docs/x.md (crate root -> repo docs/) -> ../x.md lint:allow (stand-in name) + # (crates/ -> docs/ is one directory shallower than + # / -> docs/ was, so the leading docs/ segment drops) + # ../ (that crate's own directory, no file; forge + # renders it as a directory listing) -> ./.md, + # since every crate README lives flat beside it under crates/. + fixups=(-e 's,\]\(\.\./docs/,](../,g') + for other in $members; do + [ "$other" != "$member" ] || continue + fixups+=(-e "s,\]\(\.\./$other(/)?\),](./$other.md),g") + done + sed -E "''${fixups[@]}" "$self/$member/README.md" >"$out/crates/$member.md" + done runHook postInstall '';