feat(repro-audit): 批量模式单仓失败容错并列入汇总;新增 5 仓库真实批量 demo 输出

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
farmyobutu5233 2026-07-05 12:25:02 +00:00
parent c1a0e4cc61
commit 5089874cd6
5 changed files with 56 additions and 8 deletions

View File

@ -0,0 +1,6 @@
# 真实科研相关仓库批量复现性审计清单
GengzhaoWang/UAV-Paper
momomym/paper-summarizer
zhaoyihan/paper-data-redundancy
steph1/Awesome-Paper-Crawler
datawhalechina/paper-chart-tutorial

View File

@ -0,0 +1,17 @@
# 科研复现性审计报告steph1/Awesome-Paper-Crawlerref: 默认分支)
**总分8/100 — 等级 D复现困难**
| 检查项 | 得分 | 证据 | 建议 |
|--------|------|------|------|
| README 与运行说明 | 8/15 | README=README.md运行/复现章节=未检出 | 补充 README 并加入 How to run / 复现步骤章节 |
| 开源许可证 | 0/15 | 许可证文件=缺失 | 添加 LICENSE 文件(科研代码推荐 MIT/Apache-2.0/BSD |
| 引用信息 | 0/10 | CITATION 文件=无README 引用章节=无 | 添加 CITATION.cff 或在 README 中给出 BibTeX |
| 依赖清单(环境固化) | 0/15 | 依赖文件=缺失 | 添加 requirements.txt / environment.yml 等依赖清单并固定版本 |
| 运行入口 | 0/10 | 入口=未检出 | 提供 Makefile / run.sh / main.py 等一键运行入口 |
| 数据可得性说明 | 0/10 | 数据目录=无README 数据说明=无 | 在 README 中说明数据集来源、获取方式与预处理步骤 |
| 测试/验证代码 | 0/10 | 测试目录=无 | 添加 tests/ 验证关键结果可复算 |
| 版本发布(成果固化) | 0/15 | release 数=0 | 为论文对应的代码状态打 tag 并创建 release |
---
*由 repro-audit 生成(确定性检查,同输入同输出)。*

View File

@ -0,0 +1,12 @@
# 批量复现性审计汇总
| 仓库 | 得分 | 等级 |
|------|------|------|
| momomym/paper-summarizer | 58/100 | C存在明显缺口 |
| GengzhaoWang/UAV-Paper | 8/100 | D复现困难 |
| steph1/Awesome-Paper-Crawler | 8/100 | D复现困难 |
## 无法审计的仓库
- datawhalechina/paper-chart-tutorialgitlink-cli repo +tree --owner datawhalechina --repo paper-chart-tutorial --format json 失败: [-2] 你访问的文件不存在
- zhaoyihan/paper-data-redundancygitlink-cli repo +tree --owner zhaoyihan --repo paper-data-redundancy --format json 失败: [-2] 你访问的文件不存在

View File

@ -205,13 +205,16 @@ def read_repos_file(path):
return repos
def render_summary(rows):
"""批量审计汇总表(确定性:按得分降序、同分按名称)。"""
def render_summary(rows, failures=()):
"""批量审计汇总表(确定性:按得分降序、同分按名称;失败仓库单独列出)。"""
rows = sorted(rows, key=lambda r: (-r[1], r[0]))
lines = ["# 批量复现性审计汇总", "", "| 仓库 | 得分 | 等级 |", "|------|------|------|"]
for name, total in rows:
grade = next(g for t, g in GRADE if total >= t)
lines.append(f"| {name} | {total}/100 | {grade} |")
if failures:
lines += ["", "## 无法审计的仓库", ""]
lines += [f"- {name}{reason}" for name, reason in sorted(failures)]
return "\n".join(lines) + "\n"
@ -233,17 +236,22 @@ def main():
out_dir.mkdir(parents=True, exist_ok=True)
if args.repos_file:
rows = []
rows, failures = [], []
for owner, repo in read_repos_file(args.repos_file):
total = audit_repo(owner, repo, args.ref, out_dir, args.cli,
apply_issue=args.apply, echo=False)
rows.append((f"{owner}/{repo}", total))
summary = render_summary(rows)
name = f"{owner}/{repo}"
try:
total = audit_repo(owner, repo, args.ref, out_dir, args.cli,
apply_issue=args.apply, echo=False)
rows.append((name, total))
except RuntimeError as exc:
print(f"跳过 {name}{exc}", file=sys.stderr)
failures.append((name, str(exc)))
summary = render_summary(rows, failures)
summary_path = out_dir / "repro-audit-summary.md"
summary_path.write_text(summary, encoding="utf-8")
print(summary)
print(f"汇总已保存:{summary_path}", file=sys.stderr)
return 0 if all(t >= 70 for _, t in rows) else 2
return 0 if not failures and all(t >= 70 for _, t in rows) else 2
total = audit_repo(args.owner, args.repo, args.ref, out_dir, args.cli,
apply_issue=args.apply)

View File

@ -89,6 +89,11 @@ class AuditTest(unittest.TestCase):
self.assertIn("A可复现性良好", rows[0])
self.assertIn("D复现困难", rows[2])
def test_render_summary_lists_failures(self):
summary = render_summary([("o/ok", 80)], failures=[("o/broken", "仓库树读取失败")])
self.assertIn("## 无法审计的仓库", summary)
self.assertIn("- o/broken仓库树读取失败", summary)
if __name__ == "__main__":
unittest.main()