Files
Blanton_TTL_Script/publish/publish.sh
T
etwenandClaude Opus 5 4f2f9ed090 chore(publish): Keep the mlucas binaries out of git and the bundle
src/Script_ABC_Blanton/hammer/ is ~99 MB of unstripped mlucas ELF
binaries (avx512 / avx2 / avx / sse2 / generic-c). They come with the DUT
image, so this repo has no reason to carry them - and a binary tree that
size is permanent once committed: every clone pays for it forever.

publish.sh excluded them too, because rsync copies whatever happens to be
sitting in src/. Without the exclude the delivery bundle was ~100 MB from
a machine that had the binaries and ~200 KB from a fresh clone.

While there, usage() read a fixed line range of the header, so adding a
Version History entry pushed code into the usage text. It now reads up to
the first line of code.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-09-06 17:21:39 +08:00

121 lines
5.0 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# publish.sh -- package src/Script_ABC_Blanton for delivery
# =============================================================================
# Version History:
# V1.0.0 2026-08-21 Initial. Copies src/Script_ABC_Blanton to
# publish/Script_ABC_Blanton_<Version>, taking <Version>
# from the "; Version : Vx.y.z" header of
# 1_Blanton_Script_A.ttl.
# V1.0.1 2026-09-06 Exclude hammer/ (the mlucas binaries) from the bundle,
# so the output no longer depends on whether the developer
# has them in their working tree.
# =============================================================================
#
# The version is READ FROM Script A rather than passed in, so the folder name
# can never disagree with the header the tester sees when they open the macro.
# Bump Script A's header first, then run this.
#
# Usage:
# ./publish/publish.sh # publish at Script A's version
# ./publish/publish.sh -v V1.0.4 # override the version
# ./publish/publish.sh -f # overwrite an existing output folder
# ./publish/publish.sh -z # also produce a .zip next to it
# ./publish/publish.sh -n # dry run: print what would happen
# =============================================================================
set -u
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
SRC_DIR="${REPO_ROOT}/src/Script_ABC_Blanton"
OUT_ROOT="${SCRIPT_DIR}"
NAME="Script_ABC_Blanton"
VER=""; FORCE=0; ZIP=0; DRY=0
info() { printf '[\033[34mINFO\033[0m] %s\n' "$*"; }
ok() { printf '[\033[32m OK \033[0m] %s\n' "$*"; }
die() { printf '[\033[31mERR \033[0m] %s\n' "$*" >&2; exit 1; }
# Print the header block above, up to (but not including) the first line of
# code, so adding a Version History entry never truncates the usage text.
usage() { sed -n '2,/^set -u/p' "${BASH_SOURCE[0]}" | sed '$d' | sed 's/^# \{0,1\}//'; exit 0; }
while [ $# -gt 0 ]; do
case "$1" in
-v|--version) VER="${2:-}"; shift 2 ;;
-f|--force) FORCE=1; shift ;;
-z|--zip) ZIP=1; shift ;;
-n|--dry-run) DRY=1; shift ;;
-h|--help) usage ;;
*) die "unknown option '$1' (try -h)" ;;
esac
done
[ -d "${SRC_DIR}" ] || die "source not found: ${SRC_DIR}"
# --- version from Script A's header ------------------------------------------
# The .ttl files are CRLF, so strip the carriage return or it lands in the
# folder name and produces a directory no one can cd into.
if [ -z "${VER}" ]; then
A_TTL="${SRC_DIR}/1_Blanton_Script_A.ttl"
[ -f "${A_TTL}" ] || die "cannot read version: ${A_TTL} missing"
VER=$(grep -m1 -E '^;[[:space:]]*Version[[:space:]]*:' "${A_TTL}" \
| tr -d '\r' | sed -E 's/.*:[[:space:]]*//; s/[[:space:]]+$//')
[ -n "${VER}" ] || die "no '; Version : Vx.y.z' header in $(basename "${A_TTL}")"
info "version from $(basename "${A_TTL}") : ${VER}"
else
info "version (overridden) : ${VER}"
fi
case "${VER}" in
V[0-9]*) ;;
*) die "version '${VER}' does not look like Vx.y.z" ;;
esac
DEST="${OUT_ROOT}/${NAME}_${VER}"
info "source : ${SRC_DIR#${REPO_ROOT}/}"
info "destination : ${DEST#${REPO_ROOT}/}"
if [ -e "${DEST}" ]; then
[ "${FORCE}" = "1" ] || die "${DEST##*/} already exists (use -f to overwrite)"
[ "${DRY}" = "1" ] || rm -rf -- "${DEST}"
info "existing folder removed (-f)"
fi
if [ "${DRY}" = "1" ]; then
info "dry run: nothing copied"
exit 0
fi
# --- copy ---------------------------------------------------------------------
# Captured console logs are per-run and often carry DUT serials, so they are
# never shipped; the empty logs/ directory itself is kept because Script A's
# logopen writes into it.
#
# hammer/ is excluded as well: it is ~99 MB of mlucas ELF binaries that the DUT
# image already carries, and it is gitignored. Without this exclude the bundle
# would depend on whether the developer happened to have the binaries sitting in
# src/ - 100 MB from one machine, 200 KB from a fresh clone.
mkdir -p -- "${DEST}" || die "cannot create ${DEST}"
if command -v rsync >/dev/null 2>&1; then
rsync -a --exclude='*.log' --exclude='hammer/' "${SRC_DIR}/" "${DEST}/" \
|| die "rsync failed"
else
cp -a -- "${SRC_DIR}/." "${DEST}/" || die "cp failed"
find "${DEST}" -type f -name '*.log' -delete
rm -rf -- "${DEST}/hammer"
fi
# Tera Term's logopen target, in case the source tree never had one
mkdir -p -- "${DEST}/logs"
n_files=$(find "${DEST}" -type f | wc -l)
ok "${n_files} files -> ${DEST##*/}"
if [ "${ZIP}" = "1" ]; then
command -v zip >/dev/null 2>&1 || die "zip not installed"
( cd -- "${OUT_ROOT}" && rm -f -- "${NAME}_${VER}.zip" \
&& zip -qr "${NAME}_${VER}.zip" "${NAME}_${VER}" ) || die "zip failed"
ok "$(du -h "${OUT_ROOT}/${NAME}_${VER}.zip" | cut -f1) -> ${NAME}_${VER}.zip"
fi