Merge branch '21666-provision-test-improvement'
[arvados.git] / lib / cmd / cmd.go
index a03cb90f68e6cd84ee0e9091971af7370f0ee7db..40e80f5eaab74df0f5370f50c12d1d2868e0e6f9 100644 (file)
@@ -14,12 +14,15 @@ import (
        "path/filepath"
        "regexp"
        "runtime"
+       "runtime/debug"
        "sort"
        "strings"
 
        "github.com/sirupsen/logrus"
 )
 
+const EXIT_INVALIDARGUMENT = 2
+
 type Handler interface {
        RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int
 }
@@ -35,7 +38,13 @@ func (f HandlerFunc) RunCommand(prog string, args []string, stdin io.Reader, std
 // 0.
 var Version versionCommand
 
-var version = "dev"
+var (
+       // These default version/commit strings should be set at build
+       // time: `go install -buildvcs=false -ldflags "-X
+       // git.arvados.org/arvados.git/lib/cmd.version=1.2.3"`
+       version = "dev"
+       commit  = "0000000000000000000000000000000000000000"
+)
 
 type versionCommand struct{}
 
@@ -43,6 +52,17 @@ func (versionCommand) String() string {
        return fmt.Sprintf("%s (%s)", version, runtime.Version())
 }
 
+func (versionCommand) Commit() string {
+       if bi, ok := debug.ReadBuildInfo(); ok {
+               for _, bs := range bi.Settings {
+                       if bs.Key == "vcs.revision" {
+                               return bs.Value
+                       }
+               }
+       }
+       return commit
+}
+
 func (versionCommand) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
        prog = regexp.MustCompile(` -*version$`).ReplaceAllLiteralString(prog, "")
        fmt.Fprintf(stdout, "%s %s (%s)\n", prog, version, runtime.Version())
@@ -55,12 +75,12 @@ func (versionCommand) RunCommand(prog string, args []string, stdin io.Reader, st
 //
 // Example:
 //
-//     os.Exit(Multi(map[string]Handler{
-//             "foobar": HandlerFunc(func(prog string, args []string) int {
-//                     fmt.Println(args[0])
-//                     return 2
-//             }),
-//     })("/usr/bin/multi", []string{"foobar", "baz"}, os.Stdin, os.Stdout, os.Stderr))
+//     os.Exit(Multi(map[string]Handler{
+//             "foobar": HandlerFunc(func(prog string, args []string) int {
+//                     fmt.Println(args[0])
+//                     return 2
+//             }),
+//     })("/usr/bin/multi", []string{"foobar", "baz"}, os.Stdin, os.Stdout, os.Stderr))
 //
 // ...prints "baz" and exits 2.
 type Multi map[string]Handler
@@ -86,13 +106,13 @@ func (m Multi) RunCommand(prog string, args []string, stdin io.Reader, stdout, s
        } else if len(args) < 1 {
                fmt.Fprintf(stderr, "usage: %s command [args]\n", prog)
                m.Usage(stderr)
-               return 2
+               return EXIT_INVALIDARGUMENT
        } else if cmd, ok = m[args[0]]; ok {
                return cmd.RunCommand(prog+" "+args[0], args[1:], stdin, stdout, stderr)
        } else {
                fmt.Fprintf(stderr, "%s: unrecognized command %q\n", prog, args[0])
                m.Usage(stderr)
-               return 2
+               return EXIT_INVALIDARGUMENT
        }
 }