Skip to content

Commit

Permalink
Add command filter to match/ignore
Browse files Browse the repository at this point in the history
  • Loading branch information
prymitive committed Jan 20, 2022
1 parent c8e8508 commit 58e7002
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 20 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## v0.7.1

### Added

- Added `command` filter to `match` / `ignore` blocks. This allows to include
skip some checks when (for example) running `pint watch` but include them
in `pint lint` run.

## v0.7.0

### Added
Expand Down
3 changes: 2 additions & 1 deletion cmd/pint/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ func actionCI(c *cli.Context) (err error) {
log.Debug().Strs("commits", toScan.Commits()).Msg("Found commits to scan")

gitBlame := discovery.NewGitBlameLineFinder(git.RunGit, toScan.Commits())
summary := scanFiles(context.Background(), cfg, toScan, gitBlame)
ctx := context.WithValue(context.Background(), config.CommandKey, config.CICommand)
summary := scanFiles(ctx, cfg, toScan, gitBlame)

reps := []reporter.Reporter{
reporter.NewConsoleReporter(os.Stderr),
Expand Down
3 changes: 2 additions & 1 deletion cmd/pint/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ func actionLint(c *cli.Context) (err error) {
return fmt.Errorf("no matching files")
}

summary := scanFiles(context.Background(), cfg, toScan, &discovery.NoopLineFinder{})
ctx := context.WithValue(context.Background(), config.CommandKey, config.LintCommand)
summary := scanFiles(ctx, cfg, toScan, &discovery.NoopLineFinder{})

r := reporter.NewConsoleReporter(os.Stderr)
err = r.Submit(summary)
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func scanFiles(ctx context.Context, cfg config.Config, fcs discovery.FileFindRes
}

if rule.Error.Err == nil {
checkList := cfg.GetChecksForRule(path, rule)
checkList := cfg.GetChecksForRule(ctx, path, rule)
for _, check := range checkList {
check := check
scanJobs = append(scanJobs, scanJob{path: path, rule: rule, check: check, lines: lineResults})
Expand Down
4 changes: 3 additions & 1 deletion cmd/pint/tests/0025_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ level=info msg="Loading configuration file" path=.pint.hcl
"label": {
"key": "notify",
"value": "blackhole"
}
},
"command": "watch"
},
"annotation": [
{
Expand Down Expand Up @@ -125,6 +126,7 @@ rule {
}
ignore {
kind = "alerting"
command = "watch"
label "notify" {
value = "blackhole"
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func actionWatch(c *cli.Context) (err error) {
}()
log.Info().Str("address", listen).Msg("Started HTTP server")

mainCtx, cancel := context.WithCancel(context.Background())
mainCtx, cancel := context.WithCancel(context.WithValue(context.Background(), config.CommandKey, config.WatchCommand))

// start timer to run every $interval
interval := c.Duration(intervalFlag)
Expand Down
4 changes: 4 additions & 0 deletions docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ rule {
path = "(.+)"
name = "(.+)"
kind = "alerting|recording"
command = "ci|lint|watch"
annotation "(.*)" {
value = "(.*)"
}
Expand All @@ -142,6 +143,7 @@ rule {
path = "(.+)"
name = "(.+)"
kind = "alerting|recording"
command = "ci|lint|watch"
annotation "(.*)" {
value = "(.*)"
}
Expand All @@ -160,6 +162,8 @@ rule {
- `match:name` - only rules with names (`record` for recording rules and `alert` for alerting
rules) matching this pattern will be checked rule
- `match:kind` - optional rule type filter, only rule of this type will be checked
- `match:command` - optional command type filter, this allows to include or ignore rules
based on the command pint is run with `pint ci`, `pint lint` or `pint watch`.
- `match:annotation` - optional annotation filter, only alert rules with at least one
annotation matching this pattern will be checked by this rule.
- `match:label` - optional annotation filter, only rules with at least one label
Expand Down
5 changes: 3 additions & 2 deletions internal/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"context"
"encoding/json"
"fmt"
"os"
Expand Down Expand Up @@ -73,7 +74,7 @@ func (cfg Config) String() string {
return string(content)
}

func (cfg *Config) GetChecksForRule(path string, r parser.Rule) []checks.RuleChecker {
func (cfg *Config) GetChecksForRule(ctx context.Context, path string, r parser.Rule) []checks.RuleChecker {
enabled := []checks.RuleChecker{}

allChecks := []checkMeta{
Expand Down Expand Up @@ -124,7 +125,7 @@ func (cfg *Config) GetChecksForRule(path string, r parser.Rule) []checks.RuleChe
}

for _, rule := range cfg.Rules {
allChecks = append(allChecks, rule.resolveChecks(path, r, cfg.Checks.Enabled, cfg.Checks.Disabled, proms)...)
allChecks = append(allChecks, rule.resolveChecks(ctx, path, r, cfg.Checks.Enabled, cfg.Checks.Disabled, proms)...)
}

for _, cm := range allChecks {
Expand Down
4 changes: 3 additions & 1 deletion internal/config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config_test

import (
"context"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -856,6 +857,7 @@ checks {
}

dir := t.TempDir()
ctx := context.WithValue(context.Background(), config.CommandKey, config.LintCommand)
for i, tc := range testCases {
t.Run(tc.title, func(t *testing.T) {
assert := assert.New(t)
Expand All @@ -869,7 +871,7 @@ checks {
cfg, err := config.Load(path, false)
assert.NoError(err)

checks := cfg.GetChecksForRule(tc.path, tc.rule)
checks := cfg.GetChecksForRule(ctx, tc.path, tc.rule)
checkNames := make([]string, 0, len(checks))
for _, c := range checks {
checkNames = append(checkNames, c.String())
Expand Down
43 changes: 32 additions & 11 deletions internal/config/rule.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"context"
"fmt"
"regexp"
"time"
Expand All @@ -12,11 +13,23 @@ import (
"github.com/cloudflare/pint/internal/promapi"
)

var (
const (
alertingRuleType = "alerting"
recordingRuleType = "recording"
)

type (
ContextCommandKey string
ContextCommandVal string
)

var (
CommandKey ContextCommandKey = "command"
CICommand ContextCommandVal = "ci"
LintCommand ContextCommandVal = "lint"
WatchCommand ContextCommandVal = "watch"
)

type MatchLabel struct {
Key string `hcl:",label" json:"key"`
Value string `hcl:"value" json:"value"`
Expand Down Expand Up @@ -89,11 +102,12 @@ func (ma MatchAnnotation) isMatching(rule parser.Rule) bool {
}

type Match struct {
Path string `hcl:"path,optional" json:"path,omitempty"`
Name string `hcl:"name,optional" json:"name,omitempty"`
Kind string `hcl:"kind,optional" json:"kind,omitempty"`
Label *MatchLabel `hcl:"label,block" json:"label,omitempty"`
Annotation *MatchAnnotation `hcl:"annotation,block" json:"annotation,omitempty"`
Path string `hcl:"path,optional" json:"path,omitempty"`
Name string `hcl:"name,optional" json:"name,omitempty"`
Kind string `hcl:"kind,optional" json:"kind,omitempty"`
Label *MatchLabel `hcl:"label,block" json:"label,omitempty"`
Annotation *MatchAnnotation `hcl:"annotation,block" json:"annotation,omitempty"`
Command *ContextCommandVal `hcl:"command,optional" json:"command,omitempty"`
}

func (m Match) validate(allowEmpty bool) error {
Expand Down Expand Up @@ -126,14 +140,14 @@ func (m Match) validate(allowEmpty bool) error {
}
}

if !allowEmpty && m.Path == "" && m.Name == "" && m.Kind == "" && m.Label == nil && m.Annotation == nil {
if !allowEmpty && m.Path == "" && m.Name == "" && m.Kind == "" && m.Label == nil && m.Annotation == nil && m.Command == nil {
return fmt.Errorf("ignore block must have at least one condition")
}

return nil
}

func (m Match) IsMatch(path string, r parser.Rule) bool {
func (m Match) IsMatch(ctx context.Context, path string, r parser.Rule) bool {
if m.Kind != "" {
if r.AlertingRule != nil && m.Kind != alertingRuleType {
return false
Expand Down Expand Up @@ -172,6 +186,13 @@ func (m Match) IsMatch(path string, r parser.Rule) bool {
}
}

if m.Command != nil {
cmd := ctx.Value(CommandKey).(ContextCommandVal)
if cmd != *m.Command {
return false
}
}

return true
}

Expand Down Expand Up @@ -237,14 +258,14 @@ func (rule Rule) validate() (err error) {
return nil
}

func (rule Rule) resolveChecks(path string, r parser.Rule, enabledChecks, disabledChecks []string, prometheusServers []*promapi.Prometheus) []checkMeta {
func (rule Rule) resolveChecks(ctx context.Context, path string, r parser.Rule, enabledChecks, disabledChecks []string, prometheusServers []*promapi.Prometheus) []checkMeta {
enabled := []checkMeta{}

if rule.Ignore != nil && rule.Ignore.IsMatch(path, r) {
if rule.Ignore != nil && rule.Ignore.IsMatch(ctx, path, r) {
return enabled
}

if rule.Match != nil && !rule.Match.IsMatch(path, r) {
if rule.Match != nil && !rule.Match.IsMatch(ctx, path, r) {
return enabled
}

Expand Down
20 changes: 19 additions & 1 deletion internal/config/rule_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config_test

import (
"context"
"strconv"
"testing"

Expand Down Expand Up @@ -372,12 +373,29 @@ func TestMatch(t *testing.T) {
},
isMatch: false,
},
{
path: "foo.yaml",
rule: parser.Rule{},
match: config.Match{
Command: &config.LintCommand,
},
isMatch: true,
},
{
path: "foo.yaml",
rule: parser.Rule{},
match: config.Match{
Command: &config.WatchCommand,
},
isMatch: false,
},
}

ctx := context.WithValue(context.Background(), config.CommandKey, config.LintCommand)
for i, tc := range testCases {
t.Run(strconv.Itoa(i+1), func(t *testing.T) {
assert := assert.New(t)
isMatch := tc.match.IsMatch(tc.path, tc.rule)
isMatch := tc.match.IsMatch(ctx, tc.path, tc.rule)
assert.Equal(tc.isMatch, isMatch)
})
}
Expand Down

0 comments on commit 58e7002

Please sign in to comment.