File size: 3,266 Bytes
40e8702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env bash
# Upload the FormScout source tree to both the model repo and the Space.
#
# Usage:
#   ./scripts/hf_upload.sh                     # message from last git commit
#   ./scripts/hf_upload.sh "feat: my change"   # custom message
#
# Pushes to:
#   silas-therapy/small-functional-movement-screening          (model repo)
#   spaces/silas-therapy/small-functional-movement-screening   (Gradio Space)
#
# `hf upload` does NOT read .hfignore β€” it only honors .gitignore, and only at
# commit time (after hashing and pre-uploading everything). So we parse
# .hfignore ourselves into --exclude globs and pass them explicitly.
#
# If the filtered file count still exceeds LARGE_THRESHOLD, we fall back to
# `hf upload-large-folder` (resumable, multi-threaded). Caveats of that mode:
# no --create-pr and no custom commit message β€” it commits directly to main
# in multiple commits.
set -euo pipefail

cd "$(dirname "$0")/.."

MODEL_REPO="silas-therapy/small-functional-movement-screening"
SPACE_REPO="spaces/silas-therapy/small-functional-movement-screening"
MSG="${1:-$(git log -1 --pretty=%s)}"
LARGE_THRESHOLD="${FORMSCOUT_HF_LARGE_THRESHOLD:-500}"

# Belt-and-suspenders extras on top of .hfignore. `.cache/` is the resume
# state upload-large-folder writes into the folder being uploaded.
PATTERNS=(
    "*.pdf"
    "**/node_modules/**"
    ".cache/**"
)

# Parse .hfignore into fnmatch-style globs. fnmatch's `*` crosses `/`, but a
# bare name like `.DS_Store` or `dir/` only matches at the root, so emit both
# the rooted and `**/`-prefixed forms.
while IFS= read -r line; do
    line="${line%%#*}"
    line="${line#"${line%%[![:space:]]*}"}"
    line="${line%"${line##*[![:space:]]}"}"
    [[ -z "$line" ]] && continue
    if [[ "$line" == */ ]]; then
        PATTERNS+=("${line}**" "**/${line}**")
    else
        PATTERNS+=("$line" "**/$line")
    fi
done < .hfignore

EXCLUDES=()
for p in "${PATTERNS[@]}"; do
    EXCLUDES+=(--exclude="$p")
done

# Count what would actually be uploaded, using the same filter the hub client
# applies, so the mode decision matches reality.
N_FILES=$(python3 - "${PATTERNS[@]}" <<'EOF'
import sys
from pathlib import Path
from huggingface_hub.utils import filter_repo_objects

patterns = sys.argv[1:]
files = (
    str(p) for p in Path(".").rglob("*")
    if p.is_file() and p.parts[0] != ".git"
)
print(len(list(filter_repo_objects(files, ignore_patterns=patterns))))
EOF
)
echo "── $N_FILES files to upload after .hfignore filtering"

if (( N_FILES == 0 )); then
    echo "βœ— nothing to upload β€” check .hfignore" >&2
    exit 1
fi

upload_repo() {
    local repo="$1"
    if (( N_FILES > LARGE_THRESHOLD )); then
        echo "── $repo: $N_FILES files > $LARGE_THRESHOLD, using upload-large-folder"
        echo "   (resumable; commits directly to main β€” no PR, no custom message)"
        hf upload-large-folder "$repo" . "${EXCLUDES[@]}"
    else
        echo "── uploading to: $repo"
        hf upload "$repo" . . \
            "${EXCLUDES[@]}" \
            --create-pr \
            --commit-message="$MSG"
    fi
}

upload_repo "$MODEL_REPO"
upload_repo "$SPACE_REPO"

echo "βœ“ done"