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 <jan@janware.com>
This commit is contained in:
Jan Lindemann 2026-09-12 18:28:22 +02:00
commit 7f9f65153f
Signed by: Jan Lindemann
GPG key ID: 3750640C9E25DD61
2 changed files with 36 additions and 1 deletions

View file

@ -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))