diff --git a/.golangci.yml b/.golangci.yml index 89dedd05..858ff82f 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -27,9 +27,14 @@ linters: - exptostd - nilnesserr - usetesting + - exhaustruct issues: max-same-issues: 0 + exclude-rules: + - path: ^.*_test\.go$ + linters: + - exhaustruct linters-settings: goimports: @@ -40,3 +45,23 @@ linters-settings: enable-all: true nakedret: max-func-lines: 0 + exhaustruct: + exclude: + - net/http\..+ + - crypto/tls\..+ + - encoding/xml\..+ + - .+/checks\.badMatcher + - .+/checks\.Problem + - .+/checks\.exprProblem + - .+/checks\..+Settings + - .+/config\.Match + - .+/discovery\.Entry + - .+/parser\.Rule + - .+/parser\.ParseError + - .+/parser\.VectorSelector + - .+/promapi\.MetricTimeRange + - github.com/prometheus/.+\..+ + - github.com/urfave/cli/.+ + - gitlab.com/gitlab-org/api/.+ + - github.com/google/go-github/.+ + - github.com/hashicorp/hcl/.+ diff --git a/cmd/pint/ci.go b/cmd/pint/ci.go index 8f482b30..56c77638 100644 --- a/cmd/pint/ci.go +++ b/cmd/pint/ci.go @@ -289,7 +289,7 @@ func detectCI(cfg *config.CI) *config.CI { if cfg == nil { isNil = true - cfg = &config.CI{} + cfg = &config.CI{} // nolint:exhaustruct } if bb := os.Getenv("GITHUB_BASE_REF"); bb != "" { @@ -309,7 +309,7 @@ func detectRepository(cfg *config.Repository) *config.Repository { if cfg == nil { isNil = true - cfg = &config.Repository{} + cfg = &config.Repository{} // nolint:exhaustruct } if os.Getenv("GITHUB_ACTION") != "" { @@ -342,7 +342,7 @@ func detectGithubActions(gh *config.GitHub) *config.GitHub { if gh == nil { isNil = true - gh = &config.GitHub{Timeout: time.Minute.String()} + gh = &config.GitHub{Timeout: time.Minute.String()} // nolint:exhaustruct } if repo := os.Getenv("GITHUB_REPOSITORY"); repo != "" { diff --git a/cmd/pint/lint.go b/cmd/pint/lint.go index 1a15d25e..eebc3945 100644 --- a/cmd/pint/lint.go +++ b/cmd/pint/lint.go @@ -192,6 +192,7 @@ func verifyOwners(entries []discovery.Entry, allowedOwners []*regexp.Regexp) (re Path: entry.Path, ModifiedLines: entry.ModifiedLines, Rule: entry.Rule, + Owner: "", Problem: checks.Problem{ Lines: entry.Rule.Lines, Reporter: discovery.RuleOwnerComment, @@ -211,6 +212,7 @@ func verifyOwners(entries []discovery.Entry, allowedOwners []*regexp.Regexp) (re Path: entry.Path, ModifiedLines: entry.ModifiedLines, Rule: entry.Rule, + Owner: "", Problem: checks.Problem{ Lines: entry.Rule.Lines, Reporter: discovery.RuleOwnerComment, diff --git a/cmd/pint/scan.go b/cmd/pint/scan.go index 5b5161ab..1a655bb9 100644 --- a/cmd/pint/scan.go +++ b/cmd/pint/scan.go @@ -102,7 +102,7 @@ func checkRules(ctx context.Context, workers int, isOffline bool, gen *config.Pr checkList := cfg.GetChecksForEntry(ctx, gen, entry) for _, check := range checkList { checkIterationChecks.Inc() - if check.Meta().IsOnline { + if check.Meta().Online { onlineChecksCount.Inc() } else { offlineChecksCount.Inc() diff --git a/cmd/pint/tests/0083_github_action.txt b/cmd/pint/tests/0083_github_action.txt index 6033db1b..6fdadaf1 100644 --- a/cmd/pint/tests/0083_github_action.txt +++ b/cmd/pint/tests/0083_github_action.txt @@ -61,4 +61,3 @@ groups: -- src/.pint.hcl -- repository {} - diff --git a/cmd/pint/tests/0122_lint_owner_allowed.txt b/cmd/pint/tests/0122_lint_owner_allowed.txt index 571a9ead..7eed9a7d 100644 --- a/cmd/pint/tests/0122_lint_owner_allowed.txt +++ b/cmd/pint/tests/0122_lint_owner_allowed.txt @@ -5,7 +5,7 @@ cmp stderr stderr.txt -- stderr.txt -- level=INFO msg="Loading configuration file" path=.pint.hcl level=INFO msg="Finding all rules to check" paths=["rules"] -level=INFO msg="Checking Prometheus rules" entries=5 workers=10 online=true +level=INFO msg="Checking Prometheus rules" entries=6 workers=10 online=true rules/1.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: No Owner 5 | expr: up > 0 @@ -14,6 +14,10 @@ rules/1.yml:7-8 Bug: This rule is set as owned by `bob` but `bob` doesn't match 7 | - alert: Invalid 8 | expr: up == 0 +rules/1.yml:13-14 Bug: This rule is set as owned by `zed` but `zed` doesn't match any of the allowed owner values. (rule/owner) + 13 | - alert: Owner Zed + 14 | expr: up < 0 + rules/2.yml:4-5 Bug: `rule/owner` comments are required in all files, please add a `# pint file/owner $owner` somewhere in this file and/or `# pint rule/owner $owner` on top of each rule. (rule/owner) 4 | - alert: No Owner 5 | expr: up > 0 @@ -21,7 +25,7 @@ rules/2.yml:4-5 Bug: `rule/owner` comments are required in all files, please add rules/3.yml:1 Bug: This file is set as owned by `ax` but `ax` doesn't match any of the allowed owner values. (rule/owner) 1 | # pint file/owner ax -level=INFO msg="Problems found" Bug=4 +level=INFO msg="Problems found" Bug=5 level=ERROR msg="Fatal error" err="found 1 problem(s) with severity Bug or higher" -- rules/1.yml -- groups: @@ -35,6 +39,9 @@ groups: # pint rule/owner alice - alert: Owner Alice expr: up > 0 + # pint rule/owner zed + - alert: Owner Zed + expr: up < 0 -- rules/2.yml -- groups: diff --git a/cmd/pint/watch.go b/cmd/pint/watch.go index 23e1181d..73533207 100644 --- a/cmd/pint/watch.go +++ b/cmd/pint/watch.go @@ -283,7 +283,7 @@ type problemCollector struct { } func newProblemCollector(cfg config.Config, f pathFinderFunc, minSeverity checks.Severity, maxProblems int) *problemCollector { - return &problemCollector{ + return &problemCollector{ // nolint:exhaustruct finder: f, cfg: cfg, fileOwners: map[string]string{}, diff --git a/go.mod b/go.mod index 69219c17..ba64fe56 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 github.com/gkampitakis/go-snaps v0.5.8 github.com/google/go-cmp v0.6.0 - github.com/google/go-github/v63 v63.0.0 + github.com/google/go-github/v68 v68.0.0 github.com/hashicorp/hcl/v2 v2.23.0 github.com/klauspost/compress v1.17.11 github.com/neilotoole/slogt v1.1.0 diff --git a/go.sum b/go.sum index 707514e9..68784a49 100644 --- a/go.sum +++ b/go.sum @@ -69,8 +69,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE= -github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA= +github.com/google/go-github/v68 v68.0.0 h1:ZW57zeNZiXTdQ16qrDiZ0k6XucrxZ2CGmoTvcCyQG6s= +github.com/google/go-github/v68 v68.0.0/go.mod h1:K9HAUBovM2sLwM408A18h+wd9vqdLOEqTUCbnRIcx68= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/internal/checks/alerts_absent.go b/internal/checks/alerts_absent.go index d0ef793c..bb7591a0 100644 --- a/internal/checks/alerts_absent.go +++ b/internal/checks/alerts_absent.go @@ -37,7 +37,8 @@ func (c AlertsAbsentCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/alerts_annotation.go b/internal/checks/alerts_annotation.go index 9461a098..a7ceaf32 100644 --- a/internal/checks/alerts_annotation.go +++ b/internal/checks/alerts_annotation.go @@ -45,7 +45,8 @@ func (c AnnotationCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/alerts_comparison.go b/internal/checks/alerts_comparison.go index 436b0a06..e2d1b017 100644 --- a/internal/checks/alerts_comparison.go +++ b/internal/checks/alerts_comparison.go @@ -33,7 +33,8 @@ func (c ComparisonCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/alerts_count.go b/internal/checks/alerts_count.go index d44b2ed2..658a14b3 100644 --- a/internal/checks/alerts_count.go +++ b/internal/checks/alerts_count.go @@ -49,7 +49,8 @@ func (c AlertsCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/alerts_external_labels.go b/internal/checks/alerts_external_labels.go index 49c86aff..2cfe0201 100644 --- a/internal/checks/alerts_external_labels.go +++ b/internal/checks/alerts_external_labels.go @@ -31,7 +31,8 @@ func (c AlertsExternalLabelsCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/alerts_for.go b/internal/checks/alerts_for.go index 70eddfbb..4256a889 100644 --- a/internal/checks/alerts_for.go +++ b/internal/checks/alerts_for.go @@ -29,7 +29,8 @@ func (c AlertsForChecksFor) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/alerts_template.go b/internal/checks/alerts_template.go index b85976b3..6900f0a0 100644 --- a/internal/checks/alerts_template.go +++ b/internal/checks/alerts_template.go @@ -82,7 +82,8 @@ func (c TemplateCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/base.go b/internal/checks/base.go index d6c26ccd..2ec1fefc 100644 --- a/internal/checks/base.go +++ b/internal/checks/base.go @@ -120,7 +120,7 @@ type Problem struct { type CheckMeta struct { States []discovery.ChangeType - IsOnline bool + Online bool AlwaysEnabled bool } diff --git a/internal/checks/error.go b/internal/checks/error.go index 993454d1..227ab73d 100644 --- a/internal/checks/error.go +++ b/internal/checks/error.go @@ -39,7 +39,7 @@ func (c ErrorCheck) Meta() CheckMeta { discovery.Moved, discovery.Removed, }, - IsOnline: false, + Online: false, AlwaysEnabled: true, } } diff --git a/internal/checks/labels_conflict.go b/internal/checks/labels_conflict.go index a86522d8..fe78c7e6 100644 --- a/internal/checks/labels_conflict.go +++ b/internal/checks/labels_conflict.go @@ -29,7 +29,8 @@ func (c LabelsConflictCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_aggregation.go b/internal/checks/promql_aggregation.go index 421a2230..bffc7343 100644 --- a/internal/checks/promql_aggregation.go +++ b/internal/checks/promql_aggregation.go @@ -41,7 +41,8 @@ func (c AggregationCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_counter.go b/internal/checks/promql_counter.go index 8dfdeefc..ebc886a9 100644 --- a/internal/checks/promql_counter.go +++ b/internal/checks/promql_counter.go @@ -36,7 +36,8 @@ func (c CounterCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_fragile.go b/internal/checks/promql_fragile.go index 870227bd..be2bf0af 100644 --- a/internal/checks/promql_fragile.go +++ b/internal/checks/promql_fragile.go @@ -35,7 +35,8 @@ func (c FragileCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_range_query.go b/internal/checks/promql_range_query.go index 0ef939ed..8ace14f4 100644 --- a/internal/checks/promql_range_query.go +++ b/internal/checks/promql_range_query.go @@ -37,7 +37,8 @@ func (c RangeQueryCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_rate.go b/internal/checks/promql_rate.go index 3f8c44c5..0511c009 100644 --- a/internal/checks/promql_rate.go +++ b/internal/checks/promql_rate.go @@ -47,7 +47,8 @@ func (c RateCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } @@ -78,7 +79,7 @@ func (c RateCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Rule return problems } - done := &completedList{} + done := &completedList{values: nil} for _, problem := range c.checkNode(ctx, expr.Query, entries, cfg, done) { problems = append(problems, Problem{ Lines: expr.Value.Lines, diff --git a/internal/checks/promql_regexp.go b/internal/checks/promql_regexp.go index 90c3f669..69d95ffb 100644 --- a/internal/checks/promql_regexp.go +++ b/internal/checks/promql_regexp.go @@ -49,7 +49,8 @@ func (c RegexpCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_series.go b/internal/checks/promql_series.go index ce3ab669..8e8916a4 100644 --- a/internal/checks/promql_series.go +++ b/internal/checks/promql_series.go @@ -105,7 +105,8 @@ func (c SeriesCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } @@ -245,7 +246,8 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru slog.String("name", c.prom.Name()), slog.String("metric", c.prom.UptimeMetric()), ) - promUptime = &promapi.RangeQueryResult{ + promUptime = &promapi.RangeQueryResult{ // nolint:exhaustruct + URI: c.prom.URI(), Series: promapi.SeriesTimeRanges{ From: params.Start(), Until: params.End(), @@ -258,6 +260,7 @@ func (c SeriesCheck) Check(ctx context.Context, _ discovery.Path, rule parser.Ru End: params.End(), }, }, + Gaps: nil, }, } } diff --git a/internal/checks/promql_syntax.go b/internal/checks/promql_syntax.go index 9f6a2eee..5fd9203a 100644 --- a/internal/checks/promql_syntax.go +++ b/internal/checks/promql_syntax.go @@ -27,7 +27,8 @@ func (c SyntaxCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/promql_vector_matching.go b/internal/checks/promql_vector_matching.go index 1b62d6db..2b403358 100644 --- a/internal/checks/promql_vector_matching.go +++ b/internal/checks/promql_vector_matching.go @@ -39,7 +39,8 @@ func (c VectorMatchingCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } @@ -150,6 +151,7 @@ func (c VectorMatchingCheck) checkNode(ctx context.Context, node *parser.PromQLN text, severity := textAndSeverityFromError(err, c.Reporter(), c.prom.Name(), Bug) problems = append(problems, exprProblem{ text: text, + details: "", severity: severity, }) return problems @@ -318,5 +320,5 @@ func (ls labelSets) getFirstNonOverlap(bs labelSets) (labelSet, labelSet) { } } } - return labelSet{}, labelSet{} + return labelSet{}, labelSet{} // nolint:exhaustruct } diff --git a/internal/checks/query_cost.go b/internal/checks/query_cost.go index 42819cd9..d1bd711f 100644 --- a/internal/checks/query_cost.go +++ b/internal/checks/query_cost.go @@ -46,7 +46,8 @@ func (c CostCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_dependency.go b/internal/checks/rule_dependency.go index 160382f0..22f991ac 100644 --- a/internal/checks/rule_dependency.go +++ b/internal/checks/rule_dependency.go @@ -30,7 +30,8 @@ func (c RuleDependencyCheck) Meta() CheckMeta { States: []discovery.ChangeType{ discovery.Removed, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_duplicate.go b/internal/checks/rule_duplicate.go index 0520d745..578b8499 100644 --- a/internal/checks/rule_duplicate.go +++ b/internal/checks/rule_duplicate.go @@ -31,7 +31,8 @@ func (c RuleDuplicateCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_for.go b/internal/checks/rule_for.go index 2fb2f16b..b1216948 100644 --- a/internal/checks/rule_for.go +++ b/internal/checks/rule_for.go @@ -49,7 +49,8 @@ func (c RuleForCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_label.go b/internal/checks/rule_label.go index a9cddd7b..a57fbcfe 100644 --- a/internal/checks/rule_label.go +++ b/internal/checks/rule_label.go @@ -45,7 +45,8 @@ func (c LabelCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_link.go b/internal/checks/rule_link.go index 9aff968f..723830f0 100644 --- a/internal/checks/rule_link.go +++ b/internal/checks/rule_link.go @@ -49,7 +49,8 @@ func (c RuleLinkCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: true, + Online: true, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_name.go b/internal/checks/rule_name.go index a6be3ddd..50dea84d 100644 --- a/internal/checks/rule_name.go +++ b/internal/checks/rule_name.go @@ -34,7 +34,8 @@ func (c RuleNameCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_reject.go b/internal/checks/rule_reject.go index 77c23e98..80375094 100644 --- a/internal/checks/rule_reject.go +++ b/internal/checks/rule_reject.go @@ -33,7 +33,8 @@ func (c Reject) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/checks/rule_report.go b/internal/checks/rule_report.go index dae930b9..dbab0c84 100644 --- a/internal/checks/rule_report.go +++ b/internal/checks/rule_report.go @@ -28,7 +28,8 @@ func (c ReportCheck) Meta() CheckMeta { discovery.Modified, discovery.Moved, }, - IsOnline: false, + Online: false, + AlwaysEnabled: false, } } diff --git a/internal/comments/comments.go b/internal/comments/comments.go index c3c51570..c7ac5abf 100644 --- a/internal/comments/comments.go +++ b/internal/comments/comments.go @@ -151,7 +151,7 @@ func parseSnooze(s string) (snz Snooze, err error) { return Snooze{}, fmt.Errorf("invalid snooze comment, expected '$TIME $MATCH' got %q", s) } - snz = Snooze{Match: parts[1]} + snz.Match = parts[1] snz.Until, err = time.Parse(time.RFC3339, parts[0]) if err != nil { snz.Until, err = time.Parse("2006-01-02", parts[0]) @@ -177,7 +177,7 @@ func parseValue(typ Type, s string, line int) (CommentValue, error) { if s == "" { return nil, fmt.Errorf("missing %s value", RuleOwnerComment) } - return Owner{Name: s}, nil + return Owner{Name: s, Line: 0}, nil // comment attached to the rule, line numbers are unreliable case FileDisableType: if s == "" { return nil, fmt.Errorf("missing %s value", FileDisableComment) @@ -316,8 +316,9 @@ func Parse(lineno int, text string) (comments []Comment) { parsed, err := parseComment(line, lineno+index) if err != nil { comments = append(comments, Comment{ - Type: InvalidComment, - Value: Invalid{Err: CommentError{Line: lineno + index, Err: err}}, + Type: InvalidComment, + Value: Invalid{Err: CommentError{Line: lineno + index, Err: err}}, + Offset: 0, }) continue } diff --git a/internal/config/config.go b/internal/config/config.go index bc41c9ec..bac617d4 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -89,11 +89,7 @@ func (cfg *Config) GetChecksForEntry(ctx context.Context, gen *PrometheusGenerat parsedRules := make([]parsedRule, 0, len(cfg.Rules)) if entry.PathError != nil || entry.Rule.Error.Err != nil { check := checks.NewErrorCheck(entry) - parsedRules = append(parsedRules, parsedRule{ - match: defaultMatch, - name: check.Reporter(), - check: check, - }) + parsedRules = append(parsedRules, baseParsedRule(defaultMatch, check.Reporter(), check, nil)) } else { parsedRules = append(parsedRules, baseRules(proms, defaultMatch)...) for _, rule := range cfg.Rules { @@ -133,12 +129,12 @@ func getContext() *hcl.EvalContext { } func Load(path string, failOnMissing bool) (cfg Config, fromFile bool, err error) { - cfg = Config{ + cfg = Config{ // nolint:exhaustruct CI: &CI{ MaxCommits: 20, BaseBranch: "master", }, - Parser: &Parser{}, + Parser: &Parser{}, // nolint:exhaustruct Checks: &Checks{ Enabled: checks.CheckNames, Disabled: []string{}, diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 4f271bd5..55cc70ee 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -35,6 +35,27 @@ func TestConfigLoadMissingFileOk(t *testing.T) { require.False(t, ok) } +func TestConfigLoadMergeDefaults(t *testing.T) { + dir := t.TempDir() + path := path.Join(dir, "config.hcl") + err := os.WriteFile(path, []byte("parser {}\n"), 0o644) + require.NoError(t, err) + + cfg, ok, err := config.Load(path, true) + require.NoError(t, err) + require.True(t, ok) + require.NotNil(t, cfg.CI) + require.Equal(t, 20, cfg.CI.MaxCommits) +} + +func TestConfigLoadMergeDefaultsWhenMissing(t *testing.T) { + cfg, ok, err := config.Load("xxx.hcl", false) + require.NoError(t, err) + require.False(t, ok) + require.NotNil(t, cfg.CI) + require.Equal(t, 20, cfg.CI.MaxCommits) +} + func TestDisableOnlineChecksWithPrometheus(t *testing.T) { dir := t.TempDir() path := path.Join(dir, "config.hcl") diff --git a/internal/config/parsed_rule.go b/internal/config/parsed_rule.go index e7c1fcbd..ad7bf4ce 100644 --- a/internal/config/parsed_rule.go +++ b/internal/config/parsed_rule.go @@ -30,6 +30,17 @@ func newParsedRule(rule Rule, defaultStates []string, name string, check checks. } } +func baseParsedRule(match []Match, name string, check checks.RuleChecker, tags []string) parsedRule { + return parsedRule{ + match: match, + ignore: nil, + name: name, + check: check, + tags: tags, + locked: false, + } +} + func isMatch(ctx context.Context, e discovery.Entry, ignore, match []Match) bool { for _, ignore := range ignore { if ignore.IsMatch(ctx, e.Path.Name, e) { @@ -106,99 +117,26 @@ func defaultMatchStates(cmd ContextCommandVal) []string { func baseRules(proms []*promapi.FailoverGroup, match []Match) (rules []parsedRule) { rules = append(rules, - parsedRule{ - match: match, - name: checks.SyntaxCheckName, - check: checks.NewSyntaxCheck(), - }, - parsedRule{ - match: match, - name: checks.AlertForCheckName, - check: checks.NewAlertsForCheck(), - }, - parsedRule{ - match: match, - name: checks.ComparisonCheckName, - check: checks.NewComparisonCheck(), - }, - parsedRule{ - match: match, - name: checks.TemplateCheckName, - check: checks.NewTemplateCheck(), - }, - parsedRule{ - match: match, - name: checks.FragileCheckName, - check: checks.NewFragileCheck(), - }, - parsedRule{ - match: match, - name: checks.RegexpCheckName, - check: checks.NewRegexpCheck(), - }, - parsedRule{ - match: match, - name: checks.RuleDependencyCheckName, - check: checks.NewRuleDependencyCheck(), - }, + baseParsedRule(match, checks.SyntaxCheckName, checks.NewSyntaxCheck(), nil), + baseParsedRule(match, checks.AlertForCheckName, checks.NewAlertsForCheck(), nil), + baseParsedRule(match, checks.ComparisonCheckName, checks.NewComparisonCheck(), nil), + baseParsedRule(match, checks.TemplateCheckName, checks.NewTemplateCheck(), nil), + baseParsedRule(match, checks.FragileCheckName, checks.NewFragileCheck(), nil), + baseParsedRule(match, checks.RegexpCheckName, checks.NewRegexpCheck(), nil), + baseParsedRule(match, checks.RuleDependencyCheckName, checks.NewRuleDependencyCheck(), nil), ) for _, p := range proms { rules = append(rules, - parsedRule{ - match: match, - name: checks.RateCheckName, - check: checks.NewRateCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.SeriesCheckName, - check: checks.NewSeriesCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.VectorMatchingCheckName, - check: checks.NewVectorMatchingCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.RangeQueryCheckName, - check: checks.NewRangeQueryCheck(p, 0, "", checks.Warning), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.RuleDuplicateCheckName, - check: checks.NewRuleDuplicateCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.LabelsConflictCheckName, - check: checks.NewLabelsConflictCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.AlertsExternalLabelsCheckName, - check: checks.NewAlertsExternalLabelsCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.CounterCheckName, - check: checks.NewCounterCheck(p), - tags: p.Tags(), - }, - parsedRule{ - match: match, - name: checks.AlertsAbsentCheckName, - check: checks.NewAlertsAbsentCheck(p), - tags: p.Tags(), - }, + baseParsedRule(match, checks.RateCheckName, checks.NewRateCheck(p), p.Tags()), + baseParsedRule(match, checks.SeriesCheckName, checks.NewSeriesCheck(p), p.Tags()), + baseParsedRule(match, checks.VectorMatchingCheckName, checks.NewVectorMatchingCheck(p), p.Tags()), + baseParsedRule(match, checks.RangeQueryCheckName, checks.NewRangeQueryCheck(p, 0, "", checks.Warning), p.Tags()), + baseParsedRule(match, checks.RuleDuplicateCheckName, checks.NewRuleDuplicateCheck(p), p.Tags()), + baseParsedRule(match, checks.LabelsConflictCheckName, checks.NewLabelsConflictCheck(p), p.Tags()), + baseParsedRule(match, checks.AlertsExternalLabelsCheckName, checks.NewAlertsExternalLabelsCheck(p), p.Tags()), + baseParsedRule(match, checks.CounterCheckName, checks.NewCounterCheck(p), p.Tags()), + baseParsedRule(match, checks.AlertsAbsentCheckName, checks.NewAlertsAbsentCheck(p), p.Tags()), ) } @@ -207,7 +145,7 @@ func baseRules(proms []*promapi.FailoverGroup, match []Match) (rules []parsedRul func defaultRuleMatch(match []Match, defaultStates []string) []Match { if len(match) == 0 { - return []Match{{State: defaultStates}} + return []Match{{State: defaultStates}} // nolint:exhaustruct } dst := make([]Match, 0, len(match)) for _, m := range match { diff --git a/internal/config/prometheus.go b/internal/config/prometheus.go index da0e30a3..b3eeea16 100644 --- a/internal/config/prometheus.go +++ b/internal/config/prometheus.go @@ -190,6 +190,7 @@ func NewPrometheusGenerator(cfg Config, metricsRegistry *prometheus.Registry) *P return &PrometheusGenerator{ metricsRegistry: metricsRegistry, cfg: cfg, + servers: nil, } } diff --git a/internal/discovery/git_branch.go b/internal/discovery/git_branch.go index 1c13222c..20369efd 100644 --- a/internal/discovery/git_branch.go +++ b/internal/discovery/git_branch.go @@ -273,7 +273,7 @@ func matchEntries(before, after []Entry) (ml []matchedEntry) { slog.String("name", a.Rule.Name()), ) - m := matchedEntry{after: a, hasAfter: true} + m := matchedEntry{after: a, hasAfter: true} // nolint:exhaustruct beforeSwap := make([]Entry, 0, len(before)) var matches []Entry var matched bool @@ -318,7 +318,7 @@ func matchEntries(before, after []Entry) (ml []matchedEntry) { } for _, b := range before { - ml = append(ml, matchedEntry{before: b, hasBefore: true}) + ml = append(ml, matchedEntry{before: b, hasBefore: true}) // nolint:exhaustruct } return ml diff --git a/internal/git/changes.go b/internal/git/changes.go index 21b7ee00..bbda4f6d 100644 --- a/internal/git/changes.go +++ b/internal/git/changes.go @@ -109,10 +109,10 @@ func Changes(cmd CommandRunner, baseBranch string, filter PathFilter) ([]*FileCh } // Rest is populated inside the next loop. - change := &FileChange{ + change := &FileChange{ // nolint:exhaustruct Status: status, - Path: PathDiff{ - After: Path{ + Path: PathDiff{ // nolint:exhaustruct + After: Path{ // nolint:exhaustruct Name: dstPath, }, }, diff --git a/internal/parser/decode.go b/internal/parser/decode.go index 391b604b..632d0499 100644 --- a/internal/parser/decode.go +++ b/internal/parser/decode.go @@ -32,8 +32,9 @@ func (pn PromQLNode) MarshalJSON() ([]byte, error) { // instance with parent and children populated. func tree(expr promParser.Node, parent *PromQLNode) *PromQLNode { n := PromQLNode{ - Parent: parent, - Expr: expr, + Parent: parent, + Expr: expr, + Children: nil, } for _, child := range promParser.Children(expr) { n.Children = append(n.Children, tree(child, &n)) diff --git a/internal/parser/models.go b/internal/parser/models.go index 0ecaab77..34d1bd64 100644 --- a/internal/parser/models.go +++ b/internal/parser/models.go @@ -130,11 +130,12 @@ func (ym YamlMap) GetValue(key string) *YamlNode { func newYamlMap(key, value *yaml.Node, offset int) *YamlMap { ym := YamlMap{ + Key: newYamlNode(key, offset), + Items: nil, Lines: LineRange{ First: key.Line + offset, Last: key.Line + offset, }, - Key: newYamlNode(key, offset), } var ckey *yaml.Node @@ -163,7 +164,9 @@ func (pqle PromQLExpr) IsIdentical(b PromQLExpr) bool { func newPromQLExpr(key, val *yaml.Node, offset int) *PromQLExpr { expr := PromQLExpr{ - Value: newYamlNodeWithKey(key, val, offset), + Value: newYamlNodeWithKey(key, val, offset), + SyntaxError: nil, + Query: nil, } qlNode, err := DecodeExpr(expr.Value.Value) diff --git a/internal/promapi/cache.go b/internal/promapi/cache.go index 957dd33d..8cbd5706 100644 --- a/internal/promapi/cache.go +++ b/internal/promapi/cache.go @@ -22,6 +22,7 @@ func (e *endpointStats) hit() { e.hits++ } func (e *endpointStats) miss() { e.misses++ } func newQueryCache(maxStale time.Duration) *queryCache { + // nolint:exhaustruct return &queryCache{ entries: map[uint64]*cacheEntry{}, stats: map[string]*endpointStats{}, @@ -43,7 +44,7 @@ func (c *queryCache) endpointStats(endpoint string) *endpointStats { return e } - e = &endpointStats{} + e = &endpointStats{hits: 0, misses: 0} c.stats[endpoint] = e return e } @@ -72,8 +73,9 @@ func (c *queryCache) set(key uint64, val any, ttl time.Duration) { defer c.mu.Unlock() c.entries[key] = &cacheEntry{ - data: val, - lastGet: time.Now(), + data: val, + lastGet: time.Now(), + expiresAt: time.Time{}, } if ttl > 0 { c.entries[key].expiresAt = time.Now().Add(ttl) diff --git a/internal/promapi/failover.go b/internal/promapi/failover.go index eea03971..d90ffb28 100644 --- a/internal/promapi/failover.go +++ b/internal/promapi/failover.go @@ -59,7 +59,7 @@ type FailoverGroup struct { } func NewFailoverGroup(name, uri string, servers []*Prometheus, strictErrors bool, uptimeMetric string, include, exclude []*regexp.Regexp, tags []string) *FailoverGroup { - return &FailoverGroup{ + return &FailoverGroup{ // nolint:exhaustruct name: name, uri: uri, servers: servers, diff --git a/internal/promapi/prometheus.go b/internal/promapi/prometheus.go index 09b106bd..8139b434 100644 --- a/internal/promapi/prometheus.go +++ b/internal/promapi/prometheus.go @@ -118,7 +118,7 @@ func NewPrometheus(name, uri, publicURI string, headers map[string]string, timeo publicURI = safeURI } - prom := Prometheus{ + prom := Prometheus{ // nolint:exhaustruct name: name, unsafeURI: uri, safeURI: safeURI, diff --git a/internal/promapi/range.go b/internal/promapi/range.go index 12f11e63..bd7060f1 100644 --- a/internal/promapi/range.go +++ b/internal/promapi/range.go @@ -44,7 +44,7 @@ func (q rangeQuery) Run() queryResult { ctx, cancel := q.prom.requestContext(q.ctx) defer cancel() - qr := queryResult{} + var qr queryResult args := url.Values{} args.Set("query", q.expr) @@ -132,7 +132,7 @@ func (p *Prometheus) RangeQuery(ctx context.Context, expr string, params RangeQu results := make(chan queryResult, len(slices)) for _, s := range slices { - query := queryRequest{ + query := queryRequest{ // nolint:exhaustruct query: rangeQuery{ prom: p, ctx: ctx, @@ -165,9 +165,9 @@ func (p *Prometheus) RangeQuery(ctx context.Context, expr string, params RangeQu close(results) }() - merged := RangeQueryResult{ + merged := RangeQueryResult{ // nolint:exhaustruct URI: p.publicURI, - Series: SeriesTimeRanges{ + Series: SeriesTimeRanges{ // nolint:exhaustruct From: start, Until: end, Step: step, diff --git a/internal/reporter/bitbucket_api.go b/internal/reporter/bitbucket_api.go index 8d2230b1..9e13e640 100644 --- a/internal/reporter/bitbucket_api.go +++ b/internal/reporter/bitbucket_api.go @@ -670,7 +670,7 @@ func (bb bitBucketAPI) limitComments(src []BitBucketPendingComment) []BitBucketP Text: fmt.Sprintf(`This pint run would create %d comment(s), which is more than %d limit configured for pint. %d comments were skipped and won't be visibile on this PR.`, len(src), bb.maxComments, len(src)-bb.maxComments), Severity: "NORMAL", - Anchor: BitBucketPendingCommentAnchor{ + Anchor: BitBucketPendingCommentAnchor{ // nolint:exhaustruct DiffType: "EFFECTIVE", }, }) diff --git a/internal/reporter/github.go b/internal/reporter/github.go index 21dceeef..02f1017c 100644 --- a/internal/reporter/github.go +++ b/internal/reporter/github.go @@ -9,7 +9,7 @@ import ( "strings" "time" - "github.com/google/go-github/v63/github" + "github.com/google/go-github/v68/github" "golang.org/x/oauth2" "github.com/cloudflare/pint/internal/checks" @@ -25,7 +25,6 @@ type GithubReporter struct { version string baseURL string uploadURL string - authToken string owner string repo string timeout time.Duration @@ -68,12 +67,18 @@ func NewGithubReporter(version, baseURL, uploadURL string, timeout time.Duration slog.Int("maxComments", maxComments), slog.String("headCommit", headCommit), ) + + ts := oauth2.StaticTokenSource( + &oauth2.Token{AccessToken: token}, // nolint:exhaustruct + ) + tc := oauth2.NewClient(context.Background(), ts) + gr := GithubReporter{ + client: github.NewClient(tc), version: version, baseURL: baseURL, uploadURL: uploadURL, timeout: timeout, - authToken: token, owner: owner, repo: repo, prNum: prNum, @@ -81,12 +86,6 @@ func NewGithubReporter(version, baseURL, uploadURL string, timeout time.Duration headCommit: headCommit, } - ts := oauth2.StaticTokenSource( - &oauth2.Token{AccessToken: gr.authToken}, - ) - tc := oauth2.NewClient(context.Background(), ts) - gr.client = github.NewClient(tc) - if gr.uploadURL != "" && gr.baseURL != "" { gr.client, err = gr.client.WithEnterpriseURLs(gr.baseURL, gr.uploadURL) if err != nil { @@ -102,7 +101,7 @@ func (gr GithubReporter) Describe() string { } func (gr GithubReporter) Destinations(ctx context.Context) (_ []any, err error) { - pr := ghPR{} + var pr ghPR pr.files, err = gr.listPRFiles(ctx) return []any{pr}, err } @@ -185,11 +184,11 @@ func (gr GithubReporter) Create(ctx context.Context, dst any, p PendingComment) side, line := gr.fixCommentLine(dst, p) comment := &github.PullRequestComment{ - CommitID: github.String(gr.headCommit), - Path: github.String(p.path), - Body: github.String(p.text), - Line: github.Int(line), - Side: github.String(side), + CommitID: github.Ptr(gr.headCommit), + Path: github.Ptr(p.path), + Body: github.Ptr(p.text), + Line: github.Ptr(line), + Side: github.Ptr(side), } slog.Debug("Creating a pr comment", @@ -272,9 +271,9 @@ func (gr GithubReporter) createReview(ctx context.Context, summary Summary) erro defer cancel() review := github.PullRequestReviewRequest{ - CommitID: github.String(gr.headCommit), - Body: github.String(formatGHReviewBody(gr.version, summary)), - Event: github.String("COMMENT"), + CommitID: github.Ptr(gr.headCommit), + Body: github.Ptr(formatGHReviewBody(gr.version, summary)), + Event: github.Ptr("COMMENT"), } slog.Debug("Creating a review", slog.String("commit", review.GetCommitID()), @@ -386,7 +385,7 @@ func formatGHReviewBody(version string, summary Summary) string { func (gr GithubReporter) generalComment(ctx context.Context, body string) error { comment := github.IssueComment{ - Body: github.String(body), + Body: github.Ptr(body), } slog.Debug("Creating PR comment", slog.String("body", comment.GetBody())) diff --git a/internal/reporter/gitlab.go b/internal/reporter/gitlab.go index 1cd59ccf..ce4134de 100644 --- a/internal/reporter/gitlab.go +++ b/internal/reporter/gitlab.go @@ -84,6 +84,7 @@ func NewGitLabReporter(version, branch, uri string, timeout time.Duration, token slog.Int("maxComments", maxComments), ) gl := GitLabReporter{ + client: nil, timeout: timeout, version: version, branch: branch, @@ -124,8 +125,10 @@ func (gl GitLabReporter) Destinations(ctx context.Context) ([]any, error) { for _, id := range ids { slog.Info("Found open GitLab merge request", slog.String("branch", gl.branch), slog.Int("id", id)) dst := gitlabMR{ - userID: userID, - mrID: id, + version: nil, + diffs: nil, + userID: userID, + mrID: id, } if dst.version, err = gl.getVersions(ctx, id); err != nil { return nil, fmt.Errorf("failed to get GitLab merge request versions: %w", err) @@ -393,7 +396,7 @@ type diffLine struct { func diffLineFor(lines []diffLine, line int) (diffLine, bool) { if len(lines) == 0 { - return diffLine{}, false + return diffLine{old: 0, new: 0, wasModified: false}, false } for i, dl := range lines { @@ -424,7 +427,7 @@ func diffLineFor(lines []diffLine, line int) (diffLine, bool) { wasModified: false, }, true } - return diffLine{}, false + return diffLine{old: 0, new: 0, wasModified: false}, false } var diffRe = regexp.MustCompile(`@@ \-(\d+),(\d+) \+(\d+),(\d+) @@`) diff --git a/internal/reporter/reporter.go b/internal/reporter/reporter.go index 73d1b0d0..9960c5e4 100644 --- a/internal/reporter/reporter.go +++ b/internal/reporter/reporter.go @@ -59,7 +59,7 @@ type Summary struct { } func NewSummary(reports []Report) Summary { - return Summary{reports: reports} + return Summary{reports: reports} // nolint:exhaustruct } func (s *Summary) Report(reps ...Report) {