78d549194c
tar 기반 rsync 대체 스크립트가 rsync 의 'node_modules/' 문법을 매칭하지 못해 node_modules 를 통째로 전송하다 메모리 부족으로 죽었다. 반대로 슬래시만 떼면 'build' 가 자바 패키지 kakao.response.build 까지 제외해 kakaoChatbotSkill 컴파일이 깨졌다. 선행 슬래시를 전송 루트 기준 고정으로 해석하도록 구분해 둘 다 해결한다. 배포 중 자동 커밋에 딸려 들어갔던 일회용 진단 스크립트도 함께 제거한다.
133 lines
3.8 KiB
Bash
Executable File
133 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Minimal rsync stand-in for Windows Git Bash (tar-over-ssh).
|
|
# Supports the flags used by server-dev/sync-submodules-rsync.sh:
|
|
# rsync -az [--delete] [--exclude PATTERN ...] SRC/ HOST:DEST/
|
|
set -euo pipefail
|
|
|
|
DELETE=false
|
|
EXCLUDES=()
|
|
ARGS=()
|
|
|
|
while (($#)); do
|
|
case "$1" in
|
|
-az|-a|-z|-v|-q|-P|--progress) shift ;;
|
|
--delete) DELETE=true; shift ;;
|
|
--exclude)
|
|
EXCLUDES+=("$2"); shift 2 ;;
|
|
--exclude=*)
|
|
EXCLUDES+=("${1#--exclude=}"); shift ;;
|
|
-*)
|
|
# ignore unknown short/long flags used by callers
|
|
shift ;;
|
|
*)
|
|
ARGS+=("$1"); shift ;;
|
|
esac
|
|
done
|
|
|
|
if ((${#ARGS[@]} < 2)); then
|
|
echo "rsync-shim: need SRC and DEST" >&2
|
|
exit 1
|
|
fi
|
|
|
|
SRC="${ARGS[0]}"
|
|
DEST="${ARGS[1]}"
|
|
|
|
# Git Bash /d/foo → Windows D:/foo (OpenSSH scp 용)
|
|
to_win_path() {
|
|
local p="$1"
|
|
if [[ "${p}" =~ ^/([a-zA-Z])/(.*)$ ]]; then
|
|
local drive rest
|
|
drive="$(echo "${BASH_REMATCH[1]}" | tr 'a-z' 'A-Z')"
|
|
rest="${BASH_REMATCH[2]}"
|
|
echo "${drive}:/${rest}"
|
|
else
|
|
echo "${p}"
|
|
fi
|
|
}
|
|
|
|
copy_file_remote() {
|
|
local src_file="$1"
|
|
local dest="$2"
|
|
local win_src
|
|
win_src="$(to_win_path "${src_file}")"
|
|
if [[ -f "${win_src}" || -f "${src_file}" ]]; then
|
|
local local_src="${src_file}"
|
|
[[ -f "${win_src}" ]] && local_src="${win_src}"
|
|
scp -o BatchMode=yes -q "${local_src}" "${dest}" && return 0
|
|
fi
|
|
# fallback: tar stream single file
|
|
local base dir
|
|
base="$(basename "${src_file}")"
|
|
dir="$(cd "$(dirname "${src_file}")" && pwd)"
|
|
local host="${dest%%:*}"
|
|
local remote="${dest#*:}"
|
|
local remote_dir remote_base
|
|
if [[ "${remote}" == */ ]]; then
|
|
remote_dir="${remote%/}"
|
|
remote_base="${base}"
|
|
else
|
|
remote_dir="$(dirname "${remote}")"
|
|
remote_base="$(basename "${remote}")"
|
|
fi
|
|
ssh -o BatchMode=yes "${host}" "mkdir -p '${remote_dir}'"
|
|
tar -C "${dir}" -cf - "${base}" \
|
|
| ssh -o BatchMode=yes "${host}" "tar -C '${remote_dir}' -xf - && if [[ '${remote_base}' != '${base}' ]]; then mv '${remote_dir}/${base}' '${remote_dir}/${remote_base}'; fi"
|
|
}
|
|
|
|
# file → file copy (overlay yml etc.)
|
|
if [[ -f "${SRC}" && "${DEST}" == *:* ]]; then
|
|
copy_file_remote "${SRC}" "${DEST}"
|
|
exit 0
|
|
fi
|
|
|
|
# normalize trailing slash semantics like rsync SRC/
|
|
SRC_DIR="${SRC%/}"
|
|
if [[ ! -d "${SRC_DIR}" ]]; then
|
|
# allow copying a single file into a remote dir
|
|
if [[ -f "${SRC_DIR}" ]]; then
|
|
copy_file_remote "${SRC_DIR}" "${DEST}"
|
|
exit 0
|
|
fi
|
|
echo "rsync-shim: source not found: ${SRC}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "${DEST}" != *:* ]]; then
|
|
echo "rsync-shim: only remote DEST (host:path) supported" >&2
|
|
exit 1
|
|
fi
|
|
|
|
HOST="${DEST%%:*}"
|
|
REMOTE_PATH="${DEST#*:}"
|
|
REMOTE_PATH="${REMOTE_PATH%/}"
|
|
|
|
TAR_EXCLUDES=()
|
|
for pat in "${EXCLUDES[@]}"; do
|
|
# tar 의 --exclude 는 'node_modules/' 처럼 슬래시로 끝나면 디렉터리에 매칭되지 않는다.
|
|
# (rsync 문법 그대로 넘기면 node_modules 가 통째로 전송돼 메모리 부족으로 죽는다)
|
|
pat="${pat%/}"
|
|
if [[ "${pat}" == /* ]]; then
|
|
# rsync 의 선행 슬래시 = 전송 루트 기준 고정. tar 멤버명은 './' 로 시작한다.
|
|
TAR_EXCLUDES+=(--anchored --exclude ".${pat}")
|
|
else
|
|
TAR_EXCLUDES+=(--no-anchored --exclude "${pat}")
|
|
fi
|
|
done
|
|
|
|
ssh -o BatchMode=yes "${HOST}" "mkdir -p '${REMOTE_PATH}'"
|
|
|
|
if $DELETE; then
|
|
# wipe remote dir contents then unpack (approx --delete)
|
|
# 서버 public-* 등이 root/docker 소유일 수 있어 실패해도 이어서 덮어쓴다
|
|
ssh -o BatchMode=yes "${HOST}" \
|
|
"chmod -R u+w '${REMOTE_PATH}' 2>/dev/null || true; \
|
|
find '${REMOTE_PATH}' -mindepth 1 -maxdepth 1 -exec rm -rf {} + 2>/dev/null || true" \
|
|
|| true
|
|
fi
|
|
|
|
# shellcheck disable=SC2086
|
|
tar -C "${SRC_DIR}" "${TAR_EXCLUDES[@]}" -cf - . \
|
|
| ssh -o BatchMode=yes "${HOST}" "tar -C '${REMOTE_PATH}' -xf -"
|
|
|
|
echo "rsync-shim: synced ${SRC_DIR}/ -> ${HOST}:${REMOTE_PATH}/"
|