#!/bin/sh
# Sync a local project directory to this user's scratch space on Aspire.
#
#   ./bin/aspire-ship <local-dir> [remote-name]
#
# remote-name defaults to the local directory's basename and lands at
# /scratch/users/nus/<remote-user>/<remote-name>/. The remote username is
# asked of the cluster rather than assumed, since home and scratch mirror
# each other per-user (see CLUSTER.md).
#
# Excludes the usual local-only junk so a re-ship after a training run
# doesn't drag results/checkpoints back onto the cluster. Edit EXCLUDES below
# if a project needs different ones.

set -eu

HOST="${ASPIRE_HOST:-aspire}"
BIN=$(cd -P "$(dirname "$0")" && pwd)

LOCAL_DIR="${1:?usage: aspire-ship <local-dir> [remote-name]}"
if [ ! -d "$LOCAL_DIR" ]; then
    echo "aspire-ship: no such directory: $LOCAL_DIR" >&2
    exit 1
fi
LOCAL_DIR=$(cd -P "$LOCAL_DIR" && pwd)
REMOTE_NAME="${2:-$(basename "$LOCAL_DIR")}"

"$BIN/aspire-connect"

REMOTE_USER=$(ssh -o BatchMode=yes "$HOST" whoami)
REMOTE_ROOT="/scratch/users/nus/$REMOTE_USER/$REMOTE_NAME"

ssh -o BatchMode=yes "$HOST" mkdir -p "$REMOTE_ROOT"

echo "aspire-ship: $LOCAL_DIR -> $HOST:$REMOTE_ROOT/" >&2

# No -z: a .sif is already squashfs-compressed, and compressing source before
# transfer over an already-fast link mostly just burns local CPU.
rsync -e "ssh -o BatchMode=yes" -avP \
    --exclude='.git' \
    --exclude='__pycache__' \
    --exclude='*.pyc' \
    --exclude='.venv' \
    --exclude='venv' \
    --exclude='logs' \
    --exclude='results' \
    --exclude='wandb' \
    --exclude='.apptainer-cache' \
    "$LOCAL_DIR"/ "$HOST:$REMOTE_ROOT"/

echo "aspire-ship: done -> $REMOTE_ROOT" >&2
