抖动规则能否确定自上次构建以来哪些 "needs" 发生了变化?

Can a shake rule determine which "needs" have changed since the last build?

我正在为大型 Ruby(+ 其他东西)代码库构建一个基于 shake 的构建系统,但我正在努力处理 Ruby 期望传递列表的命令文件到 "build".

以 Rubocop(一种 linting 工具)为例。我可以看到三个选项:

前两条规则在 shake 中构建起来很简单,但我的问题是我无法弄清楚如何将最后一种情况表示为 shake 规则。有人可以帮忙吗?

Shake 有两种方法,使用 batch or needHasChanged。对于您的情况,我假设 rubocop 只是在存在 lint 违规时出错,因此标准的一次一个规则是:

"*.rb-lint" %> \out -> do
    need [out -<.> "rb"]
    cmd_ "rubocop" (out -<.> "rb")
    writeFile' out ""

使用batch

函数 batch 自述为:

Useful when a command has a high startup cost - e.g. apt-get install foo bar baz is a lot cheaper than three separate calls to apt-get install.

代码大致如下:

batch 3 ("*.rb-lint-errors" %>)
    (\out -> do need [out -<.> "rb"]; return out) $
    (\outs -> do cmd_ "rubocop" [out -<.> "rb" | out <- outs]
                 mapM_ (flip writeFile' "") pits)

使用needHasChanged

函数 needHasChanged 自述为:

Like need but returns a list of rebuilt dependencies since the calling rule last built successfully.

所以你会写:

 "stamp.lint" *> \out -> do
     changed <- needHasChanged listOfAllRubyFiles
     cmd_ "rubocop" changed
     writeFile' out ""

比较

batch的优点是可以运行并行进行多个批次,并且可以设置批次的上限。相比之下 needHasChanged 更简单,但操作性很强。对于许多问题,两者都是合理的解决方案。这两个功能都是最近添加到 Shake 中的,因此请确保您使用的是 0.17.2 或更高版本,以确保它具有所有必要的错误修复。