#!/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_, taking # 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