-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdevsync.sh
More file actions
99 lines (88 loc) · 3.6 KB
/
devsync.sh
File metadata and controls
99 lines (88 loc) · 3.6 KB
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
#!/usr/bin/env bash
# devsync.sh — rsync local sources to the dev server, then run Python remotely.
#
# Usage:
# ./devsync.sh # runs: python -m chatdku.core.agent
# ./devsync.sh path/to/file.py # runs: python path/to/file.py
# ./devsync.sh chatdku.core.agent # runs: python -m chatdku.core.agent
# Arguments with `/` or a `.py` suffix are treated as file paths; everything
# else is treated as a module name and run with `python -m`.
set -euo pipefail
BOLD="\033[1m"
DIM="\033[2m"
CYAN="\033[36m"
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
RESET="\033[0m"
info() { echo -e "${CYAN}${BOLD}→${RESET} $*"; }
success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
step() { echo -e "${YELLOW}${BOLD}»${RESET} ${DIM}$*${RESET}"; }
warn() { echo -e "${RED}${BOLD}!${RESET} $*"; }
_GH_USER="$(gh api user -q .login 2>/dev/null || true)"
_SSH_USER="${_GH_USER:-$(whoami)}"
SERVER="${CHATDKU_SERVER:-${_SSH_USER}@10.200.14.82}"
REMOTE_DIR="${CHATDKU_REMOTE_DIR:-~/ChatDKU-DevSync}"
LOCAL_DIR="$(git rev-parse --show-toplevel)"
# Accept a leading `-m` / `--module` flag for familiarity; we always decide
# file-vs-module from the argument shape below.
if [[ "${1:-}" == "-m" || "${1:-}" == "--module" ]]; then
shift
fi
TARGET="${1:-}"
if [[ -n "$TARGET" ]]; then
if [[ "$TARGET" == *.py || "$TARGET" == */* ]]; then
: # file path — handled below
elif [[ "$TARGET" =~ ^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$ ]]; then
# Valid Python module name (e.g. chatdku.core.agent) — run with -m
REMOTE_RUN_CMD="uv run python -m $(printf %q "$TARGET")"
RUN_DESC="python -m $TARGET"
TARGET="" # signal: already handled
else
# Anything else — treat as a natural-language query for the agent.
REMOTE_RUN_CMD="uv run python -m chatdku.core.agent $(printf %q "$TARGET")"
RUN_DESC="agent query: $TARGET"
TARGET=""
fi
if [[ -n "$TARGET" ]]; then
# Treat as a file path
if [[ "$TARGET" = /* ]]; then
TARGET="${TARGET#"$LOCAL_DIR"/}"
fi
if [[ ! -f "$LOCAL_DIR/$TARGET" ]]; then
warn "target '$TARGET' not found under $LOCAL_DIR — syncing anyway"
fi
REMOTE_RUN_CMD="uv run python $(printf %q "$TARGET")"
RUN_DESC="python $TARGET"
fi
else
REMOTE_RUN_CMD="uv run python -m chatdku.core.agent"
RUN_DESC="agent"
fi
step "preparing remote directory $REMOTE_DIR on $SERVER"
ssh "${SERVER}" "mkdir -p ${REMOTE_DIR}"
# Secrets are loaded automatically from /datapool/secrets/chatdku_env.sh via
# /etc/profile.d/chatdku.sh for all chatdku_devs group members.
# No ~/.env file is needed or expected — see Documentations/Shared-Secrets.md.
step "verifying shared secrets are loaded on $SERVER"
if ! ssh "${SERVER}" 'bash -l -c "[ -n \"\${REDIS_HOST:-}\" ]"' 2>/dev/null; then
warn "shared secrets not loaded on $SERVER — are you in the chatdku_devs group?"
warn "Run: groups | grep chatdku_devs (if missing, ask an admin to run add_user.sh)"
fi
info "syncing ${BOLD}$LOCAL_DIR${RESET}${CYAN} → ${BOLD}$SERVER:$REMOTE_DIR"
rsync -avz --delete \
--exclude='.git/' \
--exclude='.venv/' \
--exclude='venv/' \
--exclude='__pycache__/' \
--exclude='*.pyc' \
--exclude='*.egg-info/' \
--exclude='.env' \
--exclude='node_modules/' \
--exclude='frontend/build/' \
--filter=':- .gitignore' \
"$LOCAL_DIR/" \
"$SERVER:$REMOTE_DIR/"
success "synced"
info "connecting to ${BOLD}$SERVER${RESET}${CYAN} — running ${BOLD}${RUN_DESC}${RESET}"
ssh -t "${SERVER}" "bash -l -c 'cd ${REMOTE_DIR} && uv sync && ${REMOTE_RUN_CMD}'"