hyperhive/nix/packages/reference-docs.nix
iris 5dce46830d reference-docs: virtualize the options bundle under docs/options/, like crates/
mara on hyperhive/website#59 ("is this slice 1? i expected the options
to fold into the main docs sidebar as well so that you have one all
docs tree" / "the same thing already happens: crate readmes get
included as well. add the virtual options dir"): apply the exact
technique already used for docs/crates/<crate>.md to the nixosOptionsDoc
bundle (packages.docs) — project it into the reference-docs tree at
docs/options/*.md rather than leaving it a wholly separate flake output
options.nix has to fetch and render on its own pipeline.

Simpler than the crates/ case: the options bundle is already
self-contained CommonMark with no relative doc-links needing rewriting
(nixosOptionsDoc's transformOptions already points every option
declaration at an absolute forge URL), so this is a straight
recursive copy, not a per-file sed pass.

website's docs.nix needs no changes to pick this up — its sidebar walk
is already generic over subdirectories, same reason the earlier
crates/ virtualization needed none. The website-side follow-up (has
docs.nix render these instead of options.nix's separate pipeline, and
what that means for the current /options/ URL) is a separate change on
that repo, not touched here.
2026-09-02 08:35:30 +02:00

100 lines
3.9 KiB
Nix

{
stdenv,
lib,
self,
optionsMd,
}:
# The repo `docs/` markdown tree, shipped as a standalone derivation so
# agents can read the reference docs in-container (added as a claude
# additional directory by the harness) WITHOUT pulling the branding +
# prompt assets they don't need, and so the `hyperhive/website` repo can
# reuse the exact same tree as a flake input.
#
# The docs/ tree is copied verbatim. Two more subdirs are virtualized on
# top of it, same reasoning for both: project an external source of
# truth into the tree instead of hand-copying (and drifting) it.
# `docs.nix` (website repo) needs no changes to pick either up — it
# already walks every subdirectory generically.
#
# Output layout:
# $out/ — the repo docs/ tree verbatim
# $out/crates/<crate>.md — one per workspace crate README
# $out/options/*.md — the nixosOptionsDoc bundle (`packages.docs`,
# nix/docs/default.nix), copied verbatim —
# already self-contained CommonMark, unlike
# the crate READMEs below, so no rewriting.
let
cargoToml = builtins.fromTOML (builtins.readFile ../../Cargo.toml);
members = cargoToml.workspace.members;
# A member-name relative link (`../<other-crate>`, no specific file —
# forge's browser renders that as a directory listing today) becomes a
# sibling crates/<other-crate>.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";
version = "0.1.0";
# Narrow src (just docs/) keeps the *base tree*'s input hash decoupled
# from the rest of the workspace — a doc edit only re-hashes this half.
# The crates/ generation below necessarily widens that: it reads
# each crate's own README.md via `self`, so this derivation's hash now
# also tracks the whole repo tree (Nix has no cheaper way to depend on
# "just these few files" out of a flake `self`). Accepted trade-off —
# 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;
dontBuild = true;
dontConfigure = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r ./* $out/
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
# (crates/ -> docs/ is one directory shallower than
# <crate>/ -> docs/ was, so the leading docs/ segment drops)
# ../<sibling-crate> (that crate's own directory, no file)
# -> ./<sibling-crate>.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}
runHook postInstall
'';
dontFixup = true;
meta = {
description = "hyperhive reference docs (the repo docs/ tree, plus virtual crates/<crate>.md and options/*.md subdirs)";
homepage = "https://forge.darkest.space/hyperhive/hyperhive";
};
}