From 9fde6d3c23ae514b2f79415bf93bd32afe062ac0 Mon Sep 17 00:00:00 2001 From: Colin Chartier Date: Fri, 12 Jul 2019 11:42:43 -0400 Subject: [PATCH] Add a global commands block. --- README.md | 8 +++++++ commands/run.go | 62 +++++++++++++++++++++++++++++++----------------- config/config.go | 1 + 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 98b88a0..e35d143 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,14 @@ environments: ls -al pwd ps aux + +# the global commands block defines commands for every environment. +# note 1: environments can define a command of the same name to override these +# note 2: you must be in an environment (sanic env) to use global commands +commands: +- name: do_stuff + command: ls -al + # the deploy block tells sanic how to deal with your kubernetes resources deploy: # for the "kustomize" template language, use "distributedcontainers/templater-kustomize" diff --git a/commands/run.go b/commands/run.go index 4f1e604..ed10140 100644 --- a/commands/run.go +++ b/commands/run.go @@ -10,9 +10,36 @@ import ( "strings" ) -func runCommandAction(c *cli.Context) error { - if c.NArg() == 0 { - return newUsageError(c) +func commandsMap(cfg *config.SanicConfig, env *config.Environment) map[string]config.Command { + commands := make(map[string]config.Command) + for _, globalCommand := range cfg.Commands { + commands[globalCommand.Name] = globalCommand + } + for _, envCommand := range env.Commands { + commands[envCommand.Name] = envCommand + } + return commands +} + +func mostSimilarCommands(commands map[string]config.Command, requestedCommand string, num int) []string { + var commandList []string + for _, cmd := range commands { + commandList = append(commandList, cmd.Name) + } + sort.Slice(commandList, func(i, j int) bool { + distI := levenshtein.ComputeDistance(commandList[i], requestedCommand) + distJ := levenshtein.ComputeDistance(commandList[j], requestedCommand) + return distI < distJ + }) + if len(commandList) <= num { + return commandList + } + return commandList[:num] +} + +func runCommandAction(cliCtx *cli.Context) error { + if cliCtx.NArg() == 0 { + return newUsageError(cliCtx) } s, err := shell.Current() @@ -30,31 +57,22 @@ func runCommandAction(c *cli.Context) error { return cli.NewExitError(err.Error(), 1) } - commandName := c.Args().First() - var commandNames []string - for _, command := range env.Commands { - if command.Name == commandName { - code, err := s.ShellExec(command.Command, c.Args().Tail()) - if err == nil { - return nil - } - return cli.NewExitError(err.Error(), code) + commands := commandsMap(&cfg, env) + commandName := cliCtx.Args().First() + + if cmd, ok := commands[commandName]; ok { + code, err := s.ShellExec(cmd.Command, cliCtx.Args().Tail()) + if err == nil { + return nil } - commandNames = append(commandNames, command.Name) - } - sort.Slice(commandNames, func(i, j int) bool { - distI := levenshtein.ComputeDistance(commandNames[i], commandName) - distJ := levenshtein.ComputeDistance(commandNames[j], commandName) - return distI < distJ - }) - if len(commandNames) > 6 { - commandNames = commandNames[:6] + return cli.NewExitError(err.Error, code) } + return cli.NewExitError( fmt.Sprintf("Command %s was not found in environment %s. Did you mean one of [%s]?", commandName, s.GetSanicEnvironment(), - strings.Join(commandNames, "|"), + strings.Join(mostSimilarCommands(commands, commandName, 6), "|"), ), 1) } diff --git a/config/config.go b/config/config.go index e28ae75..e8ec813 100644 --- a/config/config.go +++ b/config/config.go @@ -41,6 +41,7 @@ type Build struct { //SanicConfig is the global structure of entries in sanic.yaml type SanicConfig struct { + Commands []Command Environments map[string]Environment Deploy Deploy Build Build