17778: Merge branch 'master' into 17778-doc-update
[arvados.git] / lib / cmd / cmd.go
index 9292ef7e5ff5b3afb6012833299d9f89a7ea346c..63d7576b4cc1964b11b29a8ac199730660325f2e 100644 (file)
@@ -2,7 +2,7 @@
 //
 // SPDX-License-Identifier: Apache-2.0
 
-// package cmd helps define reusable functions that can be exposed as
+// Package cmd helps define reusable functions that can be exposed as
 // [subcommands of] command line programs.
 package cmd
 
@@ -16,6 +16,8 @@ import (
        "runtime"
        "sort"
        "strings"
+
+       "github.com/sirupsen/logrus"
 )
 
 type Handler interface {
@@ -28,11 +30,22 @@ func (f HandlerFunc) RunCommand(prog string, args []string, stdin io.Reader, std
        return f(prog, args, stdin, stdout, stderr)
 }
 
-type Version string
+// Version is a Handler that prints the package version (set at build
+// time using -ldflags) and Go runtime version to stdout, and returns
+// 0.
+var Version versionCommand
+
+var version = "dev"
+
+type versionCommand struct{}
 
-func (v Version) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
+func (versionCommand) String() string {
+       return fmt.Sprintf("%s (%s)", version, runtime.Version())
+}
+
+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, v, runtime.Version())
+       fmt.Fprintf(stdout, "%s %s (%s)\n", prog, version, runtime.Version())
        return 0
 }
 
@@ -54,9 +67,21 @@ type Multi map[string]Handler
 
 func (m Multi) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
        _, basename := filepath.Split(prog)
-       basename = strings.TrimPrefix(basename, "arvados-")
-       basename = strings.TrimPrefix(basename, "crunch-")
-       if cmd, ok := m[basename]; ok {
+       if i := strings.Index(basename, "~"); i >= 0 {
+               // drop "~anything" suffix (arvados-dispatch-cloud's
+               // DeployRunnerBinary feature relies on this)
+               basename = basename[:i]
+       }
+       cmd, ok := m[basename]
+       if !ok {
+               // "controller" command exists, and binary is named "arvados-controller"
+               cmd, ok = m[strings.TrimPrefix(basename, "arvados-")]
+       }
+       if !ok {
+               // "dispatch-slurm" command exists, and binary is named "crunch-dispatch-slurm"
+               cmd, ok = m[strings.TrimPrefix(basename, "crunch-")]
+       }
+       if ok {
                return cmd.RunCommand(prog, args, stdin, stdout, stderr)
        } else if len(args) < 1 {
                fmt.Fprintf(stderr, "usage: %s command [args]\n", prog)
@@ -130,3 +155,9 @@ func SubcommandToFront(args []string, flagset FlagSet) []string {
        copy(newargs[flagargs+1:], args[flagargs+1:])
        return newargs
 }
+
+type NoPrefixFormatter struct{}
+
+func (NoPrefixFormatter) Format(entry *logrus.Entry) ([]byte, error) {
+       return []byte(entry.Message + "\n"), nil
+}