rambleraptor commented on code in PR #103: URL: https://github.com/apache/terraform-provider-iceberg/pull/103#discussion_r3855197736
########## dev/update_licenses.sh: ########## @@ -0,0 +1,461 @@ +#!/usr/bin/env bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# Regenerate -- or verify -- the third-party license inventory that ships with +# the convenience binaries: the generated section of LICENSE-binary and the +# per-module license texts in licenses-binary/. +# +# The inventory is derived from the modules the provider binary actually links, +# not from go.mod, which also covers test-only and tooling dependencies that are +# never distributed. The linked set is computed for every GOOS/GOARCH pair that +# .goreleaser.yml builds and then unioned, so a dependency that only appears on, +# say, Windows is still accounted for. +# +# ASF policy is that "LICENSE and NOTICE must exactly represent the contents of +# the distribution they reside in" (https://infra.apache.org/licensing-howto.html), +# so this needs re-running whenever the dependency tree moves -- including when +# an `// indirect` dependency changes, which is where the drift usually hides. +# +# dev/update_licenses.sh rewrite LICENSE-binary and licenses-binary/ +# dev/update_licenses.sh --check report drift, write nothing, exit non-zero +# +# Classifications that the tooling gets wrong are pinned in +# dev/licenses/overrides.tsv rather than patched into the output by hand. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" + +LICENSE_BINARY="${REPO_ROOT}/LICENSE-binary" +LICENSES_DIR="${REPO_ROOT}/licenses-binary" +OVERRIDES_FILE="${REPO_ROOT}/dev/licenses/overrides.tsv" + +BEGIN_MARK='--- BEGIN GENERATED SECTION: dev/update_licenses.sh (do not edit by hand) ---' +END_MARK='--- END GENERATED SECTION ---' + +GO_LICENSES_VERSION="${GO_LICENSES_VERSION:-v1.6.0}" + +# Keep in sync with builds.goos / builds.goarch in .goreleaser.yml. +DEFAULT_PLATFORMS="linux/amd64 linux/arm64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64 freebsd/amd64 freebsd/arm64" +PLATFORMS="${LICENSE_PLATFORMS:-${DEFAULT_PLATFORMS}}" + +CHECK_ONLY=0 +DRIFT=0 + +usage() { + cat <<'EOF' +Usage: dev/update_licenses.sh [--check] + + (no flag) Rewrite the generated section of LICENSE-binary and the license + texts in licenses-binary/ to match the linked dependencies. + --check Report drift and exit 1 without modifying anything. + +Environment: + LICENSE_PLATFORMS Space-separated GOOS/GOARCH list to analyze. Defaults to + the full .goreleaser.yml matrix. + GO_LICENSES Path to an existing go-licenses binary. + GO_LICENSES_VERSION Version to install if one is not already on PATH. +EOF +} + +log() { printf '%s\n' "$*" >&2; } + +fail() { + printf 'error: %s\n' "$*" >&2 + exit 1 +} + +drift() { + printf '%s\n' "$*" >&2 + DRIFT=1 +} + +# Filename stem used under licenses-binary/, e.g. github.com/hashicorp/yamux -> +# LICENSE-hashicorp-yamux.txt. Drops the github.com host and the /vN major +# version suffix, both of which are noise, and keeps every other host. +slug_for() { + local mod="${1#github.com/}" + mod="$(printf '%s' "${mod}" | sed -E 's|/v[0-9]+$||')" + printf '%s' "${mod//\//-}" +} + +# Section heading used in LICENSE-binary for an SPDX identifier. An unmapped +# identifier is fatal on purpose: a license we have not seen before is a +# decision for a human, not something to guess at. +heading_for() { + case "$1" in + BSD-2-Clause) printf 'BSD 2-Clause' ;; + BSD-3-Clause) printf 'BSD 3-Clause' ;; + ISC) printf 'ISC License' ;; + MIT) printf 'MIT License' ;; + MPL-2.0) printf 'Mozilla Public License 2.0' ;; + *) return 1 ;; + esac +} + +ensure_go_licenses() { + if [[ -n "${GO_LICENSES:-}" ]]; then + [[ -x "${GO_LICENSES}" ]] || fail "GO_LICENSES=${GO_LICENSES} is not executable" + return + fi + if command -v go-licenses >/dev/null 2>&1; then + GO_LICENSES="$(command -v go-licenses)" + return + fi + local gobin="${REPO_ROOT}/build/tools" + if [[ ! -x "${gobin}/go-licenses" ]]; then + log "installing go-licenses ${GO_LICENSES_VERSION} into build/tools" + # GOFLAGS is cleared so a caller's -mod=vendor/-mod=readonly does not leak + # into the install of an unrelated module. + GOFLAGS='' GOBIN="${gobin}" go install "github.com/google/go-licenses@${GO_LICENSES_VERSION}" + fi + GO_LICENSES="${gobin}/go-licenses" +} + +# Populates ${WORK}/attributed.tsv with one row per (module, license file): +# module-path <TAB> version <TAB> license-path-within-module <TAB> spdx-id +collect() { + local template="${WORK}/report.tpl" + printf '{{range .}}{{.LicenseName}}\t{{.LicensePath}}\n{{end}}' >"${template}" + + local main_module + main_module="$(cd "${REPO_ROOT}" && go list -m)" + + : >"${WORK}/modules.raw" + : >"${WORK}/licenses.raw" + + local platform goos goarch + for platform in ${PLATFORMS}; do + goos="${platform%/*}" + goarch="${platform#*/}" + [[ "${goos}" != "${platform}" && -n "${goarch}" ]] || fail "bad platform '${platform}', want GOOS/GOARCH" + log " analyzing ${platform}" + + # Module directories, for attributing each license file to its module. + # `go list -deps .` walks the import graph of the provider's main package, + # so test-only and tool dependencies are excluded by construction. + (cd "${REPO_ROOT}" && GOOS="${goos}" GOARCH="${goarch}" \ + go list -deps -f '{{with .Module}}{{.Dir}}{{"\t"}}{{.Path}}{{"\t"}}{{.Version}}{{end}}' .) \ + >>"${WORK}/modules.raw" + + (cd "${REPO_ROOT}" && GOOS="${goos}" GOARCH="${goarch}" \ + "${GO_LICENSES}" report . --template "${template}") \ + >>"${WORK}/licenses.raw" 2>>"${WORK}/go-licenses.log" + done + + # Drop stdlib, which has no module and so yields a blank line. + grep -v '^$' "${WORK}/modules.raw" | sort -u >"${WORK}/modules.all.tsv" + grep -v '^$' "${WORK}/licenses.raw" | sort -u >"${WORK}/licenses.tsv" + + # The provider's own module has to stay in the attribution table -- its LICENSE + # is one of the files go-licenses reports -- but it is not a bundled component. + grep -v -F " ${main_module} " "${WORK}/modules.all.tsv" >"${WORK}/modules.tsv" + + [[ -s "${WORK}/modules.tsv" ]] || fail "no dependency modules found; is the module cache populated?" + + # go-licenses reports a license file per package; attribute each one to the + # module that owns it by longest matching directory prefix. + awk -F'\t' -v OFS='\t' ' + NR == FNR { dir[FNR] = $1; mod[FNR] = $2; ver[FNR] = $3; n = FNR; next } + { + best = 0; bestlen = 0 + for (i = 1; i <= n; i++) { + l = length(dir[i]) + if (l > bestlen && substr($2, 1, l) == dir[i] && substr($2, l + 1, 1) == "/") { + best = i; bestlen = l + } + } + if (best == 0) { + print "error: cannot attribute license file to a module: " $2 > "/dev/stderr" + bad = 1 + next + } + print mod[best], ver[best], substr($2, bestlen + 2), $1 + } + END { if (bad) exit 1 } + ' "${WORK}/modules.all.tsv" "${WORK}/licenses.tsv" \ + | awk -F'\t' -v main="${main_module}" '$1 != main' \ + | sort -u >"${WORK}/attributed.tsv" +} + +# Rewrites attributed.tsv in place, applying dev/licenses/overrides.tsv. +apply_overrides() { Review Comment: If I'm reading this right, if an override isn't found in the original file, it's ignored? Ideally, we'd error out. It'll help us find typos easier. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
