Files
Blanton_TTL_Script/publish/publish.sh
T
etwenandClaude Opus 5 419b680980 feat(publish): Add publish.sh and sync docs for V1.0.3
publish/publish.sh packages src/Script_ABC_Blanton into
publish/Script_ABC_Blanton_<Ver>/, with -z for a zip, -f to overwrite,
-n for a dry run.

The version is read from Script A's "; Version :" header rather than
passed in, so the folder name cannot disagree with what the tester sees
on opening the macro. The header is CRLF, so the carriage return is
stripped -- left in, it becomes part of the directory name. Captured
logs are excluded (they carry DUT serials) but the empty logs/ is kept
because logopen writes there. .gitignore now admits the tool while
still ignoring its output.

config.ttl: testcase ENV, margin scan off for this run.

Docs brought up to date with the 14 commits since 8aa5c90 -- SWB
channel/address map, the traffic and BMC tooling, line-ending policy,
and the exec-bit and tail -f traps.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RetWKFZFG1ZHcitQAyhwM
2026-08-21 09:33:06 +08:00

109 lines
4.3 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.
# =============================================================================
#
# 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; }
usage() { sed -n '2,26p' "${BASH_SOURCE[0]}" | 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.
mkdir -p -- "${DEST}" || die "cannot create ${DEST}"
if command -v rsync >/dev/null 2>&1; then
rsync -a --exclude='*.log' "${SRC_DIR}/" "${DEST}/" || die "rsync failed"
else
cp -a -- "${SRC_DIR}/." "${DEST}/" || die "cp failed"
find "${DEST}" -type f -name '*.log' -delete
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