mirror of
https://github.com/alibaba/open-code-review.git
synced 2026-08-21 06:34:29 +00:00
`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.
82 lines
1.9 KiB
Bash
Executable file
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."
|