From 299ec50c32f836ce1480e6ff768ad1eaa8542363 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Tue, 26 Apr 2022 21:15:26 +0200 Subject: [PATCH] cmd/age: improve error message for out-of-order flags Fixes #160 Closes #345 Co-authored-by: puenka --- cmd/age/age.go | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/cmd/age/age.go b/cmd/age/age.go index f1f459c..7cf80d4 100644 --- a/cmd/age/age.go +++ b/cmd/age/age.go @@ -12,6 +12,7 @@ import ( "io" "log" "os" + "regexp" "runtime/debug" "strings" @@ -125,9 +126,37 @@ func main() { } if flag.NArg() > 1 { - errorWithHint(fmt.Sprintf("too many arguments: %q", flag.Args()), - "note that the input file must be specified after all flags") + var hints []string + quotedArgs := strings.Trim(fmt.Sprintf("%q", flag.Args()), "[]") + + // If the second argument looks like a flag, suggest moving the first + // argument to the back (as long as the arguments don't need quoting). + if strings.HasPrefix(flag.Arg(1), "-") { + hints = append(hints, "the input file must be specified after all flags") + + safe := true + unsafeShell := regexp.MustCompile(`[^\w@%+=:,./-]`) + for _, arg := range os.Args { + if unsafeShell.MatchString(arg) { + safe = false + break + } + } + if safe { + i := len(os.Args) - flag.NArg() + newArgs := append([]string{}, os.Args[:i]...) + newArgs = append(newArgs, os.Args[i+1:]...) + newArgs = append(newArgs, os.Args[i]) + hints = append(hints, "did you mean:") + hints = append(hints, " "+strings.Join(newArgs, " ")) + } + } else { + hints = append(hints, "only a single input file may be specified at a time") + } + + errorWithHint("too many INPUT arguments: "+quotedArgs, hints...) } + switch { case decryptFlag: if encryptFlag {