forked from toolshed/abra
		
	
		
			
				
	
	
		
			142 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package recipe
 | 
						|
 | 
						|
import (
 | 
						|
	"coopcloud.tech/abra/cli/internal"
 | 
						|
	"coopcloud.tech/abra/pkg/autocomplete"
 | 
						|
	"coopcloud.tech/abra/pkg/formatter"
 | 
						|
	"coopcloud.tech/abra/pkg/i18n"
 | 
						|
	"coopcloud.tech/abra/pkg/lint"
 | 
						|
	"coopcloud.tech/abra/pkg/log"
 | 
						|
	"github.com/spf13/cobra"
 | 
						|
)
 | 
						|
 | 
						|
var RecipeLintCommand = &cobra.Command{
 | 
						|
	Use:     i18n.G("lint <recipe> [flags]"),
 | 
						|
	Short:   i18n.G("Lint a recipe"),
 | 
						|
	Aliases: []string{i18n.G("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.GetEnsureContext()); err != nil {
 | 
						|
			log.Fatal(err)
 | 
						|
		}
 | 
						|
 | 
						|
		headers := []string{
 | 
						|
			i18n.G("ref"),
 | 
						|
			i18n.G("rule"),
 | 
						|
			i18n.G("severity"),
 | 
						|
			i18n.G("satisfied"),
 | 
						|
			i18n.G("skipped"),
 | 
						|
			i18n.G("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.Debug(i18n.G("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 == i18n.G("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 {
 | 
						|
			if err := formatter.PrintTable(table); err != nil {
 | 
						|
				log.Fatal(err)
 | 
						|
			}
 | 
						|
 | 
						|
			for _, warnMsg := range warnMessages {
 | 
						|
				log.Warn(warnMsg)
 | 
						|
			}
 | 
						|
 | 
						|
			if hasError {
 | 
						|
				log.Warn(i18n.G("critical errors present in %s config", recipe.Name))
 | 
						|
			}
 | 
						|
		}
 | 
						|
	},
 | 
						|
}
 | 
						|
 | 
						|
var (
 | 
						|
	onlyError bool
 | 
						|
)
 | 
						|
 | 
						|
func init() {
 | 
						|
	RecipeLintCommand.Flags().BoolVarP(
 | 
						|
		&internal.Chaos,
 | 
						|
		i18n.G("chaos"),
 | 
						|
		i18n.G("C"),
 | 
						|
		false,
 | 
						|
		i18n.G("ignore uncommitted recipes changes"),
 | 
						|
	)
 | 
						|
 | 
						|
	RecipeLintCommand.Flags().BoolVarP(
 | 
						|
		&onlyError,
 | 
						|
		i18n.G("error"),
 | 
						|
		i18n.G("e"),
 | 
						|
		false,
 | 
						|
		i18n.G("only show errors"),
 | 
						|
	)
 | 
						|
}
 |