修复了脚本问题

This commit is contained in:
ThearchyHelios
2026-11-13 17:03:58 +08:00
parent eddeded2a4
commit 4dbfec4432
2 changed files with 69 additions and 11 deletions
+58
View File
@@ -9,7 +9,10 @@
from __future__ import annotations from __future__ import annotations
import ast import ast
import os
import re
import sqlite3 import sqlite3
import subprocess
import uuid import uuid
from decimal import Decimal from decimal import Decimal
from pathlib import Path from pathlib import Path
@@ -386,3 +389,58 @@ def test_caliber_drafts_page_is_modularized():
} }
actual_modules = {p.name for p in drafts_dir.glob("*.ts*")} actual_modules = {p.name for p in drafts_dir.glob("*.ts*")}
assert expected_modules.issubset(actual_modules) assert expected_modules.issubset(actual_modules)
def test_shell_scripts_brace_variables_before_utf8_and_retention_cleanup(tmp_path):
"""macOS 自带 Bash 3.2 在 UTF-8 全角标点(如 0xEF 开头的「(」「,」「:」)紧跟未加花括号的 $VAR 时,
会把首字节 0xEF(Latin-1 字母 ï)吞入变量名,在 set -u 下触发 `VAR\\xef: unbound variable`。"""
repo_root = Path(__file__).resolve().parents[2]
unbraced_utf8_var = re.compile(r"\$([A-Za-z_][A-Za-z0-9_]*)([^\x00-\x7f])")
offenders: list[str] = []
for sh_file in sorted(repo_root.rglob("*.sh")):
if ".git" in sh_file.parts or "node_modules" in sh_file.parts:
continue
for lineno, line in enumerate(sh_file.read_text(encoding="utf-8").splitlines(), 1):
stripped = line.lstrip()
if stripped.startswith("#"):
continue
for m in unbraced_utf8_var.finditer(line):
offenders.append(f"{sh_file.relative_to(repo_root)}:{lineno} ${m.group(1)}{m.group(2)}")
assert offenders == [], f"Shell 脚本存在未加花括号且紧邻非 ASCII 字符的变量展开:{offenders}"
# 提取 package-docker.sh 第 4 节清理逻辑,在真实 bash -euo pipefail 下验证含空格路径与保留份数
pkg_text = (repo_root / "scripts" / "package-docker.sh").read_text(encoding="utf-8")
start = pkg_text.index("# ---- 4. 清理旧离线包 ----")
end = pkg_text.index("size() {", start)
cleanup_snippet = pkg_text[start:end]
out_dir = tmp_path / "release with space"
out_dir.mkdir()
stems = [f"agentlab-v{i}-linux-arm64" for i in range(1, 6)]
for idx, stem in enumerate(stems, 1):
tar_file = out_dir / f"{stem}.tar"
tar_file.write_bytes(b"x")
ts = 1_700_000_000 + idx * 60
os.utime(tar_file, (ts, ts))
proc = subprocess.run(
["bash", "-e", "-u", "-o", "pipefail", "-c", cleanup_snippet],
env={
**os.environ,
"KEEP_RELEASES": "3",
"NAME": stems[-1],
"OUT": str(out_dir),
"ARCH": "arm64",
},
capture_output=True,
text=True,
check=False,
)
assert proc.returncode == 0, proc.stderr
remaining = sorted(p.name for p in out_dir.glob("*.tar"))
assert remaining == [
"agentlab-v3-linux-arm64.tar",
"agentlab-v4-linux-arm64.tar",
"agentlab-v5-linux-arm64.tar",
]
+11 -11
View File
@@ -192,25 +192,25 @@ fi
# ---- 4. 清理旧离线包 ---- # ---- 4. 清理旧离线包 ----
if [ "$KEEP_RELEASES" -gt 0 ]; then if [ "$KEEP_RELEASES" -gt 0 ]; then
SEEN_STEMS=" $NAME " SEEN_STEMS=" ${NAME} "
KEPT_COUNT=1 KEPT_COUNT=1
for OLD_FILE in $(ls -1t "$OUT"/agentlab-*-linux-"$ARCH".tar "$OUT"/agentlab-*-linux-"$ARCH".tar.gz 2>/dev/null || true); do while IFS= read -r OLD_FILE; do
[ -f "$OLD_FILE" ] || continue [ -n "${OLD_FILE}" ] && [ -f "${OLD_FILE}" ] || continue
BASE_NAME="$(basename "$OLD_FILE")" BASE_NAME="$(basename "${OLD_FILE}")"
STEM="${BASE_NAME%.gz}" STEM="${BASE_NAME%.gz}"
STEM="${STEM%.tar}" STEM="${STEM%.tar}"
case "$SEEN_STEMS" in case "${SEEN_STEMS}" in
*" $STEM "*) ;; *" ${STEM} "*) ;;
*) *)
SEEN_STEMS="$SEEN_STEMS$STEM " SEEN_STEMS="${SEEN_STEMS}${STEM} "
KEPT_COUNT=$((KEPT_COUNT + 1)) KEPT_COUNT=$((KEPT_COUNT + 1))
;; ;;
esac esac
if [ "$KEPT_COUNT" -gt "$KEEP_RELEASES" ] && [ "$STEM" != "$NAME" ]; then if [ "${KEPT_COUNT}" -gt "${KEEP_RELEASES}" ] && [ "${STEM}" != "${NAME}" ]; then
echo "==> 清理旧离线包 $OLD_FILE(保留最近 $KEEP_RELEASES 份)" echo "==> 清理旧离线包 ${OLD_FILE}(保留最近 ${KEEP_RELEASES} 份)"
rm -f "$OLD_FILE" rm -f "${OLD_FILE}"
fi fi
done done < <(ls -1t "${OUT}"/agentlab-*-linux-"${ARCH}".tar "${OUT}"/agentlab-*-linux-"${ARCH}".tar.gz 2>/dev/null || true)
fi fi
size() { du -h "$1" | awk '{print $1}'; } size() { du -h "$1" | awk '{print $1}'; }