dive/runtime/ci/rules.go
2018-12-30 14:07:56 -05:00

89 lines
2.6 KiB
Go

package ci
import (
"fmt"
"github.com/dustin/go-humanize"
"github.com/logrusorgru/aurora"
"github.com/wagoodman/dive/image"
"strconv"
)
func newGenericCiRule(key string, evaluator func(*image.AnalysisResult, string) (RuleStatus, string)) *GenericCiRule {
return &GenericCiRule{
key: key,
evaluator: evaluator,
}
}
func (rule *GenericCiRule) Key() string {
return rule.key
}
func (rule *GenericCiRule) Evaluate(result *image.AnalysisResult, value string) (RuleStatus, string) {
return rule.evaluator(result, value)
}
func (status RuleStatus) String() string {
switch status {
case RulePassed:
return "PASS"
case RuleFailed:
return aurora.Bold(aurora.Inverse(aurora.Red("FAIL"))).String()
case RuleWarning:
return aurora.Blue("WARN").String()
case RuleDisabled:
return aurora.Blue("SKIP").String()
default:
return aurora.Inverse("Unknown").String()
}
}
func loadCiRules() []Rule {
var rules = make([]Rule, 0)
rules = append(rules, newGenericCiRule(
"rules.lowestEfficiency",
func(analysis *image.AnalysisResult, value string) (RuleStatus, string) {
lowestEfficiency, err := strconv.ParseFloat(value, 64)
if err != nil {
return RuleFailed, fmt.Sprintf("invalid config value ('%v'): %v", value, err)
}
if lowestEfficiency > analysis.Efficiency {
return RuleFailed, fmt.Sprintf("image efficiency is too low (efficiency=%v < threshold=%v)", analysis.Efficiency, lowestEfficiency)
}
return RulePassed, ""
},
))
rules = append(rules, newGenericCiRule(
"rules.highestWastedBytes",
func(analysis *image.AnalysisResult, value string) (RuleStatus, string) {
highestWastedBytes, err := humanize.ParseBytes(value)
if err != nil {
return RuleFailed, fmt.Sprintf("invalid config value ('%v'): %v", value, err)
}
if analysis.WastedBytes > highestWastedBytes {
return RuleFailed, fmt.Sprintf("too many bytes wasted (wasted-bytes=%v > threshold=%v)", analysis.WastedBytes, highestWastedBytes)
}
return RulePassed, ""
},
))
rules = append(rules, newGenericCiRule(
"rules.highestUserWastedPercent",
func(analysis *image.AnalysisResult, value string) (RuleStatus, string) {
highestUserWastedPercent, err := strconv.ParseFloat(value, 64)
if err != nil {
return RuleFailed, fmt.Sprintf("invalid config value ('%v'): %v", value, err)
}
if highestUserWastedPercent < analysis.WastedUserPercent {
return RuleFailed, fmt.Sprintf("too many bytes wasted, relative to the user bytes added (%%-user-wasted-bytes=%v > threshold=%v)", analysis.WastedUserPercent, highestUserWastedPercent)
}
return RulePassed, ""
},
))
return rules
}