feat(repro-audit): 批量模式单仓失败容错并列入汇总;新增 5 仓库真实批量 demo 输出
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
c1a0e4cc61
commit
5089874cd6
|
|
@ -0,0 +1,6 @@
|
||||||
|
# 真实科研相关仓库批量复现性审计清单
|
||||||
|
GengzhaoWang/UAV-Paper
|
||||||
|
momomym/paper-summarizer
|
||||||
|
zhaoyihan/paper-data-redundancy
|
||||||
|
steph1/Awesome-Paper-Crawler
|
||||||
|
datawhalechina/paper-chart-tutorial
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# 科研复现性审计报告:steph1/Awesome-Paper-Crawler(ref: 默认分支)
|
||||||
|
|
||||||
|
**总分: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 生成(确定性检查,同输入同输出)。*
|
||||||
|
|
@ -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-tutorial:gitlink-cli repo +tree --owner datawhalechina --repo paper-chart-tutorial --format json 失败: [-2] 你访问的文件不存在
|
||||||
|
- zhaoyihan/paper-data-redundancy:gitlink-cli repo +tree --owner zhaoyihan --repo paper-data-redundancy --format json 失败: [-2] 你访问的文件不存在
|
||||||
|
|
@ -205,13 +205,16 @@ def read_repos_file(path):
|
||||||
return repos
|
return repos
|
||||||
|
|
||||||
|
|
||||||
def render_summary(rows):
|
def render_summary(rows, failures=()):
|
||||||
"""批量审计汇总表(确定性:按得分降序、同分按名称)。"""
|
"""批量审计汇总表(确定性:按得分降序、同分按名称;失败仓库单独列出)。"""
|
||||||
rows = sorted(rows, key=lambda r: (-r[1], r[0]))
|
rows = sorted(rows, key=lambda r: (-r[1], r[0]))
|
||||||
lines = ["# 批量复现性审计汇总", "", "| 仓库 | 得分 | 等级 |", "|------|------|------|"]
|
lines = ["# 批量复现性审计汇总", "", "| 仓库 | 得分 | 等级 |", "|------|------|------|"]
|
||||||
for name, total in rows:
|
for name, total in rows:
|
||||||
grade = next(g for t, g in GRADE if total >= t)
|
grade = next(g for t, g in GRADE if total >= t)
|
||||||
lines.append(f"| {name} | {total}/100 | {grade} |")
|
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"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -233,17 +236,22 @@ def main():
|
||||||
out_dir.mkdir(parents=True, exist_ok=True)
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
if args.repos_file:
|
if args.repos_file:
|
||||||
rows = []
|
rows, failures = [], []
|
||||||
for owner, repo in read_repos_file(args.repos_file):
|
for owner, repo in read_repos_file(args.repos_file):
|
||||||
total = audit_repo(owner, repo, args.ref, out_dir, args.cli,
|
name = f"{owner}/{repo}"
|
||||||
apply_issue=args.apply, echo=False)
|
try:
|
||||||
rows.append((f"{owner}/{repo}", total))
|
total = audit_repo(owner, repo, args.ref, out_dir, args.cli,
|
||||||
summary = render_summary(rows)
|
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 = out_dir / "repro-audit-summary.md"
|
||||||
summary_path.write_text(summary, encoding="utf-8")
|
summary_path.write_text(summary, encoding="utf-8")
|
||||||
print(summary)
|
print(summary)
|
||||||
print(f"汇总已保存:{summary_path}", file=sys.stderr)
|
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,
|
total = audit_repo(args.owner, args.repo, args.ref, out_dir, args.cli,
|
||||||
apply_issue=args.apply)
|
apply_issue=args.apply)
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,11 @@ class AuditTest(unittest.TestCase):
|
||||||
self.assertIn("A(可复现性良好)", rows[0])
|
self.assertIn("A(可复现性良好)", rows[0])
|
||||||
self.assertIn("D(复现困难)", rows[2])
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue