全自动化验证技巧:programming-scala-book-code-examples 的 check-scripts.sh 与 check-mains.sh 脚本指南
【免费下载链接】programming-scala-book-code-examplesThe code examples used in Programming Scala, 2nd and 3rd Editions (O'Reilly)项目地址: https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples
你是否想过,一本几百页的编程书,背后几百个代码示例是如何保证"一个都不出错"的?这个项目的答案是两把自动化验证利器:check-scripts.sh与check-mains.sh。本文为你拆解 programming-scala-book-code-examples(《Programming Scala》第 2、3 版的官方代码仓库)中的这套全自动化验证方案,即使你完全不懂 Shell 脚本,也能看懂它背后的设计智慧,并学会把它迁移到自己的项目中。
为什么代码示例需要"半自动化"验证?
书中的示例分为两类,验证难度完全不同:
- 可编译源码:位于
src/main/scala,由sbt test正常构建和测试; - REPL 脚本:位于
src/script/scala,只适合在交互式控制台里逐行加载,scalac根本编不过; - 大量
@main入口:虽然有 main 方法,却不属于任何单元测试。
更要命的是,作者为了讲清楚"错误长什么样",故意在部分文件里埋了编译错误(代码里常见// ERROR注释)。普通测试框架遇到这些文件直接报红,完全没法用。于是,作者写下了这两个脚本,用"知道哪些文件该错"的方式实现了代码示例自动化检查。
check-scripts.sh:REPL 脚本的自动化验证方法
check-scripts.sh(位于仓库根目录)专门对付src/script/scala下那些"不能编译、只能解释"的脚本。
它的验证思路非常巧妙:
- 对每个
.scala脚本文件启动sbt console(Scala REPL); - 用
:load 文件路径把脚本加载进解释器; - 把整个会话输出保存到
target/script-tests/下的同名.out文件; - 用正则表达式在输出里搜索
N errors found、N warnings found之类的关键行; - 把有问题的文件汇总写入带时间戳的错误日志(如
target/script-tests/scripts-errors-2026-08-19_08-02-35.log)。
最贴心的是expected_errors_in白名单机制:脚本内置了一张"已知故意报错"的文件清单(比如src/script/scala/progscala3/patternmatching/MatchSurprise.scala这种演示不可达 case 分支的文件),这些文件即使报错也被视为"符合预期"而放行,但依然会记录在日志里提醒人工复核。这就是它被称为"半自动化"的原因——机器负责抓大错,人负责看细节。
check-mains.sh:入口程序的一键批量运行验证
如果说check-scripts.sh管"脚本",那check-mains.sh管的就是"入口"。它维护了一个def_mains清单,列出了仓库里几十个 main 入口,例如progscala3.introscala.UpperMain1、progscala3.contexts.json.TryJSONBuilder等。
它的运行流程与前者镜像对称:用sbt runMain 类名逐个执行,输出保存到target/main-tests/,错误写入mains-errors-时间戳.log。它还支持给特定 main 传参数——通过mains_args关联数组,比如给性能测试InlinePerf传入true 10,给CommandArgs传入--help,实现了带参数的自动化运行验证。
两个脚本的通用命令行选项
这两个脚本的参数设计高度一致,几乎可以无缝迁移到任何语言项目的验证流程中:
| 选项 | 作用 |
|---|---|
-h/--help | 打印完整帮助文档 |
-v/--verbose | 边执行边打印每个文件的处理情况和完整输出 |
-c/--clean | 先清空旧的target/script-tests或target/main-tests目录 |
-n/--no-exec | 只打印将要执行的命令,不真正运行(演练模式) |
--check | 不重新运行,只基于已有输出文件检查错误 |
默认情况下check-scripts.sh扫描整个src/script/scala目录,check-mains.sh运行全部默认 main 清单;你也可以把具体目录或类名作为参数传入,做局部验证。
配套的另外两把"小工具"
除了两个主角,仓库根目录还有两个辅助脚本值得了解:
check-head-comment.sh:验证每个源码文件开头的路径注释是否与文件实际位置一致。书中代码用// src/main/scala/progscala3.introscala.UpperMain1这类注释标注出处,一旦文件被移动而注释没改,就会造成"书里找不到代码"的困惑,这个脚本专治这种小毛病;make-worksheets.sh:把src/script/scala下的脚本复制到 worksheet 目录并把扩展名改为.worksheet.sc,方便在 VSCode 等 IDE 里当工作表用。
把这套自动化验证技巧迁移到你的项目
这套方案最值得借鉴的不是代码,而是三点设计思想:
- 白名单容忍"预期失败":教学类代码故意出错是常态,与其让 CI 红灯,不如明确"哪些失败是被允许的",并单独记录供人工复查;
- 输出留痕:每次运行都生成带时间戳的输出文件和错误日志,方便事后逐条核对,而不是只给一个"通过/失败"的结论;
- 分而治之:脚本文件用解释器加载验证,main 方法用运行器验证,头部注释单独抽一个脚本验证,各司其职,互不干扰。
如果你想亲手体验这套全自动化验证流程,可以克隆仓库后直接运行:
git clone https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples然后进入仓库根目录执行./check-scripts.sh -n(演练模式,先看看它会做什么),再正式运行./check-scripts.sh和./check-mains.sh。注意作者在 README 中提醒:两个脚本都比较耗时,且最终输出仍建议人工抽查——毕竟,机器保证"不犯低级错误",人保证"结果真的正确",这才是代码示例质量检查的最佳组合。
【免费下载链接】programming-scala-book-code-examplesThe code examples used in Programming Scala, 2nd and 3rd Editions (O'Reilly)项目地址: https://gitcode.com/gh_mirrors/pr/programming-scala-book-code-examples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考