Skip to content

Commit

Permalink
- add run, version and cli commands
Browse files Browse the repository at this point in the history
- more logging
- add tests for:
  - parsing goals yaml
  - cli rendering
  - normalizing arguments
- fix rendering non-args CLI
  • Loading branch information
aaabramov committed Nov 8, 2021
1 parent d9afe90 commit 2577f53
Show file tree
Hide file tree
Showing 10 changed files with 586 additions and 257 deletions.
34 changes: 34 additions & 0 deletions cmd/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cmd

import (
"fmt"
"github.com/aaabramov/goal/lib"
"strings"

"github.com/spf13/cobra"
)

// cliCmd represents the cli command
var cliCmd = &cobra.Command{
Use: "cli GOAL [--on env]",
Short: "Show CLI for specific goal",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
goal := args[0]
if cmd, exists := commands.GetWithEnv(strings.TrimSpace(goal), env); exists {
lib.Info(cmd.Cli())
} else {
msg := fmt.Sprintf("No such goal: %s", goal)
if env != "" {
msg += fmt.Sprintf(" on env \"%s\"", env)
}
lib.Fatal(msg)
}
},
}

func init() {
rootCmd.AddCommand(cliCmd)

cliCmd.Flags().StringVarP(&env, "on", "e", "", "Environment to use, example: goal cli tf-apply --on dev")
}
175 changes: 0 additions & 175 deletions cmd/commands.go

This file was deleted.

92 changes: 13 additions & 79 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,29 @@
/*
Copyright © 2021 Andrii Abramov
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd

import (
"github.com/aaabramov/goal/lib"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
"io/ioutil"
"strings"
)

var goalFile string
var env string
var commands Commands
var commands *lib.Commands

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "goal [goal to run]",
Short: "Define and safely run project scoped aliases",
Long: `Allows you to create local aliases withing directory/repository with proper assertions upon executions.`,
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
res := make([]string, len(commands.commands))
for _, command := range commands.commands {
res := make([]string, len(commands.Commands))
for _, command := range commands.Commands {
res = append(res, command.Name)
}
return res, cobra.ShellCompDirectiveNoFileComp
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
commands.exec(strings.TrimSpace(args[0]), env)
} else {
commands.render()
if len(args) == 0 {
commands.Render()
}
},
}
Expand All @@ -57,68 +38,21 @@ func init() {
cobra.OnInitialize(loadGoals)

rootCmd.PersistentFlags().StringVarP(&goalFile, "config", "c", "goal.yaml", "goals file to use")
rootCmd.Flags().StringVarP(&env, "on", "e", "", "Environment to use, example: goal tf-apply --on dev")
}

func normalizeArgs(args []string) []string {
if args == nil {
return []string{}
} else {
return args
}
}

func parseEnvCommands(name string, envs map[string]YamlEnvGoal) (commands []Command) {
for env, envCommand := range envs {
args := normalizeArgs(envCommand.Args)
commands = append(commands, Command{
Name: name,
Cmd: envCommand.Cmd,
Args: args,
Desc: envCommand.Desc,
Assert: envCommand.Assert,
Env: env,
})
}
return
}

// parseCommands from byte input (YAML)
func parseCommands(bytes []byte) error {

rawCommands := map[string]YamlGoal{}
if err := yaml.Unmarshal(bytes, &rawCommands); err != nil {
return err
}
var res []Command
for name, command := range rawCommands {
if len(command.Envs) > 1 {
res = append(res, parseEnvCommands(name, command.Envs)...)
} else {
args := normalizeArgs(command.Args)
res = append(res, Command{
Name: name,
Cmd: command.Cmd,
Args: args,
Desc: command.Desc,
Assert: command.Assert,
})
}
}
commands = Commands{commands: res}
return nil
}

func loadGoals() {
if goalFile != "" {
bytes, err := ioutil.ReadFile(goalFile)
if err != nil {
fatal("Failed to read goals file: %s", goalFile)
lib.Fatal("Failed to read goals file: %s", goalFile)
}
if err := parseCommands(bytes); err != nil {
fatal("Invalid goals file: %s", goalFile)
parsed, err := lib.ParseCommands(bytes)
if err != nil {
lib.Fatal("Invalid goals file: %s", goalFile)
} else {
commands = parsed
}
} else {
fatal("Goals filename not specified. Either create goal.yaml file or specify location explicitly with -c option")
lib.Fatal("Goals filename not specified. Either create goal.yaml file or specify location explicitly with -c option")
}
}
37 changes: 37 additions & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cmd

import (
"strings"

"github.com/spf13/cobra"
)

var env string

// runCmd represents the run command
var runCmd = &cobra.Command{
Use: "run GOAL [--on env]",
Short: "Run specified goal",
//Long: `TODO`,
Args: cobra.ExactArgs(1),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
res := make([]string, len(commands.Commands))
for _, command := range commands.Commands {
res = append(res, command.Name)
}
return res, cobra.ShellCompDirectiveNoFileComp
},
Run: func(cmd *cobra.Command, args []string) {
if len(args) > 0 {
commands.Exec(strings.TrimSpace(args[0]), env)
} else {
cmd.Help()
}
},
}

func init() {
rootCmd.AddCommand(runCmd)

runCmd.Flags().StringVarP(&env, "on", "e", "", "Environment to use, example: goal tf-apply --on dev")
}

0 comments on commit 2577f53

Please sign in to comment.