Files
pkg/tools/build-test.sh
T
jiantw83andClaude Opus 5 ea11ca0590 fix(pkg): 補齊稽核缺失並修掉護欄失效
What:依 jsc-meta:skill-check 的稽核結果修正技能與工具——補上每個步驟的可檢核完成條件、
把留在內文的標準輸入輸出流程下放 tools/、修正查表與退碼路由造成的誤判。

Why:稽核發現這些缺失會讓技能在實際執行時走錯分支或靜默通過。
完成條件缺漏是最常被違反的一項;退碼誤判與查表錯誤則會讓良性狀況被當成失敗。

How:逐項對照 references/guidelines.md 的審核檢查清單修正,新增的工具都有
documented exit codes,並以真實執行驗證每條路徑。

Who:jsc-meta:skill-check 例行稽核(2026-08-25)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 14:58:54 +08:00

92 lines
3.4 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env sh
# build-test.sh — 偵測並執行專案的建置與測試,先建置再測試。
# 用法:build-test.sh <ecosystem> <project-dir>
# ecosystem:nodejs | python | dotnet
# 偵測方式:
# nodejs → package.json 的 scripts.build 與 scripts.test(npm init 產生的佔位 test 視為沒有)
# python → pytest 設定(pytest.ini、setup.cfg、tox.ini、pyproject.toml)或 tests 目錄與 test_*.py
# dotnet → *.sln 或 *.csproj,建置與測試都用 dotnet
# 輸出:底層指令的原始輸出。
# 結束碼(慣例見 README「工具」章的結束碼總表):
# 0 建置與測試都通過
# 1 參數個數不對
# 2 ecosystem 不認識
# 4 需要的指令不存在(npm、python3、pytest、dotnet)
# 5 推不出任何建置或測試指令——呼叫方要改問使用者
# 6 找不到專案目錄——呼叫方停手
# 其他 建置或測試失敗,帶回失敗指令的結束碼
# 本工具不用 3:3 保留給「該 ecosystem 沒有來源檔案」,這支改用 5 表達推不出指令。
set -u
if [ "$#" -ne 2 ]; then
echo "用法:build-test.sh <ecosystem> <project-dir>" >&2
exit 1
fi
eco="$1"
DIR="$2"
NO_COMMAND=5
[ -d "$DIR" ] || { echo "project dir not found: $DIR" >&2; exit 6; }
case "$eco" in
nodejs)
[ -f "$DIR/package.json" ] || { echo "no build or test command inferred for $DIR" >&2; exit "$NO_COMMAND"; }
# package.json 靠 python3 解析。少了 python3 會解出空字串,被誤判成推不出指令,所以先擋。
command -v python3 >/dev/null 2>&1 || { echo "python3 not found" >&2; exit 4; }
scripts=$(python3 - "$DIR/package.json" <<'EOF'
import json,sys
try:
d=json.load(open(sys.argv[1],encoding="utf-8"))
except Exception:
sys.exit(0)
s=(d.get("scripts") or {})
if s.get("build"): print("build")
t=s.get("test") or ""
if t and "no test specified" not in t: print("test")
EOF
)
[ -n "$scripts" ] || { echo "no build or test command inferred for $DIR" >&2; exit "$NO_COMMAND"; }
command -v npm >/dev/null 2>&1 || { echo "npm not found" >&2; exit 4; }
for s in $scripts; do
( cd "$DIR" && npm run --if-present "$s" ) || exit $?
done
exit 0
;;
python)
has_tests=0
for f in pytest.ini setup.cfg tox.ini pyproject.toml; do
if [ -f "$DIR/$f" ] && grep -q 'pytest' "$DIR/$f" 2>/dev/null; then has_tests=1; fi
done
[ -d "$DIR/tests" ] && has_tests=1
if [ "$has_tests" -eq 0 ]; then
found=$(find "$DIR" -maxdepth 3 -name 'test_*.py' 2>/dev/null | head -n 1)
[ -n "$found" ] && has_tests=1
fi
[ "$has_tests" -eq 1 ] || { echo "no build or test command inferred for $DIR" >&2; exit "$NO_COMMAND"; }
if command -v pytest >/dev/null 2>&1; then
( cd "$DIR" && pytest )
exit $?
elif command -v python3 >/dev/null 2>&1 && python3 -m pytest --version >/dev/null 2>&1; then
( cd "$DIR" && python3 -m pytest )
exit $?
else
echo "pytest not found" >&2
exit 4
fi
;;
dotnet)
projs=$(find "$DIR" -maxdepth 3 \( -name '*.sln' -o -name '*.csproj' \) 2>/dev/null)
[ -n "$projs" ] || { echo "no build or test command inferred for $DIR" >&2; exit "$NO_COMMAND"; }
command -v dotnet >/dev/null 2>&1 || { echo "dotnet not found" >&2; exit 4; }
( cd "$DIR" && dotnet build ) || exit $?
( cd "$DIR" && dotnet test ) || exit $?
exit 0
;;
*) echo "unknown ecosystem: $eco" >&2; exit 2 ;;
esac