-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrule.go
71 lines (60 loc) · 2.05 KB
/
rule.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package config
import (
"fmt"
"github.com/nobe4/gh-not/internal/jq"
"github.com/nobe4/gh-not/internal/notifications"
)
// Rule is a struct to filter and act on notifications.
//
// rules:
// - name: showcasing conditionals
// action: debug
// filters:
// - .author.login == "dependabot[bot]"
// - >
// (.subject.title | contains("something unimportant")) or
// (.subject.title | contains("something already done"))
//
// - name: ignore ci failures for the current repo
// action: done
// filters:
// - .repository.full_name == "nobe4/gh-not"
// - .reason == "ci_activity"
type Rule struct {
Name string `mapstructure:"name"`
// Filters is a list of jq filters to filter the notifications.
// The filters are applied in order, like they are joined by 'and'.
// Having 'or' can be done via '(cond1) or (cond2) or ...'.
//
// E.g.:
// filters: ["A", "B or C"]
// Will filter `A and (B or C)`.
Filters []string `mapstructure:"filters"`
// Action is the action to take on the filtered notifications.
// See github.com/nobe4/internal/actions for list of available actions.
Action string `mapstructure:"action"`
// Args is the arguments to pass to the Action.
Args []string `mapstructure:"args"`
}
// Test tests the rule for correctness.
func (r Rule) Test() error {
for _, filter := range r.Filters {
if err := jq.Validate(filter); err != nil {
return fmt.Errorf("failed to validate rule %q, filter %s: %w", r.Name, filter, err)
}
}
return nil
}
// Filter filters the notifications with the jq filters and returns the IDs.
func (r Rule) Filter(n notifications.Notifications) (notifications.Notifications, error) {
var err error
// TODO: accept only a single filter so that we can use the jq.Filter function
// once instead of looping over the filters.
// Given that it's joined by `and`, we can just write the filters directly.
for _, filter := range r.Filters {
if n, err = jq.Filter(filter, n); err != nil {
return nil, fmt.Errorf("failed to filter notifications: %w", err)
}
}
return n, nil
}