...

Text file src/k8s.io/kubernetes/hack/update-vendor-licenses.sh

Documentation: k8s.io/kubernetes/hack

     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
    29set -o errexit
    30set -o nounset
    31set -o pipefail
    32
    33KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
    34source "${KUBE_ROOT}/hack/lib/init.sh"
    35
    36export LANG=C
    37export 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#
    45process_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
   138kube::golang::setup_env
   139export GOWORK=off
   140export GOFLAGS=-mod=mod
   141
   142# Check bash version
   143if (( 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
   154fi
   155
   156# This variable can be injected, as in the verify script.
   157LICENSE_ROOT="${LICENSE_ROOT:-${KUBE_ROOT}}"
   158cd "${LICENSE_ROOT}"
   159
   160kube::util::ensure-temp-dir
   161
   162# Save the genreated LICENSE file for each package temporarily
   163TMP_LICENSE_FILE="${KUBE_TEMP}/LICENSES.$$"
   164
   165# The directory to save all the LICENSE files
   166LICENSES_DIR="${LICENSES_DIR:-${LICENSE_ROOT}/LICENSES}"
   167mkdir -p "${LICENSES_DIR}"
   168
   169# The tmp directory to save all the LICENSE files, will move to LICENSES_DIR
   170TMP_LICENSES_DIR="${KUBE_TEMP}/LICENSES.DIR.$$"
   171mkdir -p "${TMP_LICENSES_DIR}"
   172
   173DEPS_DIR="vendor"
   174declare -Ag CONTENT
   175
   176# Put the K8S LICENSE on top
   177if [ -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"
   188fi
   189
   190# Capture all module dependencies
   191modules=$(go list -m -json all | jq -r .Path | sort -f)
   192# Loop through every vendored package
   193for 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__
   233No license could be found for ${PACKAGE} - aborting.
   234
   235Options:
   2361. Check if the upstream repository has a newer version with LICENSE, COPYRIGHT and/or
   237   COPYING files.
   2382. Contact the author of the package to ensure there is a LICENSE, COPYRIGHT and/or
   239   COPYING file present.
   2403. 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"
   253done
   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.
   262rm -f "${LICENSES_DIR}/LICENSE"
   263rm -rf "${LICENSES_DIR}/vendor"
   264rm -rf "${LICENSES_DIR}/third_party"
   265mv "${TMP_LICENSES_DIR}"/* "${LICENSES_DIR}"

View as plain text