15
15
# limitations under the License.
16
16
17
17
# This script verifies all go modules in the repository.
18
+ # go.mod and go.sum files are checked that both have been
19
+ # committed. Versions of dependencies they declare are
20
+ # checked to be in line with dependencies in k8s.io/kubernetes,
21
+ # and a warning message is printed if they differ in v<Maj>.<Min>.
18
22
19
23
set -o errexit
20
24
set -o nounset
@@ -24,14 +28,93 @@ REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
24
28
25
29
mapfile -t DIRS < <( find " ${REPO_ROOT} " -name go.mod -print0 | xargs -0 dirname)
26
30
31
+ # list_deps lists dependencies of the supplied go.mod file (dependencies
32
+ # with version "v0.0.0" are skipped). The output is a json dictionary in the
33
+ # format `{"<Dependency>": "<Version>", ...}`.
34
+ function list_deps {
35
+ gomod_file=" ${1} "
36
+ go mod edit -json " ${gomod_file} " \
37
+ | jq -r '
38
+ (
39
+ [ .Require[]
40
+ | select(.Version != "v0.0.0")
41
+ | { (.Path): .Version } ]
42
+ | add
43
+ )
44
+ '
45
+ }
46
+
47
+ # diff_version_deps lists common dependencies of the two supplied go.mod files
48
+ # whose respective versions differ (up to v<Maj>.<Min>). The output is a json
49
+ # dictionary in the format:
50
+ # `{"<Dependency>": {
51
+ # "has": "<Dependency version of the first file>",
52
+ # "wants": "<Dependency version of the second file>"
53
+ # }, ...}`
54
+ function diff_version_deps {
55
+ has_deps=" ${1} "
56
+ wants_deps=" ${2} "
57
+ jq -s '
58
+ # Extracts v<Maj>.<Min> from a semantic version string.
59
+ def major_minor_semver: capture("v(?<major>\\d+)\\.(?<minor>\\d+)")
60
+ | "v" + .major + "." + .minor;
61
+
62
+ map(to_entries) # Convert both input dicts into two separate arrays.
63
+ | add # Concatenate those two arrays into a single one.
64
+ | group_by(.key) # Group items by `.key`.
65
+ | map( # Map each selected item into { "<Dep>": {"has": "<Version0>", "wants": "<Version1>"} }.
66
+ select(
67
+ # If grouping resulted in two items, it means both arrays have this dependency.
68
+ length == 2
69
+ # Compare the v<Maj>.<Min> of both items.
70
+ and (.[0].value | major_minor_semver) != (.[1].value | major_minor_semver)
71
+ )
72
+ | { (.[0].key): { "has": .[0].value, "wants": .[1].value } }
73
+ )
74
+ | add // empty
75
+ ' " ${has_deps} " " ${wants_deps} "
76
+ }
77
+
78
+ # print_diff_version_deps prints the output of diff_version_deps as a
79
+ # human-readable multi-line text.
80
+ function print_diff_version_deps {
81
+ jq -r " to_entries | map(\" Warning: version mismatch: has \(.key)@\(.value.has), but \(.value.wants) expected\" ) | join(\"\\ n\" )"
82
+ }
83
+
84
+ # Compares versions of dependencies in the supplied go.mod to
85
+ # makes sure they are in line with the ones declared in
86
+ # k8s.io/kubernetes module and prints the result.
87
+ function compare_mod_versions {
88
+ gomod_file=" ${1} "
89
+ echo " Verifying dependency versions in ${gomod_file} against ${k8s_gomod} "
90
+ deps=" $( list_deps ${gomod_file} ) "
91
+
92
+ diff_version_deps <( echo " ${deps} " ) <( echo " ${k8s_deps} " ) \
93
+ | print_diff_version_deps " ${gomod_file} "
94
+ }
95
+
96
+ function gomod_filepath_for {
97
+ mod=" ${1} "
98
+ go list -m -json " ${mod} " | jq -r .GoMod
99
+ }
100
+
101
+ k8s_gomod=" $( gomod_filepath_for k8s.io/kubernetes) "
102
+ k8s_deps=" $( list_deps ${k8s_gomod} ) "
103
+
27
104
for dir in " ${DIRS[@]} " ; do
28
105
(
29
106
cd " $dir "
30
107
echo " Verifying ${dir} "
108
+
31
109
if ! git diff --quiet HEAD -- go.mod go.sum; then
32
110
echo " go module files are out of date"
33
111
git diff HEAD -- go.mod go.sum
34
112
exit 1
35
113
fi
114
+
115
+ compare_mod_versions " ${dir} /go.mod"
36
116
)
37
117
done
118
+
119
+ compare_mod_versions " $( gomod_filepath_for github.com/kcp-dev/client-go) "
120
+ compare_mod_versions " $( gomod_filepath_for github.com/kcp-dev/apimachinery/v2) "
0 commit comments