|
#!/bin/bash |
|
set -euo pipefail |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
log() { |
|
local level=$1 msg=$2 |
|
printf >&2 '%s: %s\n' "$level" "$msg" |
|
} |
|
|
|
debug() { |
|
log DEBUG "$@" |
|
} |
|
|
|
info() { |
|
log INFO "$@" |
|
} |
|
|
|
fatal() { |
|
log FATAL "$@" |
|
exit 1 |
|
} |
|
|
|
cleanup() { |
|
if [[ -n ${workdir+x} && -d $workdir && -w $workdir ]]; then |
|
info "Removing $workdir" |
|
local count=0 |
|
rm -rfv -- "$workdir" | while read -r; do |
|
if (( count++ > 750 )); then |
|
printf . |
|
count=0 |
|
fi |
|
done |
|
printf '\n' |
|
info "Removed $workdir" |
|
fi |
|
} |
|
|
|
do_cleanup=1 |
|
if [[ ${1-} == nocleanup ]]; then |
|
do_cleanup=0; shift |
|
fi |
|
|
|
if (( do_cleanup )); then |
|
trap exit INT TERM |
|
trap cleanup EXIT |
|
fi |
|
|
|
this=$(realpath -- "$0"); readonly this |
|
cd "$(dirname "$this")/.." |
|
|
|
shellcheck "$this" |
|
|
|
readonly reqs_dir=requirements |
|
|
|
if [[ ${1+x} ]]; then |
|
tmp_dir=$(realpath -- "$1") |
|
if [[ ! ( -d $tmp_dir && -w $tmp_dir ) ]]; then |
|
fatal "$tmp_dir is not a writable directory" |
|
fi |
|
else |
|
tmp_dir=/tmp |
|
fi |
|
|
|
workdir=$(mktemp -d "$tmp_dir/check-requirements.XXXX"); readonly workdir |
|
info "Working directory: $workdir" |
|
|
|
check_requirements() { |
|
local reqs=$1 |
|
|
|
info "$reqs: beginning check" |
|
pip --disable-pip-version-check install -qr "$reqs" |
|
info "$reqs: OK" |
|
} |
|
|
|
check_convert_script() { |
|
local py=$1 |
|
local pyname=${py##*/} |
|
pyname=${pyname%.py} |
|
|
|
info "$py: beginning check" |
|
|
|
local reqs="$reqs_dir/requirements-$pyname.txt" |
|
if [[ ! -r $reqs ]]; then |
|
fatal "$py missing requirements. Expected: $reqs" |
|
fi |
|
|
|
|
|
if ! grep -qF "$reqs" requirements.txt; then |
|
fatal "$reqs needs to be added to requirements.txt" |
|
fi |
|
|
|
local venv="$workdir/$pyname-venv" |
|
python3 -m venv "$venv" |
|
|
|
( |
|
|
|
source "$venv/bin/activate" |
|
|
|
check_requirements "$reqs" |
|
|
|
python - "$py" "$pyname" <<'EOF' |
|
import sys |
|
from importlib.machinery import SourceFileLoader |
|
py, pyname = sys.argv[1:] |
|
SourceFileLoader(pyname, py).load_module() |
|
EOF |
|
) |
|
|
|
if (( do_cleanup )); then |
|
rm -rf -- "$venv" |
|
fi |
|
|
|
info "$py: imports OK" |
|
} |
|
|
|
readonly ignore_eq_eq='check_requirements: ignore "=="' |
|
|
|
for req in */**/requirements*.txt; do |
|
|
|
|
|
if grep -vF "$ignore_eq_eq" "$req" | grep -q '=='; then |
|
tab=$'\t' |
|
cat >&2 <<EOF |
|
FATAL: Avoid pinning exact package versions. Use '~=' instead. |
|
You can suppress this error by appending the following to the line: |
|
$tab# $ignore_eq_eq |
|
EOF |
|
exit 1 |
|
fi |
|
done |
|
|
|
all_venv="$workdir/all-venv" |
|
python3 -m venv "$all_venv" |
|
|
|
( |
|
|
|
source "$all_venv/bin/activate" |
|
check_requirements requirements.txt |
|
) |
|
|
|
if (( do_cleanup )); then |
|
rm -rf -- "$all_venv" |
|
fi |
|
|
|
check_convert_script examples/convert_legacy_llama.py |
|
for py in convert_*.py; do |
|
|
|
|
|
|
|
[[ $py == convert_hf_to_gguf_update.py ]] && continue |
|
|
|
check_convert_script "$py" |
|
done |
|
|
|
info 'Done! No issues found.' |
|
|