Add --lint-fatal option (#10815)

This keeps the previous behaviour of printing details about duplicate
rules but doesn't exit with a fatal exit code unless turned on.

Signed-off-by: David Leadbeater <dgl@dgl.cx>
This commit is contained in:
David Leadbeater 2022-06-03 23:33:39 +10:00 committed by GitHub
parent 636f7e5483
commit 355b8bcf0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -95,6 +95,9 @@ func main() {
"lint", "lint",
"Linting checks to apply to the rules specified in the config. Available options are: "+strings.Join(lintOptions, ", ")+". Use --lint=none to disable linting", "Linting checks to apply to the rules specified in the config. Available options are: "+strings.Join(lintOptions, ", ")+". Use --lint=none to disable linting",
).Default(lintOptionDuplicateRules).String() ).Default(lintOptionDuplicateRules).String()
checkConfigLintFatal := checkConfigCmd.Flag(
"lint-fatal",
"Make lint errors exit with exit code 3.").Default("false").Bool()
checkWebConfigCmd := checkCmd.Command("web-config", "Check if the web config files are valid or not.") checkWebConfigCmd := checkCmd.Command("web-config", "Check if the web config files are valid or not.")
webConfigFiles := checkWebConfigCmd.Arg( webConfigFiles := checkWebConfigCmd.Arg(
@ -111,6 +114,9 @@ func main() {
"lint", "lint",
"Linting checks to apply. Available options are: "+strings.Join(lintOptions, ", ")+". Use --lint=none to disable linting", "Linting checks to apply. Available options are: "+strings.Join(lintOptions, ", ")+". Use --lint=none to disable linting",
).Default(lintOptionDuplicateRules).String() ).Default(lintOptionDuplicateRules).String()
checkRulesLintFatal := checkRulesCmd.Flag(
"lint-fatal",
"Make lint errors exit with exit code 3.").Default("false").Bool()
checkMetricsCmd := checkCmd.Command("metrics", checkMetricsUsage) checkMetricsCmd := checkCmd.Command("metrics", checkMetricsUsage)
checkMetricsExtended := checkCmd.Flag("extended", "Print extended information related to the cardinality of the metrics.").Bool() checkMetricsExtended := checkCmd.Flag("extended", "Print extended information related to the cardinality of the metrics.").Bool()
@ -236,13 +242,13 @@ func main() {
os.Exit(CheckSD(*sdConfigFile, *sdJobName, *sdTimeout)) os.Exit(CheckSD(*sdConfigFile, *sdJobName, *sdTimeout))
case checkConfigCmd.FullCommand(): case checkConfigCmd.FullCommand():
os.Exit(CheckConfig(*agentMode, *checkConfigSyntaxOnly, newLintConfig(*checkConfigLint), *configFiles...)) os.Exit(CheckConfig(*agentMode, *checkConfigSyntaxOnly, newLintConfig(*checkConfigLint, *checkConfigLintFatal), *configFiles...))
case checkWebConfigCmd.FullCommand(): case checkWebConfigCmd.FullCommand():
os.Exit(CheckWebConfig(*webConfigFiles...)) os.Exit(CheckWebConfig(*webConfigFiles...))
case checkRulesCmd.FullCommand(): case checkRulesCmd.FullCommand():
os.Exit(CheckRules(newLintConfig(*checkRulesLint), *ruleFiles...)) os.Exit(CheckRules(newLintConfig(*checkRulesLint, *checkRulesLintFatal), *ruleFiles...))
case checkMetricsCmd.FullCommand(): case checkMetricsCmd.FullCommand():
os.Exit(CheckMetrics(*checkMetricsExtended)) os.Exit(CheckMetrics(*checkMetricsExtended))
@ -303,11 +309,14 @@ var lintError = fmt.Errorf("lint error")
type lintConfig struct { type lintConfig struct {
all bool all bool
duplicateRules bool duplicateRules bool
fatal bool
} }
func newLintConfig(stringVal string) lintConfig { func newLintConfig(stringVal string, fatal bool) lintConfig {
items := strings.Split(stringVal, ",") items := strings.Split(stringVal, ",")
ls := lintConfig{} ls := lintConfig{
fatal: fatal,
}
for _, setting := range items { for _, setting := range items {
switch setting { switch setting {
case lintOptionAll: case lintOptionAll:
@ -329,7 +338,7 @@ func (ls lintConfig) lintDuplicateRules() bool {
// CheckConfig validates configuration files. // CheckConfig validates configuration files.
func CheckConfig(agentMode, checkSyntaxOnly bool, lintSettings lintConfig, files ...string) int { func CheckConfig(agentMode, checkSyntaxOnly bool, lintSettings lintConfig, files ...string) int {
failed := false failed := false
hasLintErrors := false hasErrors := false
for _, f := range files { for _, f := range files {
ruleFiles, err := checkConfig(agentMode, f, checkSyntaxOnly) ruleFiles, err := checkConfig(agentMode, f, checkSyntaxOnly)
@ -352,7 +361,7 @@ func CheckConfig(agentMode, checkSyntaxOnly bool, lintSettings lintConfig, files
} }
failed = true failed = true
for _, err := range errs { for _, err := range errs {
hasLintErrors = hasLintErrors || errors.Is(err, lintError) hasErrors = hasErrors || !errors.Is(err, lintError)
} }
} else { } else {
fmt.Printf(" SUCCESS: %d rules found\n", n) fmt.Printf(" SUCCESS: %d rules found\n", n)
@ -360,12 +369,12 @@ func CheckConfig(agentMode, checkSyntaxOnly bool, lintSettings lintConfig, files
fmt.Println() fmt.Println()
} }
} }
if failed && hasLintErrors { if failed && hasErrors {
return lintErrExitCode
}
if failed {
return failureExitCode return failureExitCode
} }
if failed && lintSettings.fatal {
return lintErrExitCode
}
return successExitCode return successExitCode
} }
@ -573,7 +582,7 @@ func checkSDFile(filename string) ([]*targetgroup.Group, error) {
// CheckRules validates rule files. // CheckRules validates rule files.
func CheckRules(ls lintConfig, files ...string) int { func CheckRules(ls lintConfig, files ...string) int {
failed := false failed := false
hasLintErrors := false hasErrors := false
for _, f := range files { for _, f := range files {
if n, errs := checkRules(f, ls); errs != nil { if n, errs := checkRules(f, ls); errs != nil {
@ -583,19 +592,19 @@ func CheckRules(ls lintConfig, files ...string) int {
} }
failed = true failed = true
for _, err := range errs { for _, err := range errs {
hasLintErrors = hasLintErrors || errors.Is(err, lintError) hasErrors = hasErrors || !errors.Is(err, lintError)
} }
} else { } else {
fmt.Printf(" SUCCESS: %d rules found\n", n) fmt.Printf(" SUCCESS: %d rules found\n", n)
} }
fmt.Println() fmt.Println()
} }
if failed && hasLintErrors { if failed && hasErrors {
return lintErrExitCode
}
if failed {
return failureExitCode return failureExitCode
} }
if failed && ls.fatal {
return lintErrExitCode
}
return successExitCode return successExitCode
} }