vault/command/main.go
2017-10-24 09:30:48 -04:00

146 lines
2.7 KiB
Go

package command
import (
"bytes"
"fmt"
"io"
"log"
"os"
"sort"
"strings"
"text/tabwriter"
"github.com/mitchellh/cli"
)
func Run(args []string) int {
// Handle -v shorthand
for _, arg := range args {
if arg == "--" {
break
}
if arg == "-v" || arg == "-version" || arg == "--version" {
args = []string{"version"}
break
}
}
cli := &cli.CLI{
Name: "vault",
Args: args,
Commands: Commands,
HelpFunc: FilterDeprecatedFunc(
FilterCommandFunc("version",
groupedHelpFunc(
cli.BasicHelpFunc("vault"),
),
),
),
Autocomplete: true,
AutocompleteNoDefaultFlags: true,
}
exitCode, err := cli.Run()
if err != nil {
fmt.Fprintf(os.Stderr, "Error executing CLI: %s\n", err.Error())
return 1
}
return exitCode
}
func FilterCommandFunc(name string, f cli.HelpFunc) cli.HelpFunc {
return func(commands map[string]cli.CommandFactory) string {
newCommands := make(map[string]cli.CommandFactory, len(commands))
for k, v := range commands {
if k != name {
newCommands[k] = v
}
}
return f(newCommands)
}
}
// FilterDeprecatedFunc filters deprecated
func FilterDeprecatedFunc(f cli.HelpFunc) cli.HelpFunc {
return func(commands map[string]cli.CommandFactory) string {
newCommands := make(map[string]cli.CommandFactory)
for k, cmdFn := range commands {
command, err := cmdFn()
if err != nil {
log.Printf("[ERR] cli: Command %q failed to load: %s", k, err)
}
if _, ok := command.(*DeprecatedCommand); ok {
continue
}
newCommands[k] = cmdFn
}
return f(newCommands)
}
}
var commonCommands = []string{
"read",
"write",
"delete",
"list",
"login",
"server",
"status",
"unwrap",
}
func groupedHelpFunc(f cli.HelpFunc) cli.HelpFunc {
return func(commands map[string]cli.CommandFactory) string {
var b bytes.Buffer
tw := tabwriter.NewWriter(&b, 0, 2, 6, ' ', 0)
fmt.Fprintf(tw, "Usage: vault <command> [args]\n\n")
fmt.Fprintf(tw, "Common commands:\n")
for _, v := range commonCommands {
printCommand(tw, v, commands[v])
}
otherCommands := make([]string, 0, len(commands))
for k := range commands {
found := false
for _, v := range commonCommands {
if k == v {
found = true
break
}
}
if !found {
otherCommands = append(otherCommands, k)
}
}
sort.Strings(otherCommands)
fmt.Fprintf(tw, "\n")
fmt.Fprintf(tw, "Other commands:\n")
for _, v := range otherCommands {
printCommand(tw, v, commands[v])
}
tw.Flush()
return strings.TrimSpace(b.String())
}
}
func printCommand(w io.Writer, name string, cmdFn cli.CommandFactory) {
cmd, err := cmdFn()
if err != nil {
panic(fmt.Sprintf("failed to load %q command: %s", name, err))
}
fmt.Fprintf(w, " %s\t%s\n", name, cmd.Synopsis())
}