Shake是否适合为人类用户构建半自动化工具?

时间:2015-04-21 20:05:01

标签: haskell shake-build-system

如何制作每次构建时执行“外部”操作的脚本?

import Development.Shake

main = shakeArgs shakeOptions $ do
    want [".finished"]
    ".finished" %> \out -> do
      liftIO $ putStrLn "You sure?" >> getLine >> putStrLn "Missiles fired!"
$ runhaskell Main.hs
You sure?
no
Missiles fired!
Error when running Shake build system:
* .finished
Error, rule ".finished" failed to build file:
  .finished

2 个答案:

答案 0 :(得分:1)

由于您的操作未生成文件,因此需要将其标记为phony规则:

import Development.Shake
import Control.Monad (unless)

main = shakeArgs shakeOptions $ do
    want [".finished"]
    phony ".finished" $ do
        ok <- fmap (== "yes") $ liftIO $ putStrLn "You sure?" >> getLine
        unless ok $ fail "Your commitment to the Great War is lacking!"
        liftIO $ putStrLn "Missiles fired!"

示例会话:

$ runhaskell shake-phony.hs
You sure?
yes
Missiles fired!
Build completed in 0:29m

$ runhaskell shake-phony.hs
You sure?
no
Error when running Shake build system:
* .finished
Your commitment to the Great War is lacking!

答案 1 :(得分:1)

对代码的最小修复是使用像@Cactus建议的phony。另一种方法是直接使用action

import Development.Shake
import Control.Monad (unless)

main = shakeArgs shakeOptions $ do
    action $ do
        ok <- fmap (== "yes") $ liftIO $ putStrLn "You sure?" >> getLine
        unless ok $ fail "Your commitment to the Great War is lacking!"
        liftIO $ putStrLn "Missiles fired!"

如果不是在构建期间的任何时刻运行火力导弹,你实际上想要在最后运行它(在你制造导弹并储存在锡罐上之后),你可以写道:

main = do
    shakeArgs shakeOptions $ do
        ...normal build rules go here...
    ok <- fmap (== "yes") $ putStrLn "You sure?" >> getLine
    unless ok $ fail "Your commitment to the Great War is lacking!"
    putStrLn "Missiles fired!"

在运行Shake构建之后,您将使用普通的Haskell来发射导弹。