k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/hack/update-vendor-licenses.sh (about) 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 16 # Update the LICENSES directory. 17 # Generates a table of Go dependencies and their licenses. 18 # 19 # Usage: 20 # $0 [--create-missing] [/path/to/licenses] 21 # 22 # --create-missing will write the files that only exist upstream, locally. 23 # This option is mostly used for testing as we cannot check-in any of the 24 # additionally created files into the vendor auto-generated tree. 25 # 26 # Run every time a license file is added/modified within /vendor to 27 # update /LICENSES 28 29 set -o errexit 30 set -o nounset 31 set -o pipefail 32 33 KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 34 source "${KUBE_ROOT}/hack/lib/init.sh" 35 36 export LANG=C 37 export LC_ALL=C 38 39 ############################################################################### 40 # Process package content 41 # 42 # @param package The incoming package name 43 # @param type The type of content (LICENSE, COPYRIGHT or COPYING) 44 # 45 process_content () { 46 local package=$1 47 local type=$2 48 49 local package_root 50 local ensure_pattern 51 local dir_root 52 local find_maxdepth 53 local find_names 54 local -a local_files=() 55 56 # Necessary to expand {} 57 case ${type} in 58 LICENSE) find_names=(-iname 'licen[sc]e*') 59 find_maxdepth=1 60 # Sadly inconsistent in the wild, but mostly license files 61 # containing copyrights, but no readme/notice files containing 62 # licenses (except to "see license file") 63 ensure_pattern="license|copyright" 64 ;; 65 # We search READMEs for copyrights and this includes notice files as well 66 # Look in as many places as we find files matching 67 COPYRIGHT) find_names=(-iname 'notice*' -o -iname 'readme*') 68 find_maxdepth=3 69 ensure_pattern="copyright" 70 ;; 71 COPYING) find_names=(-iname 'copying*') 72 find_maxdepth=1 73 ensure_pattern="license|copyright" 74 ;; 75 esac 76 77 # Start search at package root 78 case ${package} in 79 github.com/*|golang.org/*|bitbucket.org/*|gonum.org/*) 80 package_root=$(echo "${package}" |awk -F/ '{ print $1"/"$2"/"$3 }') 81 ;; 82 go4.org/*) 83 package_root=$(echo "${package}" |awk -F/ '{ print $1 }') 84 ;; 85 gopkg.in/*) 86 # Root of gopkg.in package always ends with '.v(number)' and my contain 87 # more than two path elements. For example: 88 # - gopkg.in/yaml.v2 89 # - gopkg.in/inf.v0 90 # - gopkg.in/square/go-jose.v2 91 package_root=$(echo "${package}" |grep -oh '.*\.v[0-9]') 92 ;; 93 */*) 94 package_root=$(echo "${package}" |awk -F/ '{ print $1"/"$2 }') 95 ;; 96 *) 97 package_root="${package}" 98 ;; 99 esac 100 101 # Find files - only root and package level 102 local_files=() 103 IFS=" " read -r -a local_files <<< "$( 104 for dir_root in ${package} ${package_root}; do 105 [[ -d ${DEPS_DIR}/${dir_root} ]] || continue 106 107 # One (set) of these is fine 108 find "${DEPS_DIR}/${dir_root}" \ 109 -xdev -follow -maxdepth ${find_maxdepth} \ 110 -type f "${find_names[@]}" 111 done | sort -u)" 112 113 local index 114 local f 115 index="${package}-${type}" 116 if [[ -z "${CONTENT[${index}]-}" ]]; then 117 for f in "${local_files[@]-}"; do 118 if [[ -z "$f" ]]; then 119 # Set the default value and then check it to prevent 120 # accessing potentially empty array 121 continue 122 fi 123 # Find some copyright info in any file and break 124 if grep -E -i -wq "${ensure_pattern}" "${f}"; then 125 CONTENT[${index}]="${f}" 126 break 127 fi 128 done 129 fi 130 } 131 132 133 ############################################################################# 134 # MAIN 135 ############################################################################# 136 137 # use modules, and use module info rather than the vendor dir for computing dependencies 138 kube::golang::setup_env 139 export GOWORK=off 140 export GOFLAGS=-mod=mod 141 142 # Check bash version 143 if (( BASH_VERSINFO[0] < 4 )); then 144 echo 145 echo "ERROR: Bash v4+ required." 146 # Extra help for OSX 147 if [[ "$(uname -s)" == "Darwin" ]]; then 148 echo 149 echo "Ensure you are up to date on the following packages:" 150 echo "$ brew install md5sha1sum bash jq" 151 fi 152 echo 153 exit 9 154 fi 155 156 # This variable can be injected, as in the verify script. 157 LICENSE_ROOT="${LICENSE_ROOT:-${KUBE_ROOT}}" 158 cd "${LICENSE_ROOT}" 159 160 kube::util::ensure-temp-dir 161 162 # Save the genreated LICENSE file for each package temporarily 163 TMP_LICENSE_FILE="${KUBE_TEMP}/LICENSES.$$" 164 165 # The directory to save all the LICENSE files 166 LICENSES_DIR="${LICENSES_DIR:-${LICENSE_ROOT}/LICENSES}" 167 mkdir -p "${LICENSES_DIR}" 168 169 # The tmp directory to save all the LICENSE files, will move to LICENSES_DIR 170 TMP_LICENSES_DIR="${KUBE_TEMP}/LICENSES.DIR.$$" 171 mkdir -p "${TMP_LICENSES_DIR}" 172 173 DEPS_DIR="vendor" 174 declare -Ag CONTENT 175 176 # Put the K8S LICENSE on top 177 if [ -f "${LICENSE_ROOT}/LICENSE" ]; then 178 ( 179 echo "================================================================================" 180 echo "= Kubernetes licensed under: =" 181 echo 182 cat "${LICENSE_ROOT}/LICENSE" 183 echo 184 echo "= LICENSE $(kube::util::md5 "${LICENSE_ROOT}/LICENSE")" 185 echo "================================================================================" 186 ) > "${TMP_LICENSE_FILE}" 187 mv "${TMP_LICENSE_FILE}" "${TMP_LICENSES_DIR}/LICENSE" 188 fi 189 190 # Capture all module dependencies 191 modules=$(go list -m -json all | jq -r .Path | sort -f) 192 # Loop through every vendored package 193 for PACKAGE in ${modules}; do 194 if [[ -e "staging/src/${PACKAGE}" ]]; then 195 echo "${PACKAGE} is a staging package, skipping" >&2 196 continue 197 fi 198 if [[ ! -e "${DEPS_DIR}/${PACKAGE}" ]]; then 199 echo "${PACKAGE} doesn't exist in ${DEPS_DIR}, skipping" >&2 200 continue 201 fi 202 203 # if there are no files vendored under this package... 204 if [[ -z "$(find "${DEPS_DIR}/${PACKAGE}" -mindepth 1 -maxdepth 1 -type f)" ]]; then 205 # and we have at least the same number of submodules as subdirectories... 206 if [[ "$(find "${DEPS_DIR}/${PACKAGE}/" -mindepth 1 -maxdepth 1 -type d | wc -l)" -le "$(echo "${modules}" | grep -cE "^${PACKAGE}/")" ]]; then 207 echo "Only submodules of ${PACKAGE} are vendored, skipping" >&2 208 continue 209 fi 210 fi 211 212 echo "${PACKAGE}" 213 214 process_content "${PACKAGE}" LICENSE 215 process_content "${PACKAGE}" COPYRIGHT 216 process_content "${PACKAGE}" COPYING 217 218 # copy content and throw error message 219 { 220 echo "= ${DEPS_DIR}/${PACKAGE} licensed under: =" 221 echo 222 223 file="" 224 if [[ -n "${CONTENT[${PACKAGE}-LICENSE]-}" ]]; then 225 file="${CONTENT[${PACKAGE}-LICENSE]-}" 226 elif [[ -n "${CONTENT[${PACKAGE}-COPYRIGHT]-}" ]]; then 227 file="${CONTENT[${PACKAGE}-COPYRIGHT]-}" 228 elif [[ -n "${CONTENT[${PACKAGE}-COPYING]-}" ]]; then 229 file="${CONTENT[${PACKAGE}-COPYING]-}" 230 fi 231 if [[ -z "${file}" ]]; then 232 cat >&2 << __EOF__ 233 No license could be found for ${PACKAGE} - aborting. 234 235 Options: 236 1. Check if the upstream repository has a newer version with LICENSE, COPYRIGHT and/or 237 COPYING files. 238 2. Contact the author of the package to ensure there is a LICENSE, COPYRIGHT and/or 239 COPYING file present. 240 3. Do not use this package in Kubernetes. 241 __EOF__ 242 exit 9 243 fi 244 245 cat "${file}" 246 echo 247 echo "= ${file} $(kube::util::md5 "${file}")" 248 } >> "${TMP_LICENSE_FILE}" 249 250 dest_dir="${TMP_LICENSES_DIR}/vendor/${PACKAGE}" 251 mkdir -p "${dest_dir}" 252 mv "${TMP_LICENSE_FILE}" "${dest_dir}/LICENSE" 253 done 254 255 # copy licenses for forked code from vendor and third_party directories 256 (cd "${KUBE_ROOT}" && \ 257 find vendor third_party -iname 'licen[sc]e*' -o -iname 'notice*' -o -iname 'copying*' | \ 258 grep -E 'third_party|forked' | \ 259 xargs tar -czf - | tar -C "${TMP_LICENSES_DIR}" -xzf -) 260 261 # Leave things like OWNERS alone. 262 rm -f "${LICENSES_DIR}/LICENSE" 263 rm -rf "${LICENSES_DIR}/vendor" 264 rm -rf "${LICENSES_DIR}/third_party" 265 mv "${TMP_LICENSES_DIR}"/* "${LICENSES_DIR}"