lint-dependencies.sh 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #!/usr/bin/env bash
  2. # Copyright 2019 The Kubernetes Authors.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. set -o errexit
  16. set -o nounset
  17. set -o pipefail
  18. KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
  19. source "${KUBE_ROOT}/hack/lib/init.sh"
  20. # Explicitly opt into go modules, even though we're inside a GOPATH directory
  21. export GO111MODULE=on
  22. # Explicitly clear GOFLAGS, since GOFLAGS=-mod=vendor breaks dependency resolution while rebuilding vendor
  23. export GOFLAGS=
  24. # Detect problematic GOPROXY settings that prevent lookup of dependencies
  25. if [[ "${GOPROXY:-}" == "off" ]]; then
  26. kube::log::error "Cannot run with \$GOPROXY=off"
  27. exit 1
  28. fi
  29. kube::golang::verify_go_version
  30. kube::util::require-jq
  31. case "${1:-}" in
  32. "--all")
  33. echo "Checking all dependencies"
  34. filter=''
  35. ;;
  36. "-a")
  37. echo "Checking all dependencies"
  38. filter=''
  39. ;;
  40. "")
  41. # by default, skip checking golang.org/x/... dependencies... we pin to levels that match our go version for those
  42. echo "Skipping golang.org/x/... dependencies, pass --all to include"
  43. filter='select(.Path | startswith("golang.org/x/") | not) |'
  44. ;;
  45. *)
  46. kube::log::error "Unrecognized arg: ${1}"
  47. exit 1
  48. ;;
  49. esac
  50. outdated=$(go list -m -json all | jq -r "
  51. select(.Replace.Version != null) |
  52. select(.Version != .Replace.Version) |
  53. ${filter}
  54. select(.Path) |
  55. \"\(.Path)
  56. pinned: \(.Replace.Version)
  57. preferred: \(.Version)
  58. hack/pin-dependency.sh \(.Path) \(.Version)\"
  59. ")
  60. if [[ -n "${outdated}" ]]; then
  61. echo "These modules are pinned to versions different than the minimal preferred version."
  62. echo "That means that without replace directives, a different version would be selected,"
  63. echo "which breaks consumers of our published modules."
  64. echo "1. Use hack/pin-dependency.sh to switch to the preferred version for each module"
  65. echo "2. Run hack/update-vendor.sh to rebuild the vendor directory"
  66. echo "3. Run hack/lint-dependencies.sh to verify no additional changes are required"
  67. echo ""
  68. echo "${outdated}"
  69. fi
  70. unused=$(comm -23 \
  71. <(go mod edit -json | jq -r '.Replace[] | select(.New.Version != null) | .Old.Path' | sort) \
  72. <(go list -m -json all | jq -r .Path | sort))
  73. if [[ -n "${unused}" ]]; then
  74. echo ""
  75. echo "Use the given commands to remove pinned module versions that aren't actually used:"
  76. echo "${unused}" | xargs -L 1 echo 'GO111MODULE=on go mod edit -dropreplace'
  77. fi
  78. if [[ -n "${unused}${outdated}" ]]; then
  79. exit 1
  80. fi
  81. echo "All pinned versions of checked dependencies match their preferred version."
  82. exit 0