about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2021-03-24T19·02+0100
committersterni <sternenseemann@systemli.org>2021-03-31T23·06+0000
commit811fff2d8b43cab0d15f32016c3d0572ffa9db77 (patch)
treef30f9d79dcb2c7bf2aab89b573d8a05b1a845345
parentc693e8bf514bf5c34ad463dd934f787ed2eea88a (diff)
feat(nix/buildManPages): infra for generating man page dirs from nix r/2380
Very simple builder which builds (optionally) gzipped man pages from a
list of attrsets and links them into a common man directory with the
correct layout, so it should be installable immediately.

Additionally runs mandoc -T lint, but by default only for informational
purposes as it is very strict and some things are almost never true (for
example all Xrs being present in the respective directory).

buildManPages.single exposes the internal builder for a single,
optionally gzipped man page from a nix attrset.

Change-Id: I43fce011716f4a7cc80521f222800ca99ba54060
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2654
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
-rw-r--r--nix/buildManPages/OWNERS3
-rw-r--r--nix/buildManPages/default.nix77
2 files changed, 80 insertions, 0 deletions
diff --git a/nix/buildManPages/OWNERS b/nix/buildManPages/OWNERS
new file mode 100644
index 000000000000..f16dd105d761
--- /dev/null
+++ b/nix/buildManPages/OWNERS
@@ -0,0 +1,3 @@
+inherited: true
+owners:
+  - sterni
diff --git a/nix/buildManPages/default.nix b/nix/buildManPages/default.nix
new file mode 100644
index 000000000000..83cf548c77bc
--- /dev/null
+++ b/nix/buildManPages/default.nix
@@ -0,0 +1,77 @@
+{ depot, ... }:
+
+let
+  inherit (depot.third_party)
+    lib
+    gzip
+    mandoc
+    coreutils
+    ;
+
+  inherit (depot.nix)
+    runExecline
+    getBins
+    ;
+
+  bins = getBins mandoc [ "mandoc" ]
+      // getBins gzip   [ "gzip" ]
+      // getBins coreutils [ "mkdir" "ln" "cp" ]
+      ;
+
+  defaultGzip = true;
+
+  basename = gzip: { name, section, ... }:
+    "${name}.${toString section}${lib.optionalString gzip ".gz"}";
+
+  manDir = { section, ... }:
+    "\${out}/share/man/man${toString section}";
+
+  target = gzip: args:
+    "${manDir args}/${basename gzip args}";
+
+  buildManPage =
+    { requireLint ? false
+    , gzip ? defaultGzip
+    , ...
+    }:
+    { content
+    , ...
+    }@page: let
+      source = builtins.toFile (basename false page) content;
+    in runExecline (basename gzip page) {} ([
+      (if requireLint then "if" else "foreground") [
+        bins.mandoc "-mdoc" "-T" "lint" source
+      ]
+      "importas" "out" "out"
+    ] ++ (if gzip then [
+      "redirfd" "-w" "1" "$out"
+      bins.gzip "-c" source
+    ] else [
+      bins.cp "--reflink=auto" source "$out"
+    ]));
+
+  buildManPages =
+    name:
+    { derivationArgs ? {}
+    , gzip ? defaultGzip
+    , ...
+    }@args:
+    pages:
+    runExecline "${name}-man-pages" {
+      inherit derivationArgs;
+    } ([
+      "importas" "out" "out"
+    ] ++ lib.concatMap ({ name, section, content }@page: [
+      "if" [ bins.mkdir "-p" (manDir page) ]
+      "if" [
+        bins.ln "-s"
+        (buildManPage args page)
+        (target gzip page)
+      ]
+    ]) pages);
+
+in {
+  __functor = _: buildManPages;
+
+  single = buildManPage;
+}