17840: Deduplicate flag-parsing code.
[arvados.git] / lib / cmd / parseflags.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package cmd
6
7 import (
8         "flag"
9         "fmt"
10         "io"
11 )
12
13 // ParseFlags calls f.Parse(args) and prints appropriate error/help
14 // messages to stderr.
15 //
16 // The positional argument is "" if no positional arguments are
17 // accepted, otherwise a string to print with the usage message,
18 // "Usage: {prog} [options] {positional}".
19 //
20 // The first return value, ok, is true if the program should continue
21 // running normally, or false if it should exit now.
22 //
23 // If ok is false, the second return value is an appropriate exit
24 // code: 0 if "-help" was given, 2 if there was a usage error.
25 func ParseFlags(f FlagSet, prog string, args []string, positional string, stderr io.Writer) (ok bool, exitCode int) {
26         f.Init(prog, flag.ContinueOnError)
27         f.SetOutput(io.Discard)
28         err := f.Parse(args)
29         switch err {
30         case nil:
31                 if f.NArg() > 0 && positional == "" {
32                         fmt.Fprintf(stderr, "unrecognized command line arguments: %v (try -help)\n", f.Args())
33                         return false, 2
34                 }
35                 return true, 0
36         case flag.ErrHelp:
37                 if f, ok := f.(*flag.FlagSet); ok && f.Usage != nil {
38                         f.SetOutput(stderr)
39                         f.Usage()
40                 } else {
41                         fmt.Fprintf(stderr, "Usage: %s [options] %s\n", prog, positional)
42                         f.SetOutput(stderr)
43                         f.PrintDefaults()
44                 }
45                 return false, 0
46         default:
47                 fmt.Fprintf(stderr, "error parsing command line arguments: %s (try -help)\n", err)
48                 return false, 2
49         }
50 }