abra/cli/recipe/lint.go
decentral1se 671e1ca276
All checks were successful
continuous-integration/drone/pr Build is passing
continuous-integration/drone/push Build is passing
refactor!: cobra migrate
2024-12-27 13:32:29 +01:00

141 lines
2.5 KiB
Go

package recipe
import (
"fmt"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/autocomplete"
"coopcloud.tech/abra/pkg/formatter"
"coopcloud.tech/abra/pkg/lint"
"coopcloud.tech/abra/pkg/log"
"github.com/spf13/cobra"
)
var RecipeLintCommand = &cobra.Command{
Use: "lint <recipe> [flags]",
Short: "Lint a recipe",
Aliases: []string{"l"},
Args: cobra.MinimumNArgs(1),
ValidArgsFunction: func(
cmd *cobra.Command,
args []string,
toComplete string) ([]string, cobra.ShellCompDirective) {
return autocomplete.RecipeNameComplete()
},
Run: func(cmd *cobra.Command, args []string) {
recipe := internal.ValidateRecipe(args, cmd.Name())
if err := recipe.Ensure(internal.Chaos, internal.Offline); err != nil {
log.Fatal(err)
}
headers := []string{
"ref",
"rule",
"severity",
"satisfied",
"skipped",
"resolve",
}
table, err := formatter.CreateTable()
if err != nil {
log.Fatal(err)
}
table.Headers(headers...)
hasError := false
var rows [][]string
var warnMessages []string
for level := range lint.LintRules {
for _, rule := range lint.LintRules[level] {
if onlyError && rule.Level != "error" {
log.Debugf("skipping %s, does not have level \"error\"", rule.Ref)
continue
}
skipped := false
if rule.Skip(recipe) {
skipped = true
}
skippedOutput := "-"
if skipped {
skippedOutput = "✅"
}
satisfied := false
if !skipped {
ok, err := rule.Function(recipe)
if err != nil {
warnMessages = append(warnMessages, err.Error())
}
if !ok && rule.Level == "error" {
hasError = true
}
if ok {
satisfied = true
}
}
satisfiedOutput := "✅"
if !satisfied {
satisfiedOutput = "❌"
if skipped {
satisfiedOutput = "-"
}
}
row := []string{
rule.Ref,
rule.Description,
rule.Level,
satisfiedOutput,
skippedOutput,
rule.HowToResolve,
}
rows = append(rows, row)
table.Row(row...)
}
}
if len(rows) > 0 {
fmt.Println(table)
for _, warnMsg := range warnMessages {
log.Warn(warnMsg)
}
if hasError {
log.Warnf("critical errors present in %s config", recipe.Name)
}
}
},
}
var (
onlyError bool
)
func init() {
RecipeLintCommand.Flags().BoolVarP(
&internal.Chaos,
"chaos",
"C",
false,
"ignore uncommitted recipes changes",
)
RecipeLintCommand.Flags().BoolVarP(
&onlyError,
"error",
"e",
false,
"only show errors",
)
}