X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/4a2dc82a1acce855151928abe0030e1dd7dbf728..7591486e80665e7eb0213f0204949139da8652c0:/lib/cmd/cmd.go diff --git a/lib/cmd/cmd.go b/lib/cmd/cmd.go index 353167e800..a03cb90f68 100644 --- a/lib/cmd/cmd.go +++ b/lib/cmd/cmd.go @@ -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,16 +30,28 @@ 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 (versionCommand) String() string { + return fmt.Sprintf("%s (%s)", version, runtime.Version()) +} -func (v Version) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int { +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 } -// Multi is a Handler that looks up its first argument in a map, and -// invokes the resulting Handler with the remaining args. +// Multi is a Handler that looks up its first argument in a map (after +// stripping any "arvados-" or "crunch-" prefix), and invokes the +// resulting Handler with the remaining args. // // Example: // @@ -46,25 +60,33 @@ func (v Version) RunCommand(prog string, args []string, stdin io.Reader, stdout, // fmt.Println(args[0]) // return 2 // }), -// })("/usr/bin/multi", []string{"foobar", "baz"})) +// })("/usr/bin/multi", []string{"foobar", "baz"}, os.Stdin, os.Stdout, os.Stderr)) // // ...prints "baz" and exits 2. type Multi map[string]Handler func (m Multi) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int { - if len(args) < 1 { - fmt.Fprintf(stderr, "usage: %s command [args]\n", prog) - m.Usage(stderr) - return 2 - } _, basename := filepath.Split(prog) - if strings.HasPrefix(basename, "arvados-") { - basename = basename[8:] - } else if strings.HasPrefix(basename, "crunch-") { - basename = basename[7:] + if i := strings.Index(basename, "~"); i >= 0 { + // drop "~anything" suffix (arvados-dispatch-cloud's + // DeployRunnerBinary feature relies on this) + basename = basename[:i] } - if cmd, ok := m[basename]; ok { + 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) + m.Usage(stderr) + return 2 } else if cmd, ok = m[args[0]]; ok { return cmd.RunCommand(prog+" "+args[0], args[1:], stdin, stdout, stderr) } else { @@ -133,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 +}