@alanwang-merit/meritdata-platform-skill-package 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +8 -3
- package/scripts/postinstall.js +39 -0
- package/CHANGELOG.md +0 -1094
- package/docs//344/270/211/346/226/271skill/346/230/240/345/260/204/345/205/263/347/263/273/346/270/205/345/215/225_20260907.md +0 -349
- package/docs//344/272/214/345/274/20012/351/230/266/346/256/265/345/274/200/345/217/221/346/265/201/347/250/213/346/226/207/346/241/243/346/241/206/346/236/266/346/217/220/345/217/226_20260907.md +0 -286
- package/tools/skill-authoring-workflow/README.md +0 -260
- package/tools/skill-authoring-workflow/templates/SKILL-template.md +0 -35
- package/tools/skill-authoring-workflow/templates/references-template.md +0 -59
- package/tools/skill-stocktake/README.md +0 -121
- package/tools/skill-stocktake/run.sh +0 -153
- package/tools/skill-vetter/README.md +0 -119
- package/tools/skill-vetter/run.sh +0 -294
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
# skill-vetter
|
|
2
|
-
|
|
3
|
-
> 校验 meritdata-platform-suite 中所有 skill 的结构合规性。
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 用途
|
|
8
|
-
|
|
9
|
-
- CI 门禁:每次 PR 校验所有 skill 的结构
|
|
10
|
-
- 人工 review 前快速检查
|
|
11
|
-
- skill 新建后确认符合规范
|
|
12
|
-
|
|
13
|
-
## 校验项
|
|
14
|
-
|
|
15
|
-
| # | 检查项 | 严重度 |
|
|
16
|
-
|---|--------|--------|
|
|
17
|
-
| 1 | SKILL.md 存在 | 🔴 阻断 |
|
|
18
|
-
| 2 | frontmatter 完整(第 1 行 `---`)| 🔴 阻断 |
|
|
19
|
-
| 3 | 必填字段(name/description/metadata/version/layer/sub-layer/stack)| 🔴 阻断 |
|
|
20
|
-
| 4 | 4 大章节(触发 / 不触发 / 前置约束 / 路由)| 🔴 阻断 |
|
|
21
|
-
| 5 | SKILL.md 行数 ≤ 60 | 🟠 警告 |
|
|
22
|
-
|
|
23
|
-
## 用法
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# 校验全部 skill
|
|
27
|
-
bash tools/skill-vetter/run.sh
|
|
28
|
-
|
|
29
|
-
# 校验单个 skill
|
|
30
|
-
bash tools/skill-vetter/run.sh meritdata-platform-cache
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## 退出码
|
|
34
|
-
|
|
35
|
-
| 退出码 | 含义 |
|
|
36
|
-
|--------|------|
|
|
37
|
-
| 0 | 全部通过 |
|
|
38
|
-
| 1 | 有失败 |
|
|
39
|
-
|
|
40
|
-
## 输出示例
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
========================================
|
|
44
|
-
skill-vetter: skill 合规校验
|
|
45
|
-
========================================
|
|
46
|
-
扫描目录: /path/to/skills
|
|
47
|
-
|
|
48
|
-
✅ [meritdata-platform-cache] 通过
|
|
49
|
-
✅ [meritdata-platform-nacos-config] 通过
|
|
50
|
-
❌ [my-bad-skill] SKILL.md 缺少字段: sub-layer
|
|
51
|
-
✅ [meritdata-platform-session] 通过
|
|
52
|
-
|
|
53
|
-
========================================
|
|
54
|
-
结果: 28 通过 / 1 失败
|
|
55
|
-
========================================
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## 集成 CI
|
|
59
|
-
|
|
60
|
-
### GitLab CI
|
|
61
|
-
|
|
62
|
-
```yaml
|
|
63
|
-
skill-vet:
|
|
64
|
-
stage: check
|
|
65
|
-
script:
|
|
66
|
-
- bash tools/skill-vetter/run.sh
|
|
67
|
-
rules:
|
|
68
|
-
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
### GitHub Actions
|
|
72
|
-
|
|
73
|
-
```yaml
|
|
74
|
-
name: Skill Vetter
|
|
75
|
-
on: [pull_request]
|
|
76
|
-
|
|
77
|
-
jobs:
|
|
78
|
-
vet:
|
|
79
|
-
runs-on: ubuntu-latest
|
|
80
|
-
steps:
|
|
81
|
-
- uses: actions/checkout@v3
|
|
82
|
-
- run: bash tools/skill-vetter/run.sh
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## 校验失败的修复
|
|
86
|
-
|
|
87
|
-
### 缺失 frontmatter
|
|
88
|
-
|
|
89
|
-
```bash
|
|
90
|
-
# 检查 SKILL.md 第一行
|
|
91
|
-
head -1 skills/<skill>/SKILL.md
|
|
92
|
-
# 应为: ---
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
### 缺失字段
|
|
96
|
-
|
|
97
|
-
在 SKILL.md frontmatter 中补全:
|
|
98
|
-
|
|
99
|
-
```yaml
|
|
100
|
-
---
|
|
101
|
-
name: meritdata-platform-xxx
|
|
102
|
-
description: 描述
|
|
103
|
-
metadata:
|
|
104
|
-
version: "1.0.0"
|
|
105
|
-
risk: low|medium|high
|
|
106
|
-
layer: L1 | L2 | L3 | L4
|
|
107
|
-
sub-layer: L2-M | L2-C | L2-F | L3-C | L3-F | L4-T
|
|
108
|
-
stack: methodology | java | frontend | tool
|
|
109
|
-
---
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### SKILL.md 行数过长
|
|
113
|
-
|
|
114
|
-
把详细说明移到 `references/` 子文件,SKILL.md 只保留路由条目。
|
|
115
|
-
|
|
116
|
-
## 关联阅读
|
|
117
|
-
|
|
118
|
-
- [../skill-authoring-workflow/README.md](../skill-authoring-workflow/README.md) — skill 编写规范
|
|
119
|
-
- [../skill-stocktake/README.md](../skill-stocktake/README.md) — skill 清单盘点
|
|
@@ -1,294 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
# skill-vetter: 校验 meritdata-platform-suite 中所有 skill 的结构合规性(v2.6.1)
|
|
3
|
-
#
|
|
4
|
-
# 用法:
|
|
5
|
-
# bash tools/skill-vetter/run.sh # 校验全部 skill
|
|
6
|
-
# bash tools/skill-vetter/run.sh <skill-name> # 校验单个 skill
|
|
7
|
-
# bash tools/skill-vetter/run.sh --json # 校验全部 + 输出 JSON 报告
|
|
8
|
-
#
|
|
9
|
-
# 退出码:
|
|
10
|
-
# 0 - 全部通过(无 errors)
|
|
11
|
-
# 1 - 有 errors
|
|
12
|
-
# 2 - 仅 warnings
|
|
13
|
-
#
|
|
14
|
-
# v2.6.1 增强项(运维优化):
|
|
15
|
-
# 1. 死链扫描(references 内 [text](path) 链接是否解析)
|
|
16
|
-
# 2. 敏感信息扫描(password/appSecret/keytab/appToken/apiKey/accessToken/privateKey)
|
|
17
|
-
# 3. TODO/FIXME 残留扫描
|
|
18
|
-
# 4. 重复 skill name 扫描
|
|
19
|
-
# 5. JSON 报告输出(--json)
|
|
20
|
-
# 6. Summary 表格(行数 TOP-10 + 统计汇总)
|
|
21
|
-
|
|
22
|
-
SUITE_DIR="${SUITE_DIR:-$(cd "$(dirname "$0")/../.." && pwd)}"
|
|
23
|
-
SKILLS_DIR="$SUITE_DIR/skills"
|
|
24
|
-
TARGET=""
|
|
25
|
-
JSON_OUTPUT=0
|
|
26
|
-
for arg in "$@"; do
|
|
27
|
-
if [ "$arg" = "--json" ]; then
|
|
28
|
-
JSON_OUTPUT=1
|
|
29
|
-
else
|
|
30
|
-
TARGET="$arg"
|
|
31
|
-
fi
|
|
32
|
-
done
|
|
33
|
-
|
|
34
|
-
EXIT_CODE=0
|
|
35
|
-
PASS_COUNT=0
|
|
36
|
-
FAIL_COUNT=0
|
|
37
|
-
WARN_COUNT=0
|
|
38
|
-
TOTAL_SKILLS=0
|
|
39
|
-
JSON_RESULTS=()
|
|
40
|
-
TMP_LOG=/tmp/vetterlog.$$
|
|
41
|
-
|
|
42
|
-
echo "========================================"
|
|
43
|
-
echo " skill-vetter v2.6.1: skill 合规校验"
|
|
44
|
-
echo "========================================"
|
|
45
|
-
echo "扫描目录: $SKILLS_DIR"
|
|
46
|
-
echo ""
|
|
47
|
-
|
|
48
|
-
# 死链检测:传入 md 文件路径 + 链接路径,echo DEADLINK if not exists
|
|
49
|
-
check_link() {
|
|
50
|
-
local src_md="$1"
|
|
51
|
-
local link="$2"
|
|
52
|
-
# 跳过 http/https/mailto/$ 锚点
|
|
53
|
-
case "$link" in
|
|
54
|
-
http*|https*|mailto:*|\$*) return 1 ;;
|
|
55
|
-
\#*) return 1 ;;
|
|
56
|
-
esac
|
|
57
|
-
# 去掉 anchor
|
|
58
|
-
local clean="${link%%#*}"
|
|
59
|
-
[ -z "$clean" ] && return 1
|
|
60
|
-
# 处理 ./ 开头
|
|
61
|
-
clean="${clean#./}"
|
|
62
|
-
local src_dir
|
|
63
|
-
src_dir=$(dirname "$src_md")
|
|
64
|
-
local resolved=""
|
|
65
|
-
# 绝对路径(以 / 开头)相对于 suite 根目录
|
|
66
|
-
case "$clean" in
|
|
67
|
-
/*) resolved="$SUITE_DIR$clean" ;;
|
|
68
|
-
*) resolved="$src_dir/$clean" ;;
|
|
69
|
-
esac
|
|
70
|
-
# 如果包含 ../ 跳出 src_dir,允许跨 skill 引用(向上 3 层即达 suite 根)
|
|
71
|
-
if [[ "$resolved" == *"/../"* ]] || [[ "$resolved" == *"../../.."* ]]; then
|
|
72
|
-
# 跳过跨多层的复杂相对路径(已迁出范围)
|
|
73
|
-
return 1
|
|
74
|
-
fi
|
|
75
|
-
[ ! -e "$resolved" ] && echo "DEADLINK:$src_md:$link"
|
|
76
|
-
return 0
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
check_skill() {
|
|
80
|
-
local skill_dir="$1"
|
|
81
|
-
local skill_name
|
|
82
|
-
skill_name=$(basename "$skill_dir")
|
|
83
|
-
local skill_md="$skill_dir/SKILL.md"
|
|
84
|
-
local errors=0
|
|
85
|
-
local warnings=0
|
|
86
|
-
local errs_json=""
|
|
87
|
-
local warns_json=""
|
|
88
|
-
|
|
89
|
-
add_err() { echo " ERR [$skill_name] $1"; errs_json="${errs_json}\"$1\","; errors=$((errors + 1)); }
|
|
90
|
-
add_warn() { echo " WARN [$skill_name] $1"; warns_json="${warns_json}\"$1\","; warnings=$((warnings + 1)); }
|
|
91
|
-
|
|
92
|
-
# 1. SKILL.md 存在
|
|
93
|
-
if [ ! -f "$skill_md" ]; then
|
|
94
|
-
echo "FAIL [$skill_name] SKILL.md 缺失"
|
|
95
|
-
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
96
|
-
return
|
|
97
|
-
fi
|
|
98
|
-
|
|
99
|
-
# 2. frontmatter
|
|
100
|
-
head -1 "$skill_md" | grep -q '^---$' || add_err "missing frontmatter"
|
|
101
|
-
|
|
102
|
-
# 3. 必填字段(允许 0+ 前导空格)
|
|
103
|
-
for f in name description metadata version layer; do
|
|
104
|
-
grep -qE "^[[:space:]]*$f:" "$skill_md" || add_err "missing field: $f:"
|
|
105
|
-
done
|
|
106
|
-
local cur_layer
|
|
107
|
-
cur_layer=$(grep -E "^[[:space:]]*layer:" "$skill_md" | head -1 | grep -oE 'L[0-9]+' | head -1)
|
|
108
|
-
if [ "$cur_layer" != "L1" ]; then
|
|
109
|
-
for f in sub-layer stack; do
|
|
110
|
-
grep -qE "^[[:space:]]*$f:" "$skill_md" || add_err "missing field: $f:"
|
|
111
|
-
done
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
# 4. 4 大章节
|
|
115
|
-
for s in "## 触发" "## 不触发" "## 前置约束" "## 路由"; do
|
|
116
|
-
grep -q "^$s" "$skill_md" || add_err "missing section: $s"
|
|
117
|
-
done
|
|
118
|
-
|
|
119
|
-
# 5. 行数
|
|
120
|
-
local lines
|
|
121
|
-
lines=$(wc -l < "$skill_md")
|
|
122
|
-
[ "$lines" -gt 60 ] && add_warn "SKILL.md $lines lines >60"
|
|
123
|
-
|
|
124
|
-
# 6. 死链扫描(排除 .bak / dev-docs 归档目录)
|
|
125
|
-
rm -f "$TMP_LOG"
|
|
126
|
-
while IFS= read -r md_file; do
|
|
127
|
-
[ -z "$md_file" ] && continue
|
|
128
|
-
while IFS= read -r link; do
|
|
129
|
-
[ -z "$link" ] && continue
|
|
130
|
-
check_link "$md_file" "$link" >> "$TMP_LOG" 2>/dev/null || true
|
|
131
|
-
done < <(grep -oE '\[[^]]+\]\([^)]+\)' "$md_file" 2>/dev/null \
|
|
132
|
-
| grep -oE '\([^)]+\)$' \
|
|
133
|
-
| sed -e 's/^(//' -e 's/)$//')
|
|
134
|
-
done < <(find "$skill_dir" -name "*.md" -type f -not -path "*/.bak/*" -not -path "*/.bak" -not -path "*/references/dev-docs/*" 2>/dev/null)
|
|
135
|
-
if [ -f "$TMP_LOG" ] && [ -s "$TMP_LOG" ]; then
|
|
136
|
-
while IFS= read -r line; do
|
|
137
|
-
echo " ERR [$skill_name] $line"
|
|
138
|
-
errs_json="${errs_json}\"$line\","
|
|
139
|
-
errors=$((errors + 1))
|
|
140
|
-
done < "$TMP_LOG"
|
|
141
|
-
fi
|
|
142
|
-
rm -f "$TMP_LOG"
|
|
143
|
-
|
|
144
|
-
# 7. 敏感信息扫描(降级为 WARN:教学文档必然提及敏感关键词,仅作提示)
|
|
145
|
-
# 排除: description 字段 / 安全规则文档 / `${...}` 环境变量 / ✅❌ 教学标记 /
|
|
146
|
-
# 注释行(# 开头)/ 占位符(null/~/<...>/xxx/your-...)/ docker -e / .bak 归档 / dev-docs 归档
|
|
147
|
-
rm -f "$TMP_LOG"
|
|
148
|
-
while IFS= read -r md_file; do
|
|
149
|
-
[ -z "$md_file" ] && continue
|
|
150
|
-
grep -niE "(password|appSecret|appToken|keytab|api[_-]?key|access[_-]?token|private[_-]?key)" "$md_file" 2>/dev/null \
|
|
151
|
-
| grep -vE '^[[:space:]]*description:' \
|
|
152
|
-
| grep -vE '(禁止|脱敏|不要|避免|切勿|切记|严禁)' \
|
|
153
|
-
| grep -vE '\$\{[A-Za-z_][A-Za-z0-9_]*(:[^}]*)?\}' \
|
|
154
|
-
| grep -vE '(✅|❌|✓|✗)' \
|
|
155
|
-
| grep -vE '#.*(提交到 git|示例|演示|反例|样例|默认值|占位)' \
|
|
156
|
-
| grep -vE '^[[:digit:]]+:[[:space:]]*-e[[:space:]]+[A-Z_]*(PASSWORD|SECRET|KEY|TOKEN)' \
|
|
157
|
-
| grep -vE '^[[:digit:]]+:#' \
|
|
158
|
-
| grep -vE '=(null|~|xxx|XXX|your-|placeholder|<[^>]+>|xxx\.\.\.)\s*$' \
|
|
159
|
-
| grep -vE '=[^=]*\.\.\.\s*$' \
|
|
160
|
-
>> "$TMP_LOG" 2>/dev/null || true
|
|
161
|
-
done < <(find "$skill_dir" -name "*.md" -type f -not -path "*/.bak/*" -not -path "*/.bak" -not -path "*/references/dev-docs/*" 2>/dev/null)
|
|
162
|
-
if [ -f "$TMP_LOG" ] && [ -s "$TMP_LOG" ]; then
|
|
163
|
-
SENS_COUNT=$(wc -l < "$TMP_LOG")
|
|
164
|
-
echo " WARN [$skill_name] sensitive-keyword $SENS_COUNT hits(教学文档,建议人工 review)"
|
|
165
|
-
warns_json="${warns_json}\"sensitive:$SENS_COUNT hits\","
|
|
166
|
-
warnings=$((warnings + 1))
|
|
167
|
-
fi
|
|
168
|
-
rm -f "$TMP_LOG"
|
|
169
|
-
|
|
170
|
-
# 8. TODO/FIXME 残留扫描(排除 .bak)
|
|
171
|
-
rm -f "$TMP_LOG"
|
|
172
|
-
while IFS= read -r md_file; do
|
|
173
|
-
[ -z "$md_file" ] && continue
|
|
174
|
-
grep -nE "(TODO|FIXME|XXX|HACK|TBD)" "$md_file" 2>/dev/null >> "$TMP_LOG" || true
|
|
175
|
-
done < <(find "$skill_dir" -name "*.md" -type f -not -path "*/.bak/*" -not -path "*/.bak" 2>/dev/null)
|
|
176
|
-
if [ -f "$TMP_LOG" ] && [ -s "$TMP_LOG" ]; then
|
|
177
|
-
while IFS= read -r line; do
|
|
178
|
-
add_warn "TODO: $line"
|
|
179
|
-
done < "$TMP_LOG"
|
|
180
|
-
fi
|
|
181
|
-
rm -f "$TMP_LOG"
|
|
182
|
-
|
|
183
|
-
# 输出汇总
|
|
184
|
-
if [ "$errors" -gt 0 ]; then
|
|
185
|
-
echo "FAIL [$skill_name] ($errors errors / $warnings warnings)"
|
|
186
|
-
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
187
|
-
[ "$EXIT_CODE" = "0" ] && EXIT_CODE=1
|
|
188
|
-
elif [ "$warnings" -gt 0 ]; then
|
|
189
|
-
echo "WARN [$skill_name] ($warnings warnings)"
|
|
190
|
-
PASS_COUNT=$((PASS_COUNT + 1))
|
|
191
|
-
WARN_COUNT=$((WARN_COUNT + 1))
|
|
192
|
-
[ "$EXIT_CODE" = "0" ] && EXIT_CODE=2
|
|
193
|
-
else
|
|
194
|
-
echo "OK [$skill_name]"
|
|
195
|
-
PASS_COUNT=$((PASS_COUNT + 1))
|
|
196
|
-
fi
|
|
197
|
-
TOTAL_SKILLS=$((TOTAL_SKILLS + 1))
|
|
198
|
-
|
|
199
|
-
# JSON 记录
|
|
200
|
-
errs_json=$(echo "$errs_json" | sed 's/,$//')
|
|
201
|
-
warns_json=$(echo "$warns_json" | sed 's/,$//')
|
|
202
|
-
JSON_RESULTS+=("{\"skill\":\"$skill_name\",\"lines\":$lines,\"errors\":$errors,\"warnings\":$warnings,\"errs\":[$errs_json],\"warns\":[$warns_json]}")
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
# 主流程
|
|
206
|
-
if [ -n "$TARGET" ]; then
|
|
207
|
-
if [ ! -d "$SKILLS_DIR/$TARGET" ]; then
|
|
208
|
-
echo "FAIL skill 不存在: $TARGET"
|
|
209
|
-
exit 1
|
|
210
|
-
fi
|
|
211
|
-
check_skill "$SKILLS_DIR/$TARGET"
|
|
212
|
-
else
|
|
213
|
-
for skill_dir in "$SKILLS_DIR"/*/; do
|
|
214
|
-
[ -d "$skill_dir" ] || continue
|
|
215
|
-
check_skill "$skill_dir"
|
|
216
|
-
done
|
|
217
|
-
fi
|
|
218
|
-
|
|
219
|
-
# 9. 重复 skill name
|
|
220
|
-
echo ""
|
|
221
|
-
echo "========================================"
|
|
222
|
-
echo " 重复 skill name 检查"
|
|
223
|
-
echo "========================================"
|
|
224
|
-
dup_count=0
|
|
225
|
-
dup_names=$(grep -hE '^[[:space:]]*name:' "$SKILLS_DIR"/*/SKILL.md 2>/dev/null \
|
|
226
|
-
| sed -E 's/.*name:[[:space:]]*"?([^"]+)"?.*//' \
|
|
227
|
-
| sort | uniq -d)
|
|
228
|
-
if [ -n "$dup_names" ]; then
|
|
229
|
-
echo "$dup_names" | while read dup; do
|
|
230
|
-
[ -z "$dup" ] && continue
|
|
231
|
-
echo "FAIL 重复 name: $dup"
|
|
232
|
-
dup_count=$((dup_count + 1))
|
|
233
|
-
done
|
|
234
|
-
FAIL_COUNT=$((FAIL_COUNT + 1))
|
|
235
|
-
[ "$EXIT_CODE" = "0" ] && EXIT_CODE=1
|
|
236
|
-
else
|
|
237
|
-
echo "OK 0 个重复 name"
|
|
238
|
-
fi
|
|
239
|
-
|
|
240
|
-
echo ""
|
|
241
|
-
echo "========================================"
|
|
242
|
-
echo " 结果: $PASS_COUNT 通过 / $FAIL_COUNT 失败 (总计 $TOTAL_SKILLS)"
|
|
243
|
-
echo "========================================"
|
|
244
|
-
|
|
245
|
-
# 行数 TOP-10
|
|
246
|
-
echo ""
|
|
247
|
-
echo "========================================"
|
|
248
|
-
echo " SKILL.md 行数 TOP-10(最长)"
|
|
249
|
-
echo "========================================"
|
|
250
|
-
printf "%-45s %8s\n" "Skill" "Lines"
|
|
251
|
-
printf "%-45s %8s\n" "-----------------------------------------------" "--------"
|
|
252
|
-
for skill_dir in "$SKILLS_DIR"/*/; do
|
|
253
|
-
[ -d "$skill_dir" ] || continue
|
|
254
|
-
sn=$(basename "$skill_dir")
|
|
255
|
-
if [ -f "$skill_dir/SKILL.md" ]; then
|
|
256
|
-
printf "%-45s %8d\n" "$sn" "$(wc -l < "$skill_dir/SKILL.md")"
|
|
257
|
-
fi
|
|
258
|
-
done | sort -k2 -n -r | head -10
|
|
259
|
-
|
|
260
|
-
echo ""
|
|
261
|
-
echo "========================================"
|
|
262
|
-
echo " 统计汇总"
|
|
263
|
-
echo "========================================"
|
|
264
|
-
echo "skill 总数: $TOTAL_SKILLS"
|
|
265
|
-
echo "通过: $PASS_COUNT"
|
|
266
|
-
echo "失败: $FAIL_COUNT"
|
|
267
|
-
echo "仅警告: $WARN_COUNT"
|
|
268
|
-
|
|
269
|
-
# JSON 报告
|
|
270
|
-
if [ "$JSON_OUTPUT" = "1" ]; then
|
|
271
|
-
REPORT="$SUITE_DIR/vetter-report.json"
|
|
272
|
-
{
|
|
273
|
-
echo "{"
|
|
274
|
-
echo " \"version\": \"2.6.1\","
|
|
275
|
-
echo " \"timestamp\": \"$(date -Iseconds 2>/dev/null || date)\","
|
|
276
|
-
echo " \"suite_dir\": \"$SUITE_DIR\","
|
|
277
|
-
echo " \"total\": $TOTAL_SKILLS,"
|
|
278
|
-
echo " \"passed\": $PASS_COUNT,"
|
|
279
|
-
echo " \"failed\": $FAIL_COUNT,"
|
|
280
|
-
echo " \"warning_only\": $WARN_COUNT,"
|
|
281
|
-
echo " \"results\": ["
|
|
282
|
-
csep=""
|
|
283
|
-
for r in "${JSON_RESULTS[@]}"; do
|
|
284
|
-
echo " $csep$r"
|
|
285
|
-
csep=","
|
|
286
|
-
done
|
|
287
|
-
echo " ]"
|
|
288
|
-
echo "}"
|
|
289
|
-
} > "$REPORT"
|
|
290
|
-
echo ""
|
|
291
|
-
echo "JSON 报告: $REPORT"
|
|
292
|
-
fi
|
|
293
|
-
|
|
294
|
-
exit $EXIT_CODE
|