mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
commit
cc8063a911
154
hack/apidiff.sh
Executable file
154
hack/apidiff.sh
Executable file
@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright 2024 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.
|
||||
|
||||
# This script checks the coding style for the Go language files using
|
||||
# golangci-lint. Which checks are enabled depends on command line flags. The
|
||||
# default is a minimal set of checks that all existing code passes without
|
||||
# issues.
|
||||
|
||||
usage () {
|
||||
cat <<EOF >&2
|
||||
Usage: $0 [-r <revision>] [directory]"
|
||||
-r <revision>: only report issues in code added since that revision. Default is
|
||||
the common base of origin/master and HEAD.
|
||||
[package]: check directory instead of everything
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||
source "${KUBE_ROOT}/hack/lib/init.sh"
|
||||
|
||||
base="$(git merge-base origin/master HEAD)"
|
||||
while getopts "r:" o; do
|
||||
case "${o}" in
|
||||
r)
|
||||
base="${OPTARG}"
|
||||
if [ ! "$base" ]; then
|
||||
echo "ERROR: -${o} needs a non-empty parameter" >&2
|
||||
echo >&2
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
# Check specific directory or everything.
|
||||
targets=("$@")
|
||||
if [ ${#targets[@]} -eq 0 ]; then
|
||||
# This lists all entries in the go.work file as absolute directory paths.
|
||||
kube::util::read-array targets < <(
|
||||
go list -f '{{.Dir}}' -m | while read -r d; do
|
||||
# We need relative paths because we will invoke apidiff in
|
||||
# different work trees.
|
||||
d="$(realpath -s --relative-to="$(pwd)" "${d}")"
|
||||
if [ "${d}" != "." ]; then
|
||||
# sub-directories have to have a leading dot.
|
||||
d="./${d}"
|
||||
fi
|
||||
echo "${d}"
|
||||
done
|
||||
)
|
||||
fi
|
||||
|
||||
# Must be a something that git can resolve to a commit.
|
||||
# "git rev-parse --verify" checks that and prints a detailed
|
||||
# error.
|
||||
base="$(git rev-parse --verify "$base")"
|
||||
|
||||
kube::golang::setup_env
|
||||
kube::util::ensure-temp-dir
|
||||
|
||||
# Install apidiff and make sure it's found.
|
||||
export GOBIN="${KUBE_TEMP}"
|
||||
PATH="${GOBIN}:${PATH}"
|
||||
echo "installing apidiff into ${GOBIN}"
|
||||
go install golang.org/x/exp/cmd/apidiff@latest
|
||||
|
||||
cd "${KUBE_ROOT}"
|
||||
|
||||
# output_name targets a target directory and prints the base name of
|
||||
# an output file for that target.
|
||||
output_name () {
|
||||
what="$1"
|
||||
|
||||
echo "${what}" | sed -e 's/[^a-zA-Z0-9_-]/_/g' -e 's/$/.out/'
|
||||
}
|
||||
|
||||
# run invokes apidiff once per target and stores the output
|
||||
# file(s) in the given directory.
|
||||
run () {
|
||||
out="$1"
|
||||
mkdir -p "$out"
|
||||
for d in "${targets[@]}"; do
|
||||
apidiff -m -w "${out}/$(output_name "${d}")" "${d}"
|
||||
done
|
||||
}
|
||||
|
||||
# First the current code.
|
||||
run "${KUBE_TEMP}/after"
|
||||
|
||||
WORKTREE="${KUBE_TEMP}/worktree"
|
||||
|
||||
# Create a copy of the repo with the base checked out.
|
||||
git worktree add -f -d "${WORKTREE}" "${base}"
|
||||
# Clean up the copy on exit.
|
||||
kube::util::trap_add "git worktree remove -f ${WORKTREE}" EXIT
|
||||
|
||||
# Base ready for apidiff.
|
||||
(
|
||||
cd "${WORKTREE}"
|
||||
run "${KUBE_TEMP}/before"
|
||||
)
|
||||
|
||||
# Now produce a report. All changes get reported because exporting some API
|
||||
# unnecessarily might also be good to know, but the final exit code will only
|
||||
# be non-zero if there are incompatible changes.
|
||||
#
|
||||
# The report is Markdown-formatted and can be copied into a PR comment verbatim.
|
||||
res=0
|
||||
echo
|
||||
compare () {
|
||||
what="$1"
|
||||
before="$2"
|
||||
after="$3"
|
||||
changes=$(apidiff -m "${before}" "${after}" 2>&1 | grep -v -e "^Ignoring internal package") || true
|
||||
echo "## ${what}"
|
||||
if [ -z "$changes" ]; then
|
||||
echo "no changes"
|
||||
else
|
||||
echo "$changes"
|
||||
echo
|
||||
fi
|
||||
incompatible=$(apidiff -incompatible -m "${before}" "${after}" 2>&1) || true
|
||||
if [ -n "$incompatible" ]; then
|
||||
res=1
|
||||
fi
|
||||
}
|
||||
|
||||
for d in "${targets[@]}"; do
|
||||
compare "${d}" "${KUBE_TEMP}/before/$(output_name "${d}")" "${KUBE_TEMP}/after/$(output_name "${d}")"
|
||||
done
|
||||
|
||||
exit "$res"
|
Loading…
Reference in New Issue
Block a user