From 4ca09e5ea0be46850e0e0443b0eeca98b2b73005 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 5 Nov 2024 09:02:06 +1100 Subject: [PATCH] Be resilient to unexpected CLI examples when deducing value syntax, fix 2.24 (#287) This fixes #284 and unblocks publishing docs for 2.24.x versions. It ensures the reference code-generation handles the new `-l` formatting syntax in the help-all output when extracting the example value. More generally, this PR makes this part of the code slightly: - more resilient by having it search for a CLI arg with syntax that can be understood, not just assuming the first one works - more debuggable by having an explicit error for the "can't find a value" case Background: our docs codegen formats a TOML snippet in, based on the information in the help-all output. This includes needing a representation of the argument value itself to deduce if it's an array or map, and also include in the output. This representation is deduced by looking after an `=` sign, e.g. `--level=` => ``. However, in https://github.com/pantsbuild/pants/pull/21446 (released in 2.24.0.dev1), we fixed the help-all output to use the correct `-l` syntax for that argument (previously it was formatted like `-l=`, but passing `pants -l=debug ...` doesn't work, so this was misleading). This changes the `display_args` value for that option (see below) in a way that stops the argument-value-deduction from working. After this PR, the deduction now operates off the `--level=` arg instead of `-l`. - old: `["-l=","--level="]` - new: `["-l","--level="]` --- reference_codegen/generate.mjs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/reference_codegen/generate.mjs b/reference_codegen/generate.mjs index 36271f32..4293108a 100644 --- a/reference_codegen/generate.mjs +++ b/reference_codegen/generate.mjs @@ -198,6 +198,26 @@ function splitFirst(string, sep) { : [string.slice(0, firstIndex), string.slice(firstIndex + sep.length)]; } +/** Return a representation of arg value from the CLI. */ +function deduceArgValue(displayArgs, envVar) { + // Find the first argument we can understand: + for (const exampleCli of displayArgs) { + const val = exampleCli.includes("[no-]") + ? "" + : splitFirst(exampleCli, "=")[1]; + + if (val) { + return val; + } + } + + // Didn't understand any of the args, flag for the user to help: + const args = JSON.stringify(displayArgs); + throw new Error( + `In ${envVar}, failed to deduce value formatting from example CLI instances: ${args}` + ); +} + function generateTomlRepr(option, scope) { // Generate a toml block for the option to help users fill out their `pants.toml`. For // scalars and arrays, we put them inline directly in the scope, while for maps we put @@ -216,11 +236,7 @@ function generateTomlRepr(option, scope) { } const tomlLines = []; - const exampleCli = option.display_args[0]; - - const val = exampleCli.includes("[no-]") - ? "" - : splitFirst(exampleCli, "=")[1]; + const val = deduceArgValue(option.display_args, option.env_var); const isMap = val.startsWith('"{') && val.endsWith('}"'); const isArray = val.startsWith('"[') && val.endsWith(']"');