sync-to-windows.sh pushes sources out; there was no inverse, so every build
had to be retrieved by hand. This pulls back only GENERATED artefacts:
the linked output dirs (rel/dbg/pro/arm/ice.bin), the per-project VC6
intermediates, packed Resource/*.mw4 + *.dep, the MW4/ deploy, the binaries
deployed into Gameleap/mw4, and the build logs. Source, content and assets
are never pulled, so a stale copy on the build machine cannot clobber local
edits made since the last push.
Two things it has to get right, both found by running it:
It does not use rsync -a. The CIFS mount reports every file as 755 while git
tracks these as 100644, so preserving permissions would flip the exec bit on
every file pulled -- a spurious mode change on ~2000 paths. It uses
-rlt --chmod=F664,D775 instead. Verified: 1994 files pulled, 0 mode changes.
It excludes dgVoodoo2 from the MW4/ deploy (DDraw/D3D8/D3D9/D3DImm.dll,
dgVoodoo.conf, dgVoodooCpl.exe). That is a Win10/11-only prerequisite which
must never enter the repo because it breaks the XP pods; it was removed
deliberately in 0ceba9c7. A naive pull dragged all six straight back in.
This was being stripped by hand before every push back.
--delete is opt-in rather than default: a pull with --delete can destroy
mirrored history if the build machine is missing something. Excluded files
are protected from deletion, so Resource/*.tga and *.nfo cannot be removed
by it. There is also a --dry-run, and a warning if the pull targets already
hold uncommitted work.
Co-authored-by: Claude Opus 5 (Anthropic) <noreply@anthropic.com>
Co-authored-by: GitHub Copilot <copilot@github.com>
172 lines
6.8 KiB
Bash
Executable File
172 lines
6.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# sync-from-windows.sh
|
|
# Pulls build and deploy OUTPUTS back from the Windows build/test machine
|
|
# mounted at /vwe/firestorm. This is the inverse of sync-to-windows.sh, which
|
|
# pushes sources out.
|
|
#
|
|
# Only GENERATED artefacts come back. Source, content and assets are never
|
|
# pulled, so local edits made since the last push cannot be clobbered by a
|
|
# stale copy sitting on the build machine.
|
|
#
|
|
# Usage:
|
|
# ./sync-from-windows.sh # pull everything generated
|
|
# ./sync-from-windows.sh --dry-run # preview only, no files written
|
|
# ./sync-from-windows.sh --delete # also delete local files that are gone
|
|
# # on Windows (off by default: a pull with
|
|
# # --delete can destroy mirrored history)
|
|
#
|
|
# This repo is a full disaster-recovery mirror -- build outputs are tracked on
|
|
# purpose (.gitignore is deliberately almost empty), so pulling them back and
|
|
# committing them is the intended workflow, not noise.
|
|
|
|
SRC=/vwe/firestorm
|
|
DST=~/Repositories/firestorm
|
|
|
|
# Deliberately NOT -a: the CIFS mount reports every file as 755 while git
|
|
# tracks these as 100644. Preserving permissions would flip the exec bit on
|
|
# every file pulled and show up as a mode change on thousands of paths.
|
|
# -rlt keeps recursion, symlinks and mtimes; --chmod forces sane local modes.
|
|
RSYNC_OPTS="-rltv --chmod=F664,D775 --modify-window=2"
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--dry-run) RSYNC_OPTS="$RSYNC_OPTS --dry-run"
|
|
echo "[DRY RUN] No files will be written." ;;
|
|
--delete) RSYNC_OPTS="$RSYNC_OPTS --delete"
|
|
echo "[DELETE] Local files absent on Windows will be removed." ;;
|
|
*) echo "Unknown option: $arg"; exit 2 ;;
|
|
esac
|
|
done
|
|
|
|
set -e
|
|
|
|
if [[ ! -d "$SRC" ]]; then
|
|
echo "ERROR: $SRC is not mounted. Mount the build machine first." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Warn before overwriting work that is not yet committed. Untracked files are
|
|
# ignored: they are new local work, not a modified copy of something the build
|
|
# machine is about to send back.
|
|
UNCOMMITTED=$(cd "$DST" && git status --porcelain -- \
|
|
Gameleap/code Gameleap/mw4/Resource MW4 build-env 2>/dev/null \
|
|
| grep -cv '^??' || true)
|
|
if [[ "$UNCOMMITTED" -gt 0 ]]; then
|
|
echo
|
|
echo "WARNING: $UNCOMMITTED uncommitted change(s) already exist in the pull targets."
|
|
echo " Pulling will overwrite them. Ctrl-C now if that is not what you want."
|
|
echo
|
|
fi
|
|
|
|
echo
|
|
echo "=== [1/6] Linked build output dirs (MW4.exe, MW4Ed2.exe, libs, dlls, pdbs) ==="
|
|
for d in rel.bin dbg.bin pro.bin arm.bin ice.bin; do
|
|
if [[ -d "$SRC/Gameleap/code/$d" ]]; then
|
|
echo "--- $d"
|
|
rsync $RSYNC_OPTS "$SRC/Gameleap/code/$d/" "$DST/Gameleap/code/$d/"
|
|
fi
|
|
done
|
|
|
|
echo
|
|
echo "=== [2/6] Per-project intermediates (obj, pch, idb, pdb, res) ==="
|
|
# VC6 writes these into a Release/Profile/Armor/Debug folder beside each .dsp.
|
|
# They are scattered across the tree, so the list is discovered rather than
|
|
# hardcoded. 2700+ .obj files are tracked here -- see the mirror note above.
|
|
INTERMEDIATES=$(cd "$SRC" && find Gameleap/code -type d \
|
|
\( -name Release -o -name Profile -o -name Armor -o -name Debug -o -name icecap \) \
|
|
-printf '%p/\n' 2>/dev/null | sort)
|
|
if [[ -n "$INTERMEDIATES" ]]; then
|
|
echo "$INTERMEDIATES" | rsync $RSYNC_OPTS --files-from=- "$SRC/" "$DST/"
|
|
echo "--- $(echo "$INTERMEDIATES" | wc -l) intermediate dirs"
|
|
else
|
|
echo "--- none found"
|
|
fi
|
|
|
|
echo
|
|
echo "=== [3/6] Packed resources (*.mw4 + *.dep) ==="
|
|
# .tga/.nfo/.txt in here are SOURCE and travel outbound only, so they are excluded.
|
|
rsync $RSYNC_OPTS \
|
|
--include='*/' \
|
|
--include='*.mw4' \
|
|
--include='*.dep' \
|
|
--exclude='*' \
|
|
--prune-empty-dirs \
|
|
"$SRC/Gameleap/mw4/Resource/" "$DST/Gameleap/mw4/Resource/"
|
|
|
|
echo
|
|
echo "=== [4/6] Deployed game (MW4/) - output of deploy-mw4.ps1 ==="
|
|
# Two classes of exclusion here:
|
|
# - per-machine and gitignored: player-made variants, and the GameOS run-time
|
|
# reports which are rewritten on every launch.
|
|
# - dgVoodoo2: an installed-per-machine, OS-dependent prerequisite for Win10/11
|
|
# pods. It must NEVER enter the repo -- shipping it would push a Win10-only
|
|
# dependency onto the XP pods and break them. Removed deliberately in
|
|
# 0ceba9c7; do not "fix" that by letting a pull put it back.
|
|
rsync $RSYNC_OPTS \
|
|
--exclude='Resource/Variants/' \
|
|
--exclude='gos-displays.txt' \
|
|
--exclude='gos-fps.txt' \
|
|
--exclude='[Dd][Gg][Vv]oodoo.conf' \
|
|
--exclude='[Dd][Gg][Vv]oodooCpl.exe' \
|
|
--exclude='[Dd][Dd]raw.dll' \
|
|
--exclude='[Dd]3[Dd]8.dll' \
|
|
--exclude='[Dd]3[Dd]9.dll' \
|
|
--exclude='[Dd]3[Dd][Ii]mm.dll' \
|
|
"$SRC/MW4/" "$DST/MW4/"
|
|
|
|
echo
|
|
echo "=== [5/6] Binaries deployed into the data tree (Gameleap/mw4 root) ==="
|
|
# deploy-editor.ps1 installs the editor here; the game binaries are mirrored
|
|
# alongside it. Only known build products are listed, so nothing else in this
|
|
# directory can be overwritten by a stale copy.
|
|
PRODUCTS="MW4.exe MW4pro.exe MW4Ed2.exe MW4Ed2.pdb Launcher.exe autoconfig.exe \
|
|
mw4print.exe MissionLang.dll ScriptStrings.dll ctcls.dll Language.dll"
|
|
PRESENT=""
|
|
for f in $PRODUCTS; do
|
|
[[ -f "$SRC/Gameleap/mw4/$f" ]] && PRESENT="$PRESENT$f"$'\n'
|
|
done
|
|
if [[ -n "$PRESENT" ]]; then
|
|
# --delete is meaningless for an explicit file list, so it is dropped here.
|
|
printf '%s' "$PRESENT" | rsync ${RSYNC_OPTS/--delete/} --files-from=- \
|
|
"$SRC/Gameleap/mw4/" "$DST/Gameleap/mw4/"
|
|
else
|
|
echo "--- no deployed binaries found"
|
|
fi
|
|
|
|
echo
|
|
echo "=== [6/6] Build logs (build-env/*.log, *.plg, *.map) ==="
|
|
rsync $RSYNC_OPTS \
|
|
--include='*.log' --include='*.plg' --include='*.map' \
|
|
--exclude='*/' --exclude='*' \
|
|
"$SRC/build-env/" "$DST/build-env/"
|
|
|
|
echo
|
|
echo "=== Pull complete ==="
|
|
echo "Pulled: Gameleap/code/{rel,dbg,pro,arm,ice}.bin/"
|
|
echo " Gameleap/code/**/{Release,Profile,Armor,Debug}/"
|
|
echo " Gameleap/mw4/Resource/*.mw4 *.dep"
|
|
echo " MW4/ (deployed game)"
|
|
echo " Gameleap/mw4/ deployed binaries"
|
|
echo " build-env/ build logs"
|
|
echo
|
|
echo "NOT pulled (source travels outbound only):"
|
|
echo " Gameleap/code source, Gameleap/mw4/Content, hsh, Assets, Stats"
|
|
echo " Resource/*.tga *.nfo *.txt, build-env scripts, BTFrstrm"
|
|
echo "NOT pulled (per-machine):"
|
|
echo " MW4/Resource/Variants/, MW4/gos-displays.txt, MW4/gos-fps.txt"
|
|
echo " MW4/ dgVoodoo2 (DDraw/D3D8/D3D9/D3DImm.dll, dgVoodoo.conf/Cpl.exe)"
|
|
echo " -- a Win10/11-only prerequisite that must never reach the XP pods"
|
|
|
|
echo
|
|
echo "=== Changed in the working tree ==="
|
|
cd "$DST"
|
|
CHANGED=$(git status --porcelain | wc -l)
|
|
if [[ "$CHANGED" -eq 0 ]]; then
|
|
echo " nothing changed - the repo already matched the build machine"
|
|
else
|
|
git status --short | head -40
|
|
[[ "$CHANGED" -gt 40 ]] && echo " ... and $((CHANGED - 40)) more"
|
|
echo
|
|
echo " $CHANGED path(s) changed. Review, then commit."
|
|
fi
|