运行 如果文件的一部分发生更改,则执行操作

Running an Action if part of a file changes

如果文件的一部分发生变化,运行宁一些 Action 的推荐方法是什么?

我的用例给出了一个我知道存在的文件(具体为elm-package.json),运行一个shell命令(elm package install --yes)如果文件的一部分更改(dependencies 字段)。

似乎 Oracle 抽象公开了一个值与最后一个值的比较(通过 Eq)。所以我尝试了一个 newtype 像:

newtype ElmDependencies = ElmDependencies () deriving ...
type instance RuleResult ElmDependencies = String

但是现在,我在实际使用 ElmDependencies -> Action String 类型的函数时遇到了困难,因为我想编写的规则实际上并不关心返回的字符串是什么,它只是想在字符串出现时被调用变化。

换句话说,

action $ do
    _ <- askOracle (ElmDependencies ())
    cmd_ "elm package install --yes"

顶层不行;每次都会 运行 动作。

您的 askOracle 方法非常接近,但 Shake 需要能够 识别操作的 "output",因此它可以给它一个持久的名称 在运行之间,因此其他步骤可以依赖它,并使用该持久名称来避免重新计算。一种方法是让操作创建一个戳记文件,例如:

"packages.stamp" *> \out -> do
    _ <- askOracle $ ElmDependencies ()
    cmd_ "elm package install --yes"
    writeFile' out ""
want ["packages.stamp"]

另外,使用 Oracle 的替代方法是创建一个文件 elm-package-dependencies.json 您从中生成 elm-package.json,使用 writeFileIfChanged 写入(文件为 Eq),并依赖于此 packages.stamp 中的文件。这样你就可以在文件上获得 Eq,也可以 轻松调试它或删除 -dependencies.json 文件以强制重新运行。