play.wenpai.net/scripts/phpcs-scan.sh
elementary-qa fad50aa160 新增 PHPCS 静态分析作为第 10 个验收维度
- phpcs-scan.sh: WordPress-Extra 标准扫描,提取安全发现输出 JSON
- 报告生成器集成 PHPCS 维度(高危: SQL注入/CSRF, 中危: 输出未转义)
- acceptance-criteria.json 新增 phpcs 阈值,整体门槛调整为 8/10
- Justfile 新增 phpcs-scan 独立任务,test-plugin 流程自动集成
- plugin-check.sh: PCP 自动化脚本(Playground 集成,待完善)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-20 01:20:59 +08:00

69 lines
2.1 KiB
Bash
Executable file
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
# PHPCS WordPress 安全 + 编码规范扫描
# 用法: phpcs-scan.sh <plugin-dir> <output-dir>
set -euo pipefail
PLUGIN_DIR="${1:?用法: $0 <plugin-dir> <output-dir>}"
OUTPUT_DIR="${2:?用法: $0 <plugin-dir> <output-dir>}"
mkdir -p "$OUTPUT_DIR"
echo "[phpcs] 扫描: $PLUGIN_DIR"
# 完整扫描JSON 格式)
phpcs --standard=WordPress-Extra \
--extensions=php \
--report=json \
-s -n \
"$PLUGIN_DIR" \
> "$OUTPUT_DIR/phpcs-full.json" 2>/dev/null || true
# 提取安全相关发现
python3 -c "
import json, sys
with open('$OUTPUT_DIR/phpcs-full.json') as f:
data = json.load(f)
security_rules = ['Security', 'PreparedSQL']
security = []
summary = {'errors': data['totals']['errors'], 'warnings': data['totals']['warnings'], 'files': len(data['files'])}
by_rule = {}
for fpath, info in data['files'].items():
short = fpath.split('/')
# 取插件目录后的相对路径
try:
idx = next(i for i, p in enumerate(short) if p in ('includes','modules','templates','assets')) - 1
rel = '/'.join(short[idx:])
except StopIteration:
rel = '/'.join(short[-2:])
for msg in info['messages']:
src = msg.get('source', '')
is_security = any(r in src for r in security_rules)
if is_security:
security.append({
'file': rel,
'line': msg['line'],
'rule': src,
'severity': 'high' if 'PreparedSQL' in src or 'NonceVerification' in src else 'medium',
'message': msg['message'][:150]
})
by_rule[src] = by_rule.get(src, 0) + 1
result = {
'tool': 'phpcs + WordPress-Extra',
'summary': summary,
'securityFindings': len(security),
'byRule': by_rule,
'findings': security
}
with open('$OUTPUT_DIR/phpcs-security.json', 'w') as f:
json.dump(result, f, indent=2, ensure_ascii=False)
print(f'[phpcs] {summary[\"files\"]} 文件, {summary[\"errors\"]} 错误, {summary[\"warnings\"]} 警告')
print(f'[phpcs] 安全发现: {len(security)} 条')
for rule, count in sorted(by_rule.items(), key=lambda x: -x[1]):
print(f' {rule}: {count}')
"