Accept match value positionally so -pm <value> works
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful

pflag does not attach a space-separated value to a string flag that is grouped
with a bool flag, so `node-lookup -R -pm k8s` parsed -p and left `k8s` as a
stray positional, failing with "unknown command k8s". Only `-pm=k8s` or the
un-grouped `-p -m k8s` worked, which is surprising.

- Allow one positional argument (cobra.MaximumNArgs(1)) and fall back to it for
  the match value when -m is empty (matchValue()), so -pm/-im/-ipm <value> and
  a bare `-p <value>` all work. -m still wins when both are given.
- Add matchValue unit tests.
- Document the positional value and the pflag grouping quirk in AGENTS.md.
This commit is contained in:
2026-07-05 17:02:25 +10:00
parent e070357d3f
commit 8696097a6a
3 changed files with 52 additions and 6 deletions
+23 -2
View File
@@ -236,6 +236,21 @@ func stdinReader(f *os.File) (*bufio.Reader, bool) {
return r, true
}
// matchValue resolves the value to match against. The -m/--match flag wins; if
// it is empty, the (optional) positional argument is used instead. The
// positional fallback exists so combined shorthands like `-pm k8s` work — pflag
// leaves the space-separated `k8s` as a positional rather than attaching it to
// the grouped -m flag.
func matchValue(flagMatch string, args []string) string {
if flagMatch != "" {
return flagMatch
}
if len(args) > 0 {
return args[0]
}
return ""
}
func allFactsForNode(puppetDBURL, node string) ([]fact, error) {
query, _ := json.Marshal([]interface{}{"=", "certname", node})
return queryPuppetDB(puppetDBURL, string(query))
@@ -389,8 +404,14 @@ func main() {
)
rootCmd := &cobra.Command{
Use: appName,
Use: appName + " [value]",
Short: "Query PuppetDB for nodes.",
// Accept an optional positional match value in addition to -m. This makes
// combined shorthands like `-pm k8s` work: pflag does not attach a
// space-separated value to a string flag grouped with a bool flag (only
// `-pm=k8s` or `-p -m k8s` do), so `k8s` arrives here as a positional
// argument instead. Falling back to it keeps the ergonomic form working.
Args: cobra.MaximumNArgs(1),
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("url") {
cfg.PuppetDBURL = puppetDBURL
@@ -398,7 +419,7 @@ func main() {
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
return run(cfg, nodeName, factName, match, showRole, partial, inverse, nodeOnly, valueOnly, count, ansible, jsonMode, allFacts)
return run(cfg, nodeName, factName, matchValue(match, args), showRole, partial, inverse, nodeOnly, valueOnly, count, ansible, jsonMode, allFacts)
},
SilenceUsage: true,
}