-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
approvers.go
110 lines (98 loc) · 2.97 KB
/
approvers.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"fmt"
"reflect"
"sort"
"github.com/sirupsen/logrus"
"k8s.io/test-infra/prow/repoowners"
)
func traverseProcessMap(v reflect.Value, current string, out *map[string][]string) {
if v.Kind() == reflect.Map {
logrus.WithField("function", "traverseProcessMap").Debugln("call")
for _, key := range v.MapKeys() {
logrus.WithField("key", key.Interface()).WithField("type", key.Kind()).Debugln("found key")
content := v.MapIndex(key)
switch key.Kind() {
case reflect.String:
switch content.Kind() {
case reflect.Struct:
username := key.Interface().(string)
if _, ok := (*out)[username]; !ok {
logrus.WithField("handle", username).WithField("project", current).Debugln("create entry")
(*out)[username] = []string{current}
} else {
logrus.WithField("handle", username).WithField("project", current).Debugln("update entry")
(*out)[username] = append((*out)[username], current)
}
break
case reflect.Map:
current := key.Interface().(string)
logrus.WithField("directory", current).Debugln("detected folder to append to next handles")
traverseProcessMap(content, current, out)
break
}
break
case reflect.Ptr:
switch content.Kind() {
case reflect.Map:
traverseProcessMap(content, current, out)
break
}
break
}
}
}
}
func processApprovers(v reflect.Value, out *map[string][]string) error {
if out == nil {
return fmt.Errorf("missing output for processing approvers")
}
project := ""
traverseProcessMap(v, project, out) // v is `map[string]map[*regexp.Regexp]sets.String`
return nil
}
func getApprovers(ownersClient *repoowners.Client, org, repo, branch string, dedupe bool) (map[string][]string, error) {
owners, err := ownersClient.LoadRepoOwners(org, repo, branch)
if err != nil {
logrus.WithError(err).WithField("organization", org).WithField("repository", repo).Fatal("Unable to fetch OWNERS.")
}
approvers := getUnexportedValue(reflect.ValueOf(owners).Elem().FieldByName("approvers"))
result := map[string][]string{}
err = processApprovers(approvers, &result)
if err != nil {
return nil, err
}
for k, values := range result {
newvalues := []string{}
for _, v := range values {
if dedupe && v == "" {
newvalues = []string{fmt.Sprintf("%s/%s", org, repo)}
break
}
if v != "" {
v = fmt.Sprintf("/%s", v)
}
newvalues = append(newvalues, fmt.Sprintf("%s/%s:%s%s", org, repo, branch, v))
}
result[k] = newvalues
}
return result, nil
}
// Merge two approvers maps.
//
// This function never replaces any key that already exists in the left map (lx).
func mergeApprovers(lx, rx map[string][]string, sorting bool) map[string][]string {
for key, rv := range rx {
if lv, present := lx[key]; present {
// Then we don't want to replace it, append
lx[key] = append(lv, rv...)
} else {
// Key not in the left map so we can just shove it in
lx[key] = rv
}
if sorting {
sort.Strings(lx[key])
}
}
return lx
}