File size: 4,531 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<#
.SYNOPSIS
    Upload the FormScout source tree to both the model repo and the Space (Windows).

.DESCRIPTION
    PowerShell port of scripts/hf_upload.sh.

    `hf upload` does NOT read .hfignore — it only honors .gitignore at commit
    time. So we parse .hfignore ourselves into --exclude globs and pass them
    explicitly.

    If the filtered file count exceeds LargeThreshold, we fall back to
    `hf upload-large-folder` (resumable, multi-threaded). That mode commits
    directly to main in multiple commits — no --create-pr, no custom message.

.PARAMETER Message
    Commit message. Defaults to the last git commit subject.

.PARAMETER DryRun
    Print what would be uploaded (file count, mode, excludes) without uploading.

.EXAMPLE
    .\scripts\hf_upload.ps1
    .\scripts\hf_upload.ps1 "feat: my change"
    .\scripts\hf_upload.ps1 -DryRun
#>
param(
    [string]$Message,
    [switch]$DryRun
)

$ErrorActionPreference = "Stop"

# cd to repo root (parent of this script's directory)
$RepoRoot = Split-Path -Parent $PSScriptRoot
Set-Location $RepoRoot

$ModelRepo = "silas-therapy/small-functional-movement-screening"
$SpaceRepo = "spaces/silas-therapy/small-functional-movement-screening"

if (-not $Message) {
    $Message = (git log -1 --pretty=%s).Trim()
}

$LargeThreshold = if ($env:FORMSCOUT_HF_LARGE_THRESHOLD) {
    [int]$env:FORMSCOUT_HF_LARGE_THRESHOLD
} else {
    500
}

# Belt-and-suspenders extras on top of .hfignore.
$Patterns = [System.Collections.Generic.List[string]]::new()
$Patterns.Add("*.pdf")
$Patterns.Add("**/node_modules/**")
$Patterns.Add(".cache/**")

# Parse .hfignore into fnmatch-style globs. A bare name like `.DS_Store` or
# `dir/` only matches at the root, so emit both the rooted and `**/`-prefixed
# forms.
if (Test-Path ".hfignore") {
    foreach ($raw in Get-Content ".hfignore") {
        $line = $raw -replace '#.*$', ''
        $line = $line.Trim()
        if ([string]::IsNullOrEmpty($line)) { continue }
        if ($line.EndsWith("/")) {
            $Patterns.Add("${line}**")
            $Patterns.Add("**/${line}**")
        } else {
            $Patterns.Add($line)
            $Patterns.Add("**/$line")
        }
    }
}

# Build --exclude args
$Excludes = [System.Collections.Generic.List[string]]::new()
foreach ($p in $Patterns) {
    $Excludes.Add("--exclude=$p")
}

# Count what would actually be uploaded, using the same filter the hub client
# applies, so the mode decision matches reality.
$PatternArgs = $Patterns -join "`n"
$NFiles = $PatternArgs | python -c @"
import sys
from pathlib import Path
from huggingface_hub.utils import filter_repo_objects

patterns = sys.stdin.read().splitlines()
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))))
"@
$NFiles = [int]($NFiles.Trim())
Write-Host "-- $NFiles files to upload after .hfignore filtering"

if ($NFiles -eq 0) {
    Write-Error "nothing to upload -- check .hfignore"
    exit 1
}

function Upload-Repo {
    param([string]$Repo)

    if ($NFiles -gt $LargeThreshold) {
        Write-Host "-- ${Repo}: $NFiles files > $LargeThreshold, using upload-large-folder"
        Write-Host "   (resumable; commits directly to main -- no PR, no custom message)"
        if ($DryRun) {
            Write-Host "   [dry-run] hf upload-large-folder $Repo . <$($Excludes.Count) excludes>"
            return
        }
        hf upload-large-folder $Repo . @Excludes
    } else {
        Write-Host "-- uploading to: $Repo"
        if ($DryRun) {
            Write-Host "   [dry-run] hf upload $Repo . . <$($Excludes.Count) excludes> --create-pr --commit-message=`"$Message`""
            return
        }
        hf upload $Repo . . @Excludes --create-pr --commit-message="$Message"
    }
    if ($LASTEXITCODE -ne 0) {
        Write-Error "upload to $Repo failed (exit $LASTEXITCODE)"
        exit $LASTEXITCODE
    }
}

if ($DryRun) {
    Write-Host ""
    Write-Host "=== DRY RUN ==="
    Write-Host "Commit message : $Message"
    Write-Host "Large threshold: $LargeThreshold"
    Write-Host "Mode           : $(if ($NFiles -gt $LargeThreshold) { 'upload-large-folder' } else { 'upload + create-pr' })"
    Write-Host "Exclude globs  : $($Excludes.Count)"
    foreach ($e in $Excludes) { Write-Host "    $e" }
    Write-Host ""
}

Upload-Repo $ModelRepo
Upload-Repo $SpaceRepo

if ($DryRun) {
    Write-Host "OK -- dry run complete (nothing uploaded)"
} else {
    Write-Host "OK -- done"
}