...

Text file src/k8s.io/utils/hack/verify-apidiff.sh

Documentation: k8s.io/utils/hack

     1#!/usr/bin/env bash
     2
     3# Copyright 2020 The Kubernetes Authors.
     4#
     5# Licensed under the Apache License, Version 2.0 (the "License");
     6# you may not use this file except in compliance with the License.
     7# You may obtain a copy of the License at
     8#
     9#     http://www.apache.org/licenses/LICENSE-2.0
    10#
    11# Unless required by applicable law or agreed to in writing, software
    12# distributed under the License is distributed on an "AS IS" BASIS,
    13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14# See the License for the specific language governing permissions and
    15# limitations under the License.
    16
    17set -o errexit
    18set -o nounset
    19set -o pipefail
    20
    21function usage {
    22  local script="$(basename $0)"
    23
    24  echo >&2 "Usage: ${script} [-r <branch|tag> | -d <dir>]
    25
    26This script should be run at the root of a module.
    27
    28-r <branch|tag>
    29  Compare the exported API of the local working copy with the 
    30  exported API of the local repo at the specified branch or tag.
    31
    32-d <dir>
    33  Compare the exported API of the local working copy with the 
    34  exported API of the specified directory, which should point
    35  to the root of a different version of the same module.
    36
    37Examples:
    38  ${script} -r master
    39  ${script} -r v1.10.0
    40  ${script} -r release-1.10
    41  ${script} -d /path/to/historical/version
    42"
    43  exit 1
    44}
    45
    46ref=""
    47dir=""
    48while getopts r:d: o
    49do case "$o" in
    50  r)    ref="$OPTARG";;
    51  d)    dir="$OPTARG";;
    52  [?])  usage;;
    53  esac
    54done
    55
    56# If REF and DIR are empty, print usage and error
    57if [[ -z "${ref}" && -z "${dir}" ]]; then
    58  usage;
    59fi
    60# If REF and DIR are both set, print usage and error
    61if [[ -n "${ref}" && -n "${dir}" ]]; then
    62  usage;
    63fi
    64
    65if ! which apidiff > /dev/null; then
    66  echo "Installing golang.org/x/exp/cmd/apidiff..."
    67  pushd "${TMPDIR:-/tmp}" > /dev/null
    68    go install golang.org/x/exp/cmd/apidiff@latest
    69  popd > /dev/null
    70fi
    71
    72output=$(mktemp -d -t "apidiff.output.XXXX")
    73cleanup_output () { rm -fr "${output}"; }
    74trap cleanup_output EXIT
    75
    76# If ref is set, clone . to temp dir at $ref, and set $dir to the temp dir
    77clone=""
    78base="${dir}"
    79if [[ -n "${ref}" ]]; then
    80  base="${ref}"
    81  clone=$(mktemp -d -t "apidiff.clone.XXXX")
    82  cleanup_clone_and_output () { rm -fr "${clone}"; cleanup_output; }
    83  trap cleanup_clone_and_output EXIT
    84  git clone . -q --no-tags -b "${ref}" "${clone}"
    85  dir="${clone}"
    86fi
    87
    88pushd "${dir}" >/dev/null
    89  echo "Inspecting API of ${base}..."
    90  go list ./... > packages.txt
    91  for pkg in $(cat packages.txt); do
    92    mkdir -p "${output}/${pkg}"
    93    apidiff -w "${output}/${pkg}/apidiff.output" "${pkg}"
    94  done
    95popd >/dev/null
    96
    97retval=0
    98
    99echo "Comparing with ${base}..."
   100for pkg in $(go list ./...); do
   101  # New packages are ok
   102  if [ ! -f "${output}/${pkg}/apidiff.output" ]; then
   103    continue
   104  fi
   105
   106  # Check for incompatible changes to previous packages
   107  incompatible=$(apidiff -incompatible "${output}/${pkg}/apidiff.output" "${pkg}")
   108  if [[ -n "${incompatible}" ]]; then
   109    echo >&2 "FAIL: ${pkg} contains incompatible changes:
   110${incompatible}
   111"
   112    retval=1
   113  fi
   114done
   115
   116# Check for removed packages
   117removed=$(comm -23 "${dir}/packages.txt" <(go list ./...))
   118if [[ -n "${removed}" ]]; then
   119  echo >&2 "FAIL: removed packages:
   120${removed}
   121"
   122  retval=1
   123fi
   124
   125exit $retval

View as plain text