Something went wrong. Try again.
Backend environment for match hosting for lance.blue
Something went wrong. Try again.
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200#!/usr/bin/env bash# prune-data.sh deletes from the MegaMek tree at image build. Two ways that goes# wrong are invisible until a match runs, and both are what the guards exist for:## - a MegaMek bump renames what a prune line names, the glob matches nothing,# and the build quietly ships the bytes the line was written to remove# - a glob grows too broad and takes a file the game needs with it## So the test is not "does rm work". It is that both failures stop the build.set -uo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"TMP="$(mktemp -d)"trap 'rm -rf "$TMP"' EXIT
pass=0; fail=0check() { if "${@:2}"; then echo "ok $1"; pass=$((pass+1)); else echo "FAIL $1"; fail=$((fail+1)); fi; }
# A MegaMek tree carrying one file per path the script names, plus one file it# must not touch in each directory it prunes from.stage_tree() { # <dir> local mm="$1" rm -rf "$mm" mkdir -p "$mm/data/images/portraits/Male/MekWarrior" \ "$mm/data/images/portraits/Female/MekWarrior" \ "$mm/data/images/portraits/Male/Astech" \ "$mm/data/images/portraits/Female/Astech" \ "$mm/data/images/portraits/Black Widow Company" \ "$mm/data/images/hexes/Ahne" \ "$mm/data/images/hexes/largeTextures" \ "$mm/data/images/misc" \ "$mm/data/images/widgets/kiro" \ "$mm/data/boards/unofficial/UlyssesMaps/MegaMek Invitational Map Pack" \ "$mm/data/universe/planetary_systems" \ "$mm/lib" touch "$mm/data/images/portraits/default.gif" \ "$mm/data/images/portraits/Male/MekWarrior/MW_M_999.png" \ "$mm/data/images/portraits/Female/MekWarrior/MW_F_999.png" \ "$mm/data/images/portraits/Male/Astech/AST_M_1.png" \ "$mm/data/images/portraits/Female/Astech/AST_F_1.png" \ "$mm/data/images/portraits/Black Widow Company/Francine.jpg" \ "$mm/data/images/hexes/saxarba.tileset" \ "$mm/data/images/hexes/defaulthexset.txt" \ "$mm/data/images/hexes/largeTextures.tileset" \ "$mm/data/images/hexes/bw_atmospheric.tileset" \ "$mm/data/images/hexes/Ahne/hex.png" \ "$mm/data/images/hexes/largeTextures/hex.png" \ "$mm/data/images/misc/MekHQ.png" \ "$mm/data/images/misc/MekHQ Load_uhd.png" \ "$mm/data/images/misc/MHQcamo1.png" \ "$mm/data/images/misc/mml-background.png" \ "$mm/data/images/misc/mml-splash.jpg" \ "$mm/data/images/misc/mml_logo.jpg" \ "$mm/data/images/misc/megamek_splash_hd.png" \ "$mm/data/images/misc/camo_overlay0.png" \ "$mm/data/images/misc/camo_overlay5.png" \ "$mm/data/images/widgets/kiro/01.gif" \ "$mm/data/images/widgets/kiro/border.psd" \ "$mm/MegaMek.jar" \ "$mm/lib/MegaMek.jar" \ "$mm/lib/commons-io-2.21.0.jar" \ "$mm/data/universe/eras.xml" \ "$mm/data/universe/planetary_systems/canon_systems.zip" # Directories with spaces in them, which the .docx prune has to glob through. touch "$mm/data/boards/unofficial/UlyssesMaps/MegaMek Invitational Map Pack/MegaMek Invitational - Map Pack Rules.docx" \ "$mm/data/boards/unofficial/UlyssesMaps/MegaMek Invitational Map Pack/20x20 Marik Arena - Factory.board" # The portraits the shipped scenarios name, read out of the script rather # than repeated here: whether that list is the right one is settled against # the real tree at build time, by keep. What the fixture is for is that # everything else around them goes. local portrait for portrait in $(portraits_kept); do touch "$(portrait_path "$mm" "$portrait")" done}
portraits_kept() { grep -oE 'MekWarrior/MW_[MF]_[0-9]+\.png' "$ROOT/megamek/prune-data.sh" \ | sed 's#.*/##' | sort -u}
portrait_path() { # <dir> <file> case "$2" in MW_M_*) echo "$1/data/images/portraits/Male/MekWarrior/$2" ;; *) echo "$1/data/images/portraits/Female/MekWarrior/$2" ;; esac}
run_prune() { # <dir> MM_HOME="$1" bash "$ROOT/megamek/prune-data.sh" 2>&1}
# --- the happy path ---------------------------------------------------------MM="$TMP/mm"stage_tree "$MM"out="$(run_prune "$MM")"; status=$?
check "runs clean against a complete tree" test "$status" -eq 0[ "$status" -eq 0 ] || printf '%s\n' "$out" | sed 's/^/ /'
check "unreferenced portraits removed" \ test ! -e "$MM/data/images/portraits/Male/MekWarrior/MW_M_999.png" \ -a ! -e "$MM/data/images/portraits/Female/MekWarrior/MW_F_999.png"# A whole portrait category nothing names. The files go, and so does the# directory they leave behind - an empty tree in the image is still inodes.check "an emptied portrait category removed" \ test ! -e "$MM/data/images/portraits/Male/Astech" \ -a ! -e "$MM/data/images/portraits/Female/Astech"check "unreachable hex sets removed" test ! -e "$MM/data/images/hexes/Ahne"check "orphaned tilesets removed" \ test ! -e "$MM/data/images/hexes/largeTextures.tileset"check "foreign-project art removed" test ! -e "$MM/data/images/misc/MekHQ.png"check "art with a space in the name removed" \ test ! -e "$MM/data/images/misc/MekHQ Load_uhd.png"
check "Photoshop source art removed" \ test ! -e "$MM/data/images/widgets/kiro/border.psd"# The pattern globs through two directories whose names contain spaces. A prune# line that names such a path literally would be word-split and match nothing.check "a document under directories with spaces removed" \ test ! -e "$MM/data/boards/unofficial/UlyssesMaps/MegaMek Invitational Map Pack/MegaMek Invitational - Map Pack Rules.docx"# The first prune outside data/, and the one glob that could reach a file the# build stages after this one still compile against.check "the duplicate stock jar removed" test ! -e "$MM/lib/MegaMek.jar"check "MekHQ's planetary systems removed" \ test ! -e "$MM/data/universe/planetary_systems"
check "the portrait fallback survives" test -e "$MM/data/images/portraits/default.gif"# An MMSVersion 2 scenario whose messages: block names one of these does not# load without it - MessageDeserializer throws rather than falling back.missing=0for portrait in $(portraits_kept); do [ -e "$(portrait_path "$MM" "$portrait")" ] || missing=$((missing+1))donecheck "every portrait a shipped scenario names survives" test "$missing" -eq 0check "portrait categories the script never names survive" \ test -e "$MM/data/images/portraits/Black Widow Company/Francine.jpg"check "the kiro art the stock skins name survives" \ test -e "$MM/data/images/widgets/kiro/01.gif"check "boards beside the pruned document survive" \ test -e "$MM/data/boards/unofficial/UlyssesMaps/MegaMek Invitational Map Pack/20x20 Marik Arena - Factory.board"check "the stock jar the build compiles against survives" test -e "$MM/MegaMek.jar"check "the other jars in lib/ survive" test -e "$MM/lib/commons-io-2.21.0.jar"check "the universe data MegaMek does read survives" test -e "$MM/data/universe/eras.xml"check "the default hex set survives" test -e "$MM/data/images/hexes/saxarba.tileset"check "the fallback hex set survives" test -e "$MM/data/images/hexes/defaulthexset.txt"check "MegaMek's own splash art survives" \ test -e "$MM/data/images/misc/megamek_splash_hd.png"# Same directory as the foreign-project art, and no file names them - a glob# there that grew would take a facing's camo shading with it.check "the facing camo overlays survive" \ test -e "$MM/data/images/misc/camo_overlay0.png" -a -e "$MM/data/images/misc/camo_overlay5.png"
check "reports what it removed" grep -q "^pruned " <<<"$out"
# --- a prune line that no longer matches anything ---------------------------# What an upstream rename looks like. Shipping the bytes silently is the failure# this has to prevent, so the build must stop.MM="$TMP/mm-moved"stage_tree "$MM"rm -rf "$MM/data/images/hexes/Ahne"out="$(run_prune "$MM")"; status=$?
check "a prune that matches nothing fails the build" test "$status" -ne 0check "and names the pattern that missed" grep -q "Ahne" <<<"$out"
# --- a kept file that is not there ------------------------------------------# The prune next to it was written on the assumption that it exists, so its# absence means the assumption needs re-checking, not that the prune is fine.MM="$TMP/mm-nofallback"stage_tree "$MM"rm -f "$MM/data/images/portraits/default.gif"out="$(run_prune "$MM")"; status=$?
check "a missing kept file fails the build" test "$status" -ne 0check "and says which one" grep -q "default.gif" <<<"$out"
# --- nothing is pruned before the guards have run ---------------------------# The failure above must leave the tree alone: a build that half-prunes and then# exits non-zero is a cache entry nobody can reason about.check "a failed guard prunes nothing" \ test -e "$MM/data/images/portraits/Male/MekWarrior/MW_M_999.png"
# --- a portrait the prune keeps that upstream dropped -----------------------# The kept list was read off the scenarios; if a name is no longer in the# release the two have drifted and the scan has to be rerun. Carrying on would# put a scenario back on tests/scenarios-known-bad.txt, which is where this# started.MM="$TMP/mm-noportrait"stage_tree "$MM"victim="$(portraits_kept | head -1)"rm -f "$(portrait_path "$MM" "$victim")"out="$(run_prune "$MM")"; status=$?
check "a portrait upstream dropped fails the build" test "$status" -ne 0check "and names the portrait" grep -q "$victim" <<<"$out"
echo "$pass passed, $fail failed"[ "$fail" -eq 0 ]