-
Notifications
You must be signed in to change notification settings - Fork 0
/
validate.go
128 lines (114 loc) · 3.4 KB
/
validate.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package grapher
import (
"fmt"
"strings"
"sourcegraph.com/sourcegraph/srclib/graph"
)
func ValidateRefs(refs []*graph.Ref) (errs MultiError) {
refKeys := make(map[graph.RefKey]struct{})
for _, ref := range refs {
key := ref.RefKey()
if _, in := refKeys[key]; in {
errs = append(errs, fmt.Errorf("duplicate ref key: %+v", key))
} else {
refKeys[key] = struct{}{}
}
}
return
}
func ValidateDefs(defs []*graph.Def) (errs MultiError) {
defKeys := make(map[graph.DefKey]struct{})
for _, def := range defs {
key := def.DefKey
if _, in := defKeys[key]; in {
errs = append(errs, fmt.Errorf("duplicate def key: %+v", key))
} else {
defKeys[key] = struct{}{}
}
}
return
}
type MultiError []error
func (e MultiError) Error() string {
var msgs []string
for _, err := range e {
msgs = append(msgs, err.Error())
}
return strings.Join(msgs, "\n")
}
// UnresolvedInternalRefs returns a map of unresolved internal refs,
// keyed on the (nonexistent) defs they point to. CurrentRepoURI must
// be the repo URI of the repo the refs and defs were built from. It
// is used to determine whether a ref is an internal ref or not. Only
// internal refs can be checked in this way because checking
// resolution to external defs would require loading external data,
// which is outside the scope of this function.
func UnresolvedInternalRefs(currentRepoURI string, refs []*graph.Ref, defs []*graph.Def) map[graph.DefKey][]*graph.Ref {
defKeys := map[graph.DefKey]*graph.Def{}
for _, def := range defs {
// Remove CommitID because the internal refs don't have a
// DefCommitID (it's implied).
defKeyInMapKey := def.DefKey
defKeyInMapKey.CommitID = ""
defKeys[defKeyInMapKey] = def
}
unresolvedInternalRefsByDefKey := map[graph.DefKey][]*graph.Ref{}
for _, ref := range refs {
// We can only check internal refs easily here, since we've
// pulled only the data we need to do so already. Checking
// xrefs would also be useful but it would take a lot longer
// and require fetching external data.
if graph.URIEqual(ref.DefRepo, currentRepoURI) {
defKey := ref.DefKey()
if _, resolved := defKeys[defKey]; !resolved {
unresolvedInternalRefsByDefKey[defKey] = append(unresolvedInternalRefsByDefKey[defKey], ref)
}
}
}
return unresolvedInternalRefsByDefKey
}
// PopulateImpliedFields fills in fields on graph data objects that
// individual toolchains leave blank but that are implied by the
// source unit the graph data objects were built from.
func PopulateImpliedFields(repo, commitID, unitType, unit string, o *Output) {
for _, def := range o.Defs {
def.UnitType = unitType
def.Unit = unit
def.Repo = repo
def.CommitID = commitID
if len(def.Data) == 0 {
def.Data = []byte(`{}`)
}
}
for _, ref := range o.Refs {
ref.Repo = repo
ref.UnitType = unitType
ref.Unit = unit
ref.CommitID = commitID
// Treat an empty repository URI as referring to the current
// repository.
if ref.DefRepo == "" {
ref.DefRepo = repo
if ref.DefUnit == "" {
ref.DefUnitType = unitType
ref.DefUnit = unit
}
}
if ref.DefUnitType == "" {
// default DefUnitType to same unit type as the ref itself
ref.DefUnitType = unitType
}
}
for _, doc := range o.Docs {
doc.UnitType = unitType
doc.Unit = unit
doc.Repo = repo
doc.CommitID = commitID
}
for _, ann := range o.Anns {
ann.UnitType = unitType
ann.Unit = unit
ann.Repo = repo
ann.CommitID = commitID
}
}