File: verify-apidiff.sh

package info (click to toggle)
golang-k8s-utils 0.0~git20221128.99ec85e-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bookworm-backports
  • size: 912 kB
  • sloc: sh: 206; makefile: 24
file content (125 lines) | stat: -rwxr-xr-x 3,191 bytes parent folder | download
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
#!/usr/bin/env bash

# Copyright 2020 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o errexit
set -o nounset
set -o pipefail

function usage {
  local script="$(basename $0)"

  echo >&2 "Usage: ${script} [-r <branch|tag> | -d <dir>]

This script should be run at the root of a module.

-r <branch|tag>
  Compare the exported API of the local working copy with the 
  exported API of the local repo at the specified branch or tag.

-d <dir>
  Compare the exported API of the local working copy with the 
  exported API of the specified directory, which should point
  to the root of a different version of the same module.

Examples:
  ${script} -r master
  ${script} -r v1.10.0
  ${script} -r release-1.10
  ${script} -d /path/to/historical/version
"
  exit 1
}

ref=""
dir=""
while getopts r:d: o
do case "$o" in
  r)    ref="$OPTARG";;
  d)    dir="$OPTARG";;
  [?])  usage;;
  esac
done

# If REF and DIR are empty, print usage and error
if [[ -z "${ref}" && -z "${dir}" ]]; then
  usage;
fi
# If REF and DIR are both set, print usage and error
if [[ -n "${ref}" && -n "${dir}" ]]; then
  usage;
fi

if ! which apidiff > /dev/null; then
  echo "Installing golang.org/x/exp/cmd/apidiff..."
  pushd "${TMPDIR:-/tmp}" > /dev/null
    go get golang.org/x/exp/cmd/apidiff
  popd > /dev/null
fi

output=$(mktemp -d -t "apidiff.output.XXXX")
cleanup_output () { rm -fr "${output}"; }
trap cleanup_output EXIT

# If ref is set, clone . to temp dir at $ref, and set $dir to the temp dir
clone=""
base="${dir}"
if [[ -n "${ref}" ]]; then
  base="${ref}"
  clone=$(mktemp -d -t "apidiff.clone.XXXX")
  cleanup_clone_and_output () { rm -fr "${clone}"; cleanup_output; }
  trap cleanup_clone_and_output EXIT
  git clone . -q --no-tags -b "${ref}" "${clone}"
  dir="${clone}"
fi

pushd "${dir}" >/dev/null
  echo "Inspecting API of ${base}..."
  go list ./... > packages.txt
  for pkg in $(cat packages.txt); do
    mkdir -p "${output}/${pkg}"
    apidiff -w "${output}/${pkg}/apidiff.output" "${pkg}"
  done
popd >/dev/null

retval=0

echo "Comparing with ${base}..."
for pkg in $(go list ./...); do
  # New packages are ok
  if [ ! -f "${output}/${pkg}/apidiff.output" ]; then
    continue
  fi

  # Check for incompatible changes to previous packages
  incompatible=$(apidiff -incompatible "${output}/${pkg}/apidiff.output" "${pkg}")
  if [[ -n "${incompatible}" ]]; then
    echo >&2 "FAIL: ${pkg} contains incompatible changes:
${incompatible}
"
    retval=1
  fi
done

# Check for removed packages
removed=$(comm -23 "${dir}/packages.txt" <(go list ./...))
if [[ -n "${removed}" ]]; then
  echo >&2 "FAIL: removed packages:
${removed}
"
  retval=1
fi

exit $retval