1

我有一个项目,我使用shake根据输入文件生成一堆报告,并作为一个restful webservice运行。我选择 Shake 的一个原因是,如果输入文件没有更改(例如,基于 Digest,可通过 配置shakeOptions),则不应重建任何内容。

我注意到即使我刚刚构建了这些进程并且在两次运行之间没有发生文件更改,这些进程也会运行。所以我尝试了一个简单的例子,它应该模拟我的一个构建过程

import           Control.Monad.IO.Class
import           Development.Shake

wanted = "foo.3"

main = shake shakeOptions $ do
  want [wanted]                                       -- (1)
  "*.1" %> \out -> do                                 -- (2)
    liftIO $ putStrLn out
    unit $ cmd Shell "touch" "foo.2"

  "*.2" %> \out -> do need [out]                      -- (3)
                      unit $ cmd "touch" wanted

  action $ unit $ cmd Shell "touch" wanted            -- (4)

%>规则永远不会运行 -action规则总是完成。

如果我注释掉 (4) 并手动创建文件“foo.1” - 规则 (1) 失败,因为它没有弄清楚 (2) -> (3) 可以构建结果。

另一方面,如果我注释掉 (2) 和 (3) 并离开 (4) - 即使“foo.3”存在并且之前已通过摇动“构建”,规则也会运行。

我将shake-0.15.11与shake结合使用-使用shake runhaskell Main.hs --package shakeshake exec -- testshake没有任何区别。编译器是 GHC-8.0.2。所有这些都是在 Linux (Mint) 上完成的。

我阅读了 Shake 如何决定是否重建目标?- 我从中收集到,只有当输入文件或输出文件发生变化(变化由shakeOptions配置决定)时,才会重建东西

4

1 回答 1

1

首先,pat %> act意味着您创建了 file-build-rule,它将针对任何文件路径运行,该模式将被接受pat。这意味着如果有人调用then 将运行带有参数need [foo]的操作。因此,该操作应该尝试 build 。pat ?== fooactfooactfoo

其次,关于action,如文档中所述:

该操作将在每次构建执行中运行(除非使用 withoutActions)。

wand定义如下:want = action . need.

例如,我重新设计了您的示例,并假设了您的文件之间的依赖关系。即, foo.3 需要 foo.2, foo.2 需要 foo.1 并且 foo.1 已经存在(它的源代码)。

wanted = "foo.3"
main = shake shakeOptions $ do
    want [wanted]

    "*.3" %> \out -> do                      
        putNormal out
        need [out -<.> ".2"]
        unit $ cmd Shell "touch" out

    "*.2" %> \out -> do
        putNormal out
        need [out -<.> ".1"]
        unit $ cmd Shell "touch" out
于 2017-05-04T15:14:12.580 回答