From 7f9f65153fa2d17845976224b84e55db204c0b14 Mon Sep 17 00:00:00 2001 From: Jan Lindemann Date: Sat, 12 Sep 2026 18:28:22 +0200 Subject: [PATCH] cmds.projects.CmdCreateFile: Add --field-keys option The --field option accepts arbitrary KEY=VALUE pairs, inserting them into the rendered template output, but there is no way to declare which keys a template actually supports. Passing a key the template does not use goes unnoticed, and a template cannot offer optional fields that drop out of the output when not supplied. Add a --field-keys option, a comma-separated list of the keys a template accepts. Passing a key via --field that is not in that list is an error, and keys from the list that are not passed are added with an empty value, so the respective field renders as empty and effectively drops out of the output. Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.85.1 Signed-off-by: Jan Lindemann --- .../jw/pkg/cmds/projects/CmdCreateFile.py | 29 ++++++++++++++++++- .../integration/jw-pkg/help/test-expected.txt | 8 +++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/python/jw/pkg/cmds/projects/CmdCreateFile.py b/src/python/jw/pkg/cmds/projects/CmdCreateFile.py index 754f42cb..007d9734 100644 --- a/src/python/jw/pkg/cmds/projects/CmdCreateFile.py +++ b/src/python/jw/pkg/cmds/projects/CmdCreateFile.py @@ -132,11 +132,38 @@ class CmdCreateFile(Cmd): # export metavar = 'KEY=VALUE', help = 'Additional fields to insert into the output file', ) + parser.add_argument( + '--field-keys', + help = ( + 'Possible keys for the --field option, comma-separated. Defaults to ' + 'all passed via the --field option. If this field is specified, ' + 'passing a key in --field that\'s not specified here is an error, ' + 'and not passing one makes the respective field go away from the ' + 'rendering output' + ) + ) parser.add_argument('module', help = 'The module to generate the file for') @override async def _run(self, args: Namespace) -> None: + + # -- Honour --field-keys option + fields = args.field + if args.field_keys: + passed_keys = set([field[0] for field in fields]) + field_keys = set(args.field_keys.split(',')) + if passed_keys - field_keys: + raise Exception( + 'The following keys in --field are not in --field-keys: ' + + ', '.join(sorted(passed_keys - field_keys)) + ) + for key in field_keys - passed_keys: + fields.append((key, '')) + + # -- Find method for --format method = getattr(self, 'render_' + args.format, None) if method is None: # choices already restricts this; keeps the linter happy raise Exception(f'Unsupported output format {args.format}') - sys.stdout.write(method(args.module, args.field)) + + # -- Render + sys.stdout.write(method(args.module, fields)) diff --git a/test/integration/jw-pkg/help/test-expected.txt b/test/integration/jw-pkg/help/test-expected.txt index 4ac25287..ae035045 100644 --- a/test/integration/jw-pkg/help/test-expected.txt +++ b/test/integration/jw-pkg/help/test-expected.txt @@ -336,6 +336,7 @@ usage: jw-pkg.py projects create-file [-h] --format {pyright,tmpl} [--search-path SEARCH_PATH] [--template-name TEMPLATE_NAME] [--quote] [-f KEY=VALUE] + [--field-keys FIELD_KEYS] module Generate a file from project metadata @@ -357,6 +358,13 @@ options: -f, --field KEY=VALUE Additional fields to insert into the output file (default: []) + --field-keys FIELD_KEYS + Possible keys for the --field option, comma-separated. + Defaults to all passed via the --field option. If this + field is specified, passing a key in --field that's + not specified here is an error, and not passing one + makes the respective field go away from the rendering + output (default: None) ============= Running: jw-pkg.py -t ../../../.. --log-level info projects create-pkg-config --help usage: jw-pkg.py projects create-pkg-config [-h] [-F PROJECT_DESCR_FILE] [-d DESCRIPTION] [-n NAME]