gitlink-cli/scripts/verify.sh

166 lines
7.6 KiB
Bash
Raw Permalink 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 bash
# =============================================================================
# GitLink-CLI 子任务一 全量验证脚本(对齐 doc/DEMO-SCRIPT-SUBTASK1.md
#
# 七段验证(每段独立,可单独跑:./verify.sh <段号>,如 ./verify.sh 5
# 1 编译 + 静态检查
# 2 单元测试 + 覆盖率≥80%
# 3 命令注册冒烟show / demo / 8 个新 shortcut 模块)
# 4 能力探测(需 GITLINK_TOKEN无则跳过
# 5 终端↔网页联动Demo Mockshow + html_url + demo +run --list
# 6 五大类功能 E2EDemo Mock + 真机可选)
# 7 format 统一 + --debug 增强Demo Mock
#
# 退出码0 全绿;非 0 表示有失败段。
# =============================================================================
set -uo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
# Windows 默认二进制是 .exeLinux/macOS 无后缀。
if [ -x "$ROOT/gitlink-cli.exe" ]; then BIN="$ROOT/gitlink-cli.exe"
elif [ -x "$ROOT/gitlink-cli" ]; then BIN="$ROOT/gitlink-cli"
else BIN="" # 将在段3前构建
fi
PASS=0; FAIL=0; SKIP=0
GREEN='\033[32m'; RED='\033[31m'; YEL='\033[1;33m'; BOLD='\033[1m'; RST='\033[0m'
section(){ printf "\n${BOLD}━━━ 段 %s : %s ━━━${RST}\n" "$1" "$2"; }
ok() { printf " ${GREEN}${RST} %s\n" "$1"; PASS=$((PASS+1)); }
ng() { printf " ${RED}${RST} %s\n" "$1"; FAIL=$((FAIL+1)); }
skip() { printf " ${YEL}${RST} %s\n" "$1"; SKIP=$((SKIP+1)); }
contain() { grep -q "$1" <<<"$2"; }
# 选段:若传了段号,只跑该段。
SELECTED="${1:-all}"
run_section(){ [ "$SELECTED" = "all" ] || [ "$SELECTED" = "$1" ]; }
# ----------------------------------------------------------------------------
section 1 "编译 + 静态检查"
if run_section 1; then
if go build -o "$ROOT/.gitlink-cli.verify" . 2>err.log; then
BIN="$ROOT/.gitlink-cli.verify"; ok "go build"
else ng "go build: $(cat err.log)"; fi
if go vet ./... >err.log 2>&1; then ok "go vet"; else ng "go vet: $(cat err.log)"; fi
if [ -z "$(gofmt -s -l . 2>/dev/null | grep -v '^vendor/')" ]; then ok "gofmt -s"
else ng "gofmt -s: $(gofmt -s -l . | head -3)"; fi
if go run ./internal/i18n/cmd/check >err.log 2>&1; then ok "i18n check"
else skip "i18n check (容许 P2 前未全覆盖)"; fi
fi
# ----------------------------------------------------------------------------
section 2 "单元测试 + 覆盖率≥80%"
if run_section 2; then
# -race 留给 CI 的 Linux runnerWindows 本地 race runtime 的 DLL 依赖不稳。
RACE_FLAG=""
[ "$(go env GOOS)" != "windows" ] && RACE_FLAG="-race"
if go test $RACE_FLAG -coverprofile=coverage.verify.out ./... >test.log 2>&1; then
ok "go test ${RACE_FLAG:-(no-race)} 全绿"
else ng "go test 失败(见 test.log"; tail -5 test.log; fi
COV=$(go tool cover -func=coverage.verify.out 2>/dev/null | grep '^total:' | awk '{print $3}' | tr -d '%')
COVI=${COV%.*}
if [ -n "$COVI" ] && [ "$COVI" -ge 80 ]; then ok "覆盖率 ${COV}% ≥ 80%"
else ng "覆盖率 ${COV:-?}% < 80%"; fi
fi
# ----------------------------------------------------------------------------
section 3 "命令注册冒烟"
if run_section 3; then
[ -z "$BIN" ] && { ng "无二进制可执行(先 go build"; }
if [ -n "$BIN" ]; then
HELP=$("$BIN" --help 2>&1 || true)
for c in show demo browse status alias auth config api version; do
contain "$c" "$HELP" && ok "$c 注册" || ng "$c 未注册"
done
# 8 个新 shortcut 模块(第一类)
for grp in webhook wiki pm pipeline label member milestone notification; do
"$BIN" "$grp" --help >/dev/null 2>&1 && ok "$grp +help" || ng "$grp +help"
done
fi
fi
# ----------------------------------------------------------------------------
section 4 "能力探测(需 GITLINK_TOKEN"
if run_section 4; then
if [ -z "${GITLINK_TOKEN:-}" ]; then
skip "段4 跳过(未设置 GITLINK_TOKEN"
elif [ -z "$BIN" ]; then ng "无二进制"
else
OUT=$("$BIN" capability +check 2>&1 || true)
contain "label" "$OUT" && ok "capability +check 探测到模块" || ng "capability +check 无输出"
fi
fi
# ----------------------------------------------------------------------------
section 5 "终端↔网页联动Demo Mock"
if run_section 5 && [ -n "$BIN" ]; then
# show repo
OUT=$("$BIN" show repo --owner jiangtx --repo gitlink-cli-demo 2>&1)
contain "gitlink.org.cn/jiangtx/gitlink-cli-demo" "$OUT" && ok "show repo URL" || ng "show repo URL"
# show issue JSON html_url
OUT=$("$BIN" show issue --owner jiangtx --repo demo --number 42 --format json 2>&1)
contain '"html_url"' "$OUT" && ok "show issue JSON html_url" || ng "show issue html_url"
# show 各实体
for ent in webhook wiki label milestone member ci; do
"$BIN" show "$ent" --owner o --repo r >/dev/null 2>&1 && ok "show $ent" || ng "show $ent"
done
# demo +run --list
OUT=$("$BIN" demo +run --list 2>&1)
contain "showcase" "$OUT" && ok "demo +run --list" || ng "demo +run --list"
# browse --list / --no-open
OUT=$("$BIN" browse --owner o --repo r --list 2>&1)
contain "issues" "$OUT" && ok "browse --list" || ng "browse --list"
OUT=$("$BIN" browse --owner o --repo r --no-open issues/42 2>&1)
contain "/issues/42" "$OUT" && ok "browse --no-open issues/42" || ng "browse --no-open"
fi
# ----------------------------------------------------------------------------
section 6 "五大类功能 E2EDemo Mock"
if run_section 6 && [ -n "$BIN" ]; then
export GITLINK_DEMO=1
# 第一类:新增模块的 list
for cmd in "webhook +list --owner o --repo r" "label +list --owner o --repo r" \
"milestone +list --owner o --repo r" "member +list --owner o --repo r" \
"notification +list"; do
OUT=$("$BIN" $cmd 2>&1 || true)
(contain '"ok": true' "$OUT" || contain '"status":0' "$OUT") \
&& ok "第一类: $cmd" || ng "第一类: $cmd$OUT"
done
# 第二类:三种输出格式
for fmt in json table yaml; do
OUT=$("$BIN" repo +list --format "$fmt" 2>&1 || true)
[ -n "$OUT" ] && ok "第二类: repo +list --format $fmt" || ng "第二类: --format $fmt"
done
# 第三类:批量 dry-run
OUT=$("$BIN" issue +batch-close --owner o --repo r --numbers 1,2,3 --dry-run 2>&1 || true)
(contain "DRY RUN" "$OUT" || contain '"ok": true' "$OUT") \
&& ok "第三类: issue +batch-close --dry-run" || ng "第三类: batch-close → $OUT"
# 第五类Raw API 补全
OUT=$("$BIN" repo +languages --owner o --repo r 2>&1 || true)
(contain '"ok": true' "$OUT" || contain "Go" "$OUT") \
&& ok "第五类: repo +languages" || ng "第五类: repo +languages → $OUT"
unset GITLINK_DEMO
fi
# ----------------------------------------------------------------------------
section 7 "format 统一 + --debug 增强"
if run_section 7 && [ -n "$BIN" ]; then
export GITLINK_DEMO=1
OUT=$("$BIN" alias +list --format json 2>&1 || true)
contain '"ok": true' "$OUT" && ok "alias --format json 走 output" || skip "alias formatP1-2 前可能未统一)"
OUT=$("$BIN" issue +list --owner o --repo r --debug 2>&1 || true)
(contain "→ GET" "$OUT" || contain "→ POST" "$OUT") \
&& ok "--debug 打印请求行" || ng "--debug 请求行"
contain "Bearer \*\*\*" "$OUT" && ok "--debug Authorization redact" \
|| skip "--debug Header redactP2-2 前未实现)"
unset GITLINK_DEMO
fi
# ----------------------------------------------------------------------------
printf "\n${BOLD}━━━ 汇总 ━━━${RST}\n"
printf " ${GREEN}通过: %d${RST} ${RED}失败: %d${RST} ${YEL}跳过: %d${RST}\n" "$PASS" "$FAIL" "$SKIP"
rm -f "$ROOT/.gitlink-cli.verify" err.log test.log 2>/dev/null
[ "$FAIL" -eq 0 ]