02d8e63a98
Adds project-level configuration and per-job suppression directives:
.glint.yml (searched from pipeline dir up to the git root):
- ignore: [GL007, GL032] — suppress rules globally for the project
- severity: {GL004: warning} — override rule severity (error/warning/ignore)
- stages: [quality] — extra stages beyond the pipeline's stages: block
- token: / url: / cache_dir: — defaults for flags; lower priority than
CLI flags and environment variables
Inline suppression (# glint: ignore):
- Place "# glint: ignore GL007" immediately before a job definition to
suppress that rule for the specific job only
- Multiple rules: "# glint: ignore GL007, GL032" (comma or space separated)
- Wildcard: "# glint: ignore all" suppresses every finding for the job
- Suppressions are scoped to the annotated job; pipeline-level findings
are unaffected
- Parsed from yaml.Node head/line comments in the first parse pass;
stored in Pipeline.Suppressions (root file only, not includes)
New packages: internal/config (Load, walk-up search, .git boundary stop)
New files: cmd/glint/filter.go (applyConfig, isSuppressed helpers)
Tests: config_test.go, parser_suppress_test.go, filter_test.go
Validate fixtures: testdata/config_ignored/, config_severity/, config_suppress/
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.k3nny.fr/glint/internal/config"
|
|
"git.k3nny.fr/glint/internal/linter"
|
|
)
|
|
|
|
// applyConfig filters and adjusts findings according to the project config
|
|
// and inline suppression comments parsed from the pipeline YAML.
|
|
//
|
|
// Processing order:
|
|
// 1. Build a combined ignore set from config.Ignore and any severity entry
|
|
// whose value is "ignore".
|
|
// 2. Drop findings whose rule is in the ignore set.
|
|
// 3. Drop findings suppressed by an inline "# glint: ignore" comment on the
|
|
// job definition (from p.Suppressions).
|
|
// 4. Apply severity overrides ("error" / "warning") from config.Severity.
|
|
func applyConfig(findings []linter.Finding, cfg config.Config, suppressions map[string][]string) []linter.Finding {
|
|
// Build the global ignore set (uppercased rule IDs).
|
|
ignoreSet := make(map[string]bool, len(cfg.Ignore))
|
|
for _, r := range cfg.Ignore {
|
|
ignoreSet[strings.ToUpper(r)] = true
|
|
}
|
|
// Severity entries with value "ignore" are equivalent to Ignore entries.
|
|
sevMap := make(map[string]string, len(cfg.Severity)) // upperRule → lowerLevel
|
|
for rule, sev := range cfg.Severity {
|
|
upper := strings.ToUpper(rule)
|
|
lower := strings.ToLower(sev)
|
|
sevMap[upper] = lower
|
|
if lower == "ignore" {
|
|
ignoreSet[upper] = true
|
|
}
|
|
}
|
|
|
|
if len(ignoreSet) == 0 && len(sevMap) == 0 && len(suppressions) == 0 {
|
|
return findings
|
|
}
|
|
|
|
kept := findings[:0:0] // reuse underlying array but return fresh slice
|
|
for _, f := range findings {
|
|
ruleUpper := strings.ToUpper(f.Rule)
|
|
|
|
// Global ignore.
|
|
if ignoreSet[ruleUpper] {
|
|
continue
|
|
}
|
|
|
|
// Inline suppression.
|
|
if isSuppressed(f.Job, ruleUpper, suppressions) {
|
|
continue
|
|
}
|
|
|
|
// Severity override.
|
|
if level, ok := sevMap[ruleUpper]; ok {
|
|
switch level {
|
|
case "error":
|
|
f.Severity = linter.Error
|
|
case "warning":
|
|
f.Severity = linter.Warning
|
|
}
|
|
}
|
|
|
|
kept = append(kept, f)
|
|
}
|
|
return kept
|
|
}
|
|
|
|
// isSuppressed reports whether jobName has a "# glint: ignore" directive that
|
|
// covers ruleUpper. The wildcard entry "*" (from "# glint: ignore all")
|
|
// suppresses every rule.
|
|
func isSuppressed(jobName, ruleUpper string, suppressions map[string][]string) bool {
|
|
if jobName == "" || len(suppressions) == 0 {
|
|
return false
|
|
}
|
|
rules, ok := suppressions[jobName]
|
|
if !ok {
|
|
return false
|
|
}
|
|
for _, r := range rules {
|
|
if r == "*" || r == ruleUpper {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|