open-code-review/scripts/verify-license.sh
chethanuk 1ae808e100
fix(scripts): stop license checks failing on valid headers (#971)
`echo "$header" | grep -q ...` races. grep -q exits on the first match, so
echo can die of SIGPIPE (141); `set -o pipefail` makes that the pipeline's
status, and verify-license.sh reports a header that is present as missing.
Measured on a 410-byte header under CPU load: 4 spurious failures in 3000
iterations, naming a different file each time.

has_header() in add-license.sh has the same race, and there a false negative
makes add_header() prepend a second copyright block to a file that already
has one.

Feed the header through a here-string instead, and read the year with bash's
regex match rather than a grep | grep | head chain that can take SIGPIPE the
same way.
2026-08-17 17:25:35 +08:00

82 lines
1.9 KiB
Bash
Executable file

#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
# Copyright 2026 alibaba/open-code-review Contributors
set -euo pipefail
REPO_ROOT="$(git rev-parse --show-toplevel)"
cd "$REPO_ROOT"
CURRENT_YEAR=$(date +%Y)
MIN_YEAR=2026
SPDX_REGEX="SPDX-License-Identifier: Apache-2.0"
COPYRIGHT_REGEX="Copyright [0-9]{4} alibaba/open-code-review Contributors"
YEAR_REGEX="Copyright ([0-9]{4})"
LICENSE_EXTS=(go sh js mjs ts tsx)
IGNORED_PATHS=(
"vendor/"
"dist/"
"node_modules/"
"testdata/"
)
is_ignored() {
local file="$1"
for ignore in "${IGNORED_PATHS[@]}"; do
if [[ "$file" == */"$ignore"* ]] || [[ "$file" == "$ignore"* ]]; then
return 0
fi
done
return 1
}
FAILED=()
while IFS= read -r file; do
[ -z "$file" ] && continue
is_ignored "$file" && continue
ext="${file##*.}"
match=false
for e in "${LICENSE_EXTS[@]}"; do
if [[ "$ext" == "$e" ]]; then
match=true
break
fi
done
$match || continue
header="$(head -20 "$file")"
# Feed $header via here-string, not `echo |`: grep -q exits on the first match,
# so echo can die of SIGPIPE (141) and pipefail then reports a valid header as missing.
if ! grep -qF "$SPDX_REGEX" <<<"$header"; then
FAILED+=("$file (missing SPDX identifier)")
continue
fi
if ! grep -qE "$COPYRIGHT_REGEX" <<<"$header"; then
FAILED+=("$file (missing copyright notice)")
continue
fi
year=""
[[ "$header" =~ $YEAR_REGEX ]] && year="${BASH_REMATCH[1]}"
if [ -z "$year" ] || [ "$year" -lt "$MIN_YEAR" ] || [ "$year" -gt "$CURRENT_YEAR" ]; then
FAILED+=("$file (invalid year: ${year:-none})")
continue
fi
done < <(git ls-files)
if [ "${#FAILED[@]}" -gt 0 ]; then
echo "ERROR: The following files are missing or have invalid license headers:"
printf ' %s\n' "${FAILED[@]}"
echo ""
echo "Run 'make license-add' to fix."
exit 1
fi
echo "All source files have valid license headers."