update-vendor-licenses.sh 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #!/usr/bin/env bash
  2. # Copyright 2015 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. # Update the Godeps/LICENSES document.
  16. # Generates a table of Godep dependencies and their license.
  17. #
  18. # Usage:
  19. # $0 [--create-missing] [/path/to/licenses]
  20. #
  21. # --create-missing will write the files that only exist upstream, locally.
  22. # This option is mostly used for testing as we cannot check-in any of the
  23. # additionally created files into the vendor auto-generated tree.
  24. #
  25. # Run every time a license file is added/modified within /vendor to
  26. # update /Godeps/LICENSES
  27. set -o errexit
  28. set -o nounset
  29. set -o pipefail
  30. export LANG=C
  31. export LC_ALL=C
  32. ###############################################################################
  33. # Process package content
  34. #
  35. # @param package The incoming package name
  36. # @param type The type of content (LICENSE, COPYRIGHT or COPYING)
  37. #
  38. process_content () {
  39. local package=$1
  40. local type=$2
  41. local package_root
  42. local ensure_pattern
  43. local dir_root
  44. local find_maxdepth
  45. local find_names
  46. local -a local_files=()
  47. # Necessary to expand {}
  48. case ${type} in
  49. LICENSE) find_names=(-iname 'licen[sc]e*')
  50. find_maxdepth=1
  51. # Sadly inconsistent in the wild, but mostly license files
  52. # containing copyrights, but no readme/notice files containing
  53. # licenses (except to "see license file")
  54. ensure_pattern="license|copyright"
  55. ;;
  56. # We search READMEs for copyrights and this includes notice files as well
  57. # Look in as many places as we find files matching
  58. COPYRIGHT) find_names=(-iname 'notice*' -o -iname 'readme*')
  59. find_maxdepth=3
  60. ensure_pattern="copyright"
  61. ;;
  62. COPYING) find_names=(-iname 'copying*')
  63. find_maxdepth=1
  64. ensure_pattern="license|copyright"
  65. ;;
  66. esac
  67. # Start search at package root
  68. case ${package} in
  69. github.com/*|golang.org/*|bitbucket.org/*|gonum.org/*)
  70. package_root=$(echo "${package}" |awk -F/ '{ print $1"/"$2"/"$3 }')
  71. ;;
  72. go4.org/*)
  73. package_root=$(echo "${package}" |awk -F/ '{ print $1 }')
  74. ;;
  75. gopkg.in/*)
  76. # Root of gopkg.in package always ends with '.v(number)' and my contain
  77. # more than two path elements. For example:
  78. # - gopkg.in/yaml.v2
  79. # - gopkg.in/inf.v0
  80. # - gopkg.in/square/go-jose.v2
  81. package_root=$(echo "${package}" |grep -oh '.*\.v[0-9]')
  82. ;;
  83. */*)
  84. package_root=$(echo "${package}" |awk -F/ '{ print $1"/"$2 }')
  85. ;;
  86. *)
  87. package_root="${package}"
  88. ;;
  89. esac
  90. # Find files - only root and package level
  91. local_files=()
  92. IFS=" " read -r -a local_files <<< "$(
  93. for dir_root in ${package} ${package_root}; do
  94. [[ -d ${DEPS_DIR}/${dir_root} ]] || continue
  95. # One (set) of these is fine
  96. find "${DEPS_DIR}/${dir_root}" \
  97. -xdev -follow -maxdepth ${find_maxdepth} \
  98. -type f "${find_names[@]}"
  99. done | sort -u)"
  100. local index
  101. local f
  102. index="${package}-${type}"
  103. if [[ -z "${CONTENT[${index}]-}" ]]; then
  104. for f in "${local_files[@]-}"; do
  105. if [[ -z "$f" ]]; then
  106. # Set the default value and then check it to prevent
  107. # accessing potentially empty array
  108. continue
  109. fi
  110. # Find some copyright info in any file and break
  111. if grep -E -i -wq "${ensure_pattern}" "${f}"; then
  112. CONTENT[${index}]="${f}"
  113. break
  114. fi
  115. done
  116. fi
  117. }
  118. #############################################################################
  119. # MAIN
  120. #############################################################################
  121. KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
  122. source "${KUBE_ROOT}/hack/lib/init.sh"
  123. export GO111MODULE=on
  124. # Check bash version
  125. if (( BASH_VERSINFO[0] < 4 )); then
  126. echo
  127. echo "ERROR: Bash v4+ required."
  128. # Extra help for OSX
  129. if [[ "$(uname -s)" == "Darwin" ]]; then
  130. echo
  131. echo "Ensure you are up to date on the following packages:"
  132. echo "$ brew install md5sha1sum bash jq"
  133. fi
  134. echo
  135. exit 9
  136. fi
  137. # This variable can be injected, as in the verify script.
  138. LICENSE_ROOT="${LICENSE_ROOT:-${KUBE_ROOT}}"
  139. cd "${LICENSE_ROOT}"
  140. VENDOR_LICENSE_FILE="Godeps/LICENSES"
  141. TMP_LICENSE_FILE="/tmp/Godeps.LICENSES.$$"
  142. DEPS_DIR="vendor"
  143. declare -Ag CONTENT
  144. # Put the K8S LICENSE on top
  145. (
  146. echo "================================================================================"
  147. echo "= Kubernetes licensed under: ="
  148. echo
  149. cat "${LICENSE_ROOT}/LICENSE"
  150. echo
  151. echo "= LICENSE $(kube::util::md5 "${LICENSE_ROOT}/LICENSE")"
  152. echo "================================================================================"
  153. ) > ${TMP_LICENSE_FILE}
  154. # Loop through every vendored package
  155. for PACKAGE in $(go list -m -json all | jq -r .Path | sort -f); do
  156. if [[ -e "staging/src/${PACKAGE}" ]]; then
  157. echo "$PACKAGE is a staging package, skipping" > /dev/stderr
  158. continue
  159. fi
  160. if [[ ! -e "${DEPS_DIR}/${PACKAGE}" ]]; then
  161. echo "$PACKAGE doesn't exist in vendor, skipping" > /dev/stderr
  162. continue
  163. fi
  164. process_content "${PACKAGE}" LICENSE
  165. process_content "${PACKAGE}" COPYRIGHT
  166. process_content "${PACKAGE}" COPYING
  167. # display content
  168. echo
  169. echo "================================================================================"
  170. echo "= ${DEPS_DIR}/${PACKAGE} licensed under: ="
  171. echo
  172. file=""
  173. if [[ -n "${CONTENT[${PACKAGE}-LICENSE]-}" ]]; then
  174. file="${CONTENT[${PACKAGE}-LICENSE]-}"
  175. elif [[ -n "${CONTENT[${PACKAGE}-COPYRIGHT]-}" ]]; then
  176. file="${CONTENT[${PACKAGE}-COPYRIGHT]-}"
  177. elif [[ -n "${CONTENT[${PACKAGE}-COPYING]-}" ]]; then
  178. file="${CONTENT[${PACKAGE}-COPYING]-}"
  179. fi
  180. if [[ -z "${file}" ]]; then
  181. cat > /dev/stderr << __EOF__
  182. No license could be found for ${PACKAGE} - aborting.
  183. Options:
  184. 1. Check if the upstream repository has a newer version with LICENSE, COPYRIGHT and/or
  185. COPYING files.
  186. 2. Contact the author of the package to ensure there is a LICENSE, COPYRIGHT and/or
  187. COPYING file present.
  188. 3. Do not use this package in Kubernetes.
  189. __EOF__
  190. exit 9
  191. fi
  192. cat "${file}"
  193. echo
  194. echo "= ${file} $(kube::util::md5 "${file}")"
  195. echo "================================================================================"
  196. echo
  197. done >> ${TMP_LICENSE_FILE}
  198. cat ${TMP_LICENSE_FILE} > ${VENDOR_LICENSE_FILE}