aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorQyriad <qyriad@qyriad.me>2024-04-08 21:43:38 -0600
committereldritch horrors <pennae@lix.systems>2024-04-10 15:04:34 +0200
commit723ddadf92d0e8d54197424e1a0cb839e9d3d6b6 (patch)
tree9ce86d7f6b0f1debe9cb5755ef2b4896b8fa66dc /doc
parent7e139c52dd901c0feccf6a4f2cbc56673d5e0259 (diff)
docs: generalize manpage generation script as json-to-tree.py
This should be capable of replacing every invocation of nix eval --write-to. Change-Id: I60387bc9b0fc54a91244eddb639beaa64d705878
Diffstat (limited to 'doc')
-rwxr-xr-xdoc/manual/generate-manpage.py63
-rwxr-xr-xdoc/manual/json-to-tree.py61
-rw-r--r--doc/manual/meson.build41
3 files changed, 85 insertions, 80 deletions
diff --git a/doc/manual/generate-manpage.py b/doc/manual/generate-manpage.py
deleted file mode 100755
index f082caffa..000000000
--- a/doc/manual/generate-manpage.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python3
-
-"""
-This script is a helper for this project's Meson buildsystem, to generate
-manpages as mdbook markdown for nix3 CLI commands. It is an analogue to an
-inline sequence of bash commands in the autoconf+Make buildsystem, which works
-around a limitation in `nix eval --write-to`, in that it refuses to write to any
-directory that already exists.
-
-Basically, this script is a glorified but hopefully-more-robust version of:
-$ rm -rf $output
-$ nix eval --write-to $output.tmp --expr 'import doc/manual/generate-manpage.nix true
- (builtins.readFile ./generate-manpage.nix)'
-$ mv $output.tmp $output
-"""
-
-import argparse
-import os.path
-import shlex
-import shutil
-import subprocess
-import sys
-import tempfile
-
-name = 'generate-manpage.py'
-
-def log(*args, **kwargs):
- kwargs['file'] = sys.stderr
- return print(f'{name}:', *args, **kwargs)
-
-def main():
- parser = argparse.ArgumentParser(name)
- parser.add_argument('--nix', required=True, help='Full path to the nix binary to use')
- parser.add_argument('-o', '--output', required=True, help='Output directory')
- parser.add_argument('--generator', required=True, help='Path to generate-manpage.nix')
- parser.add_argument('--cli-json', required=True, help='Path to the nix.json output from Nix')
- args = parser.parse_args()
-
- with tempfile.TemporaryDirectory() as tempdir:
-
- temp_out = os.path.join(tempdir, 'new-cli')
-
- nix_args = [
- args.nix,
- '--experimental-features',
- 'nix-command',
- 'eval',
- '-I', 'nix/corepkgs=corepkgs',
- '--store', 'dummy://',
- '--impure',
- '--raw',
- '--write-to', temp_out,
- '--expr',
- f'import {args.generator} true (builtins.readFile {args.cli_json})',
- ]
-
- log('generating nix3 man pages with', shlex.join(nix_args))
-
- subprocess.check_call(nix_args)
-
- shutil.copytree(temp_out, args.output, dirs_exist_ok=True)
-
-sys.exit(main())
diff --git a/doc/manual/json-to-tree.py b/doc/manual/json-to-tree.py
new file mode 100755
index 000000000..27c8e417c
--- /dev/null
+++ b/doc/manual/json-to-tree.py
@@ -0,0 +1,61 @@
+#!/usr/bin/env python3
+
+"""
+This script is a helper for this project's Meson buildsystem, to replace its
+usage of `nix eval --write-to`. Writing a JSON object as a nested directory
+tree is more generic, easier to maintain, and far, far less cursed. Nix
+has 'good' support for JSON output. Let's just use it.
+"""
+
+import argparse
+from pathlib import Path
+import json
+import sys
+
+name = 'json-to-tree.py'
+
+def log(*args, **kwargs):
+ kwargs['file'] = sys.stderr
+ return print(f'{name}:', *args, **kwargs)
+
+def write_dict_to_directory(current_directory: Path, data: dict, files_written=0):
+ current_directory.mkdir(parents=True, exist_ok=True)
+ for key, value in data.items():
+ nested_path = current_directory / key
+ match value:
+ case dict(nested_data):
+ files_written += write_dict_to_directory(nested_path, nested_data)
+
+ case str(content):
+ nested_path.write_text(content)
+ files_written += 1
+
+ case rest:
+ assert False, \
+ f'should have been called on a dict or string, not {type(rest)=}\n\t{rest=}'
+
+ return files_written
+
+def main():
+ parser = argparse.ArgumentParser(name)
+ parser.add_argument('-i', '--input', type=argparse.FileType('r'), default='-',
+ help='The JSON input to operate on and output as a directory tree',
+ )
+ parser.add_argument('-o', '--output', type=Path, required=True,
+ help='The place to put the directory tree',
+ )
+ args = parser.parse_args()
+
+ json_string = args.input.read()
+
+ try:
+ data = json.loads(json_string)
+ except json.JSONDecodeError:
+ log(f'could not decode JSON from input: {json_string}')
+ raise
+
+
+ files_written = write_dict_to_directory(args.output, data)
+ log(f'wrote {files_written} files')
+
+sys.exit(main())
diff --git a/doc/manual/meson.build b/doc/manual/meson.build
index dafec9a4c..55373d15c 100644
--- a/doc/manual/meson.build
+++ b/doc/manual/meson.build
@@ -7,13 +7,13 @@ nix_env_for_docs = {
}
nix_for_docs = [ nix, '--experimental-features', 'nix-command' ]
-nix_eval_for_docs = nix_for_docs + [
+nix_eval_for_docs_common = nix_for_docs + [
'eval',
'-I', 'nix/corepkgs=corepkgs',
'--store', 'dummy://',
'--impure',
- '--raw',
]
+nix_eval_for_docs = nix_eval_for_docs_common + '--raw'
nix_conf_file_json = custom_target(
command : nix_for_docs + [ 'show-config', '--json' ],
@@ -132,27 +132,34 @@ nix3_cli_json = custom_target(
capture : true,
output : 'nix.json',
)
-# `nix eval --write-to` is rather picky, and refuses to write to a directory that exists at all.
-# This is fine for clean builds because it creates the directory and then is never run again,
-# but during development if nix.json changes, then using `nix eval --write-to` will error,
-# since that part of the build directory already exists.
-# Thus, another Python script. It runs the relevant `nix eval --write-to` command in a temporary
-# directory, and then copies that tree to our build output directory.
+
+# Intermediate step for manpage generation.
+# This splorks the output of generate-manpage.nix as JSON,
+# which gets written as a directory tree below.
+nix3_cli_files_json = custom_target(
+ command : nix_eval_for_docs_common + [
+ '--json',
+ '--expr',
+ 'import @INPUT0@ true (builtins.readFile @INPUT1@)',
+ ],
+ input : [
+ 'generate-manpage.nix',
+ nix3_cli_json,
+ ],
+ capture : true,
+ output : 'new-cli.json',
+ env : nix_env_for_docs,
+)
nix3_cli_files = custom_target(
command : [
python,
'@INPUT0@',
- '--nix=@INPUT1@',
- '--generator=@INPUT2@',
- '--cli-json=@INPUT3@',
- '--output=@OUTPUT@',
+ '-i', '@INPUT1@',
+ '-o', '@OUTPUT@',
],
input : [
- 'generate-manpage.py', # INPUT0
- nix, # INPUT1
- 'generate-manpage.nix', # INPUT2
- nix3_cli_json, # INPUT3
- 'utils.nix',
+ 'json-to-tree.py',
+ nix3_cli_files_json,
],
output : 'new-cli',
)