/
moduledifference.go
74 lines (66 loc) · 2.12 KB
/
moduledifference.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
package modface
// ModuleDifference represents the interface difference between two versions of a module.
type ModuleDifference struct {
ModPath string
OldModPath string
ModPathsMatch bool
PackageRemovals map[string]PackageInterface
PackageAdditions map[string]PackageInterface
PackageChanges map[string]*PackageDifference
}
func newModuleDifference() *ModuleDifference {
md := new(ModuleDifference)
md.PackageRemovals = make(map[string]PackageInterface)
md.PackageAdditions = make(map[string]PackageInterface)
md.PackageChanges = make(map[string]*PackageDifference)
return md
}
// Any returns true if there are any differences, otherwise false.
func (md ModuleDifference) Any() bool {
numChanges := len(md.PackageAdditions) + len(md.PackageRemovals) + len(md.PackageChanges)
if !md.ModPathsMatch || numChanges > 0 {
return true
}
return false
}
// Breaking returns true if there are any breaking differences, otherwise false.
// Any package removals or packages with breaking changes are considered breaking changes
// for the module.
func (md ModuleDifference) Breaking() bool {
if !md.ModPathsMatch || len(md.PackageRemovals) > 0 {
return true
}
for _, packdiff := range md.PackageChanges {
if packdiff.Breaking() {
return true
}
}
return false
}
// Diff computes the interface difference between two versions of a module.
func Diff(oldmod, newmod *Module) *ModuleDifference {
moddiff := newModuleDifference()
moddiff.ModPath = newmod.Path
moddiff.OldModPath = oldmod.Path
moddiff.ModPathsMatch = oldmod.Path == newmod.Path
for pkgname, oldpack := range oldmod.Packages {
newpack, found := newmod.Packages[pkgname]
if !found {
// package in old but not in new, so it has been removed
moddiff.PackageRemovals[pkgname] = oldpack
} else {
packdiff := PackageDiff(oldpack, newpack)
if packdiff.Any() {
moddiff.PackageChanges[pkgname] = packdiff
}
}
}
for pkgname, newface := range newmod.Packages {
_, found := oldmod.Packages[pkgname]
if !found {
// package in new but not in old, so it has been added
moddiff.PackageAdditions[pkgname] = newface
}
}
return moddiff
}