TypePHP 编译器
https://swoole.com/aot/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
4.5 KiB
178 lines
4.5 KiB
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
readonly MIN_AGE_MINUTES=60
|
|
|
|
dry_run=false
|
|
tmp_root=/tmp
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: ./cleanup-typephp-tmp.sh [options]
|
|
|
|
Remove inactive TypePHP temporary files and directories from /tmp.
|
|
An entry is skipped when it or any of its descendants was modified or
|
|
metadata-changed during the last 60 minutes.
|
|
Recognized prefixes: typephp-, typephp_, utils_test_, and phpx-windows.
|
|
|
|
Options:
|
|
-n, --dry-run Show what would be removed without deleting anything
|
|
--tmp-dir DIR Use another temporary directory (primarily for testing)
|
|
-h, --help Show this help
|
|
EOF
|
|
}
|
|
|
|
while (($# > 0)); do
|
|
case "$1" in
|
|
-n | --dry-run)
|
|
dry_run=true
|
|
;;
|
|
--tmp-dir)
|
|
if (($# < 2)); then
|
|
echo "Error: --tmp-dir requires a directory." >&2
|
|
exit 2
|
|
fi
|
|
tmp_root=$2
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Error: unknown option: $1" >&2
|
|
usage >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [[ ! -d "$tmp_root" ]]; then
|
|
echo "Error: temporary directory does not exist: $tmp_root" >&2
|
|
exit 1
|
|
fi
|
|
|
|
tmp_root=$(realpath -e -- "$tmp_root")
|
|
if [[ -z "$tmp_root" || "$tmp_root" == / ]]; then
|
|
echo "Error: refusing to use an unsafe temporary directory." >&2
|
|
exit 1
|
|
fi
|
|
|
|
readonly tmp_root
|
|
readonly owner_uid=${SUDO_UID:-$(id -u)}
|
|
|
|
format_size() {
|
|
local kib=$1
|
|
awk -v kib="$kib" 'BEGIN {
|
|
if (kib >= 1048576) {
|
|
printf "%.2f GiB", kib / 1048576
|
|
} else if (kib >= 1024) {
|
|
printf "%.2f MiB", kib / 1024
|
|
} else {
|
|
printf "%d KiB", kib
|
|
}
|
|
}'
|
|
}
|
|
|
|
entry_size_kib() {
|
|
local output
|
|
output=$(du -sk -- "$1" 2>/dev/null) || {
|
|
printf '0'
|
|
return
|
|
}
|
|
printf '%s' "${output%%$'\t'*}"
|
|
}
|
|
|
|
has_recent_entry() {
|
|
local candidate=$1
|
|
local recent
|
|
|
|
# Check the complete tree. Looking only at the top-level directory mtime
|
|
# would miss writes to an existing file in a nested build directory.
|
|
if ! recent=$(find -P "$candidate" -xdev \
|
|
\( -mmin "-${MIN_AGE_MINUTES}" -o -cmin "-${MIN_AGE_MINUTES}" \) \
|
|
-printf '1' -quit 2>/dev/null); then
|
|
return 0
|
|
fi
|
|
|
|
[[ -n "$recent" ]]
|
|
}
|
|
|
|
matched_count=0
|
|
removed_count=0
|
|
skipped_recent_count=0
|
|
skipped_error_count=0
|
|
total_kib=0
|
|
|
|
while IFS= read -r -d '' candidate; do
|
|
((matched_count += 1))
|
|
|
|
# Keep the target constrained to one direct child of the selected root.
|
|
if [[ "$candidate" != "$tmp_root"/* || "${candidate%/*}" != "$tmp_root" ]]; then
|
|
echo "[skip unsafe] $candidate" >&2
|
|
((skipped_error_count += 1))
|
|
continue
|
|
fi
|
|
|
|
if has_recent_entry "$candidate"; then
|
|
echo "[skip recent] $candidate"
|
|
((skipped_recent_count += 1))
|
|
continue
|
|
fi
|
|
|
|
size_kib=$(entry_size_kib "$candidate")
|
|
size=$(format_size "$size_kib")
|
|
|
|
# The size scan can take noticeable time for a large build tree. Recheck
|
|
# freshness immediately before acting in case a compiler started using it.
|
|
if has_recent_entry "$candidate"; then
|
|
echo "[skip recent] $candidate"
|
|
((skipped_recent_count += 1))
|
|
continue
|
|
fi
|
|
|
|
if $dry_run; then
|
|
echo "[would remove] $size $candidate"
|
|
((removed_count += 1))
|
|
((total_kib += size_kib))
|
|
continue
|
|
fi
|
|
|
|
if [[ -d "$candidate" && ! -L "$candidate" ]]; then
|
|
if rm -rf --one-file-system -- "$candidate"; then
|
|
echo "[removed] $size $candidate"
|
|
((removed_count += 1))
|
|
((total_kib += size_kib))
|
|
else
|
|
echo "[skip error] failed to remove: $candidate" >&2
|
|
((skipped_error_count += 1))
|
|
fi
|
|
elif rm -f -- "$candidate"; then
|
|
echo "[removed] $size $candidate"
|
|
((removed_count += 1))
|
|
((total_kib += size_kib))
|
|
else
|
|
echo "[skip error] failed to remove: $candidate" >&2
|
|
((skipped_error_count += 1))
|
|
fi
|
|
done < <(
|
|
find -P "$tmp_root" -mindepth 1 -maxdepth 1 -uid "$owner_uid" \
|
|
\( -name 'typephp-*' -o -name 'typephp_*' \
|
|
-o -name 'utils_test_*' -o -name 'phpx-windows*' \) -print0
|
|
)
|
|
|
|
if $dry_run; then
|
|
action='would remove'
|
|
else
|
|
action='removed'
|
|
fi
|
|
|
|
printf 'Summary: matched %d, %s %d (%s), skipped recent %d, errors %d.\n' \
|
|
"$matched_count" "$action" "$removed_count" "$(format_size "$total_kib")" \
|
|
"$skipped_recent_count" "$skipped_error_count"
|
|
|
|
if ((skipped_error_count > 0)); then
|
|
exit 1
|
|
fi
|
|
|