Files
pmaports-rtwo/.githooks/pre-commit
T
Caleb Connolly 1c3296a63a githooks: ignore unstaged hunks of APKBUILD (MR 5807)
It's possible that additional sources have been made to an APKBUILD
which are unstaged, but if the hunks adding those sources haven't been
staged either then it doesn't make sense to fail on this.

Use git show to get only the staged hunks for the APKBUILD.

Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
2024-12-04 16:17:36 +01:00

130 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
#
# This hook checks that all local sources specified in the staged APKBUILDs
# are staged too or already committed and that checksums are correct.
#
set -eu
# Maximal allowed size (in bytes) of a file.
FILE_SIZE_LIMIT=262144 # 256 kiB
if ! command -v sha512sum >/dev/null; then
# macOS / BSDs (?) don't have sha512sum, but shasum.
alias sha512sum='shasum -a 512'
fi
error() {
printf '\033[0;31mpre-commit:\033[0m %s\n' "$1" >&2 # red
}
# Prints paths of created or modified files being committed.
changed_files() {
git diff-index \
--name-only \
--cached \
--diff-filter=ACMR HEAD \
-- "$@"
}
# Prints file names and checksums (in format <SHA-512>:<filename>) of local
# sources specified in the APKBUILD ($1).
apkbuild_local_sources() {
apkbuild="$1"
set +eu
. "$apkbuild" || {
error "$apkbuild is invalid"
return 1
}
set -eu
status=0
: ${source:=""}
for src in $source; do
# Skip remote sources.
case "$src" in */*) continue;; esac
echo "$sha512sums" | awk -v src="$src" '
{ if ($2 == src) { ok=1; print($2 ":" $1) } }
END { if (ok != 1) exit 1 }' || {
status=1
error "${apkbuild%/*}: file \"$src\" is missing in \$sha512sums (hint: run pmbootstrap checksum)"
}
done
return $status
}
# check if given object is a symlink
is_symlink() {
test "$(git ls-files --stage "$1" | awk '{print $1}')" = "120000"
}
# Checks that all local sources specified in the APKBUILD file ($1) are
# available in git tree and checksums are correct.
check_local_sources() {
local apkbuild="$1"
local startdir="$2"
local status=0
local checksum_act checksum_exp content filename line sources
sources=$(apkbuild_local_sources "$apkbuild")
for line in $sources; do
filename=${line%%:*}
checksum_exp=${line#*:}
if ! git cat-file -e ":$startdir/$filename" 2>/dev/null; then
error "$startdir: missing file \"$filename\""
status=1
continue
fi
if is_symlink ":$startdir/$filename"; then
continue
fi
checksum_act=$(git show ":$startdir/$filename" | sha512sum)
if [ "$checksum_act" != "$checksum_exp -" ]; then
local cmd="pmbootstrap checksum $(basename "$startdir")"
error "$startdir: bad checksum for file \"$filename\" (hint: run $cmd)"
status=1
fi
done
return $status
}
# Checks if the file ($1) being committed is not bigger than FILE_SIZE_LIMIT.
check_file_size() {
local path="$1"
local size
size=$(git cat-file -s ":$path")
if [ $size -gt $FILE_SIZE_LIMIT ]; then
local size_kb=$(( size / 1024 ))
error "file \"$path\" is quite big ($(( size / 1024 )) kiB), better put a remote url in source="
return 1
fi
}
cleanup() {
[ -f "$_staged" ] && rm "$_staged"
}
trap cleanup EXIT
for apkbuild in $(changed_files '**/APKBUILD'); do
_staged="$(mktemp)"
git show ":$apkbuild" >"$_staged"
check_local_sources "$_staged" "${apkbuild%/*}"
cleanup
done
for path in $(changed_files); do
check_file_size "$path"
done
trap - EXIT