| | #!/usr/bin/env 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.' |
| |
|