Haskell 用 Twitch 摇一摇?

Haskell Shake with Twitch?

我正在(或尝试)从出色的 tup to haskell shake 作为我的构建系统..

只是我不知道如何在更改时重建文件。

我当然可以使用 inotify 或像 filewatcher or even watchman 这样的包装器。

虽然我使用的是 shake,但我想知道如何与共享 do 语法的 twitch 集成,但在其他方面没有提供太多文档..

最终目标是将 pandoc 用于多格式文档。

tup 不足的唯一原因是它不支持目标。

首先,您应该编写自己的 shake 构建规则。然后,当某些源文件将被更改时,您应该 运行 您的构建规则来生成您的目标。

像这样:

main = defaultMain $ do
  "src/*.md" |> const build

build = shakeArgs shake{shakeFiles="out"} $ do
    want ["out/foo.html", "out/foo.pdf"]

    "out/*.html" %> \out -> do
        let src = "src" </> dropDirectory1 out -<.> "md"
        cmd_ "pandoc -o" [out] src

    "out/*.pdf" %> \out -> do
        let src = "src" </> dropDirectory1 out -<.> "md"
        cmd_ "pandoc -o" [out] src

src 目录中的 markdown 文件被更改时,out/foo.htmlout/foo.pdf 将被更新。

如果你想优化 shake 的工作,那么你可以这样做:

main = defaultMain $ do
  "src/*.md" |> build . dependentTargets

build targets = shakeArgs shake{shakeFiles="out"} $ do
    want targets
    ...

dependentTargets src
    | "*.md" ?== src = ["out/foo.html", "out/foo.pdf"]
    | otherwise = []

软件包 twitch 建议使用扩展名 OverloadedStrings 来编译这样的代码:

"src/*.md" |> ...

但这会导致程序其他部分的代码不明确。为了解决这个问题,您可以像这样显式地将 String 转换为 Dep

import Data.String

fromString "src/*.md" |> ...

您可以通过重新定义 (|>) 运算符来改进此代码:

import Data.String
import Twitch hiding ((|>))

pattern |> callback = addModify callback $ fromString pattern

"src/*.md" |> ...

我使用 shake 构建网站并将其包装到 twitch 以在某些文件更改时重新构建 运行 抖动构建。主要调用的watching函数(用forkIO分两个目录看,每个都可以运行摇)被括号;它还会启动 Web 服务器。

mainWatch :: SiteLayout -> Port -> Path Abs Dir ->  IO ()
mainWatch layout  bakedPort bakedPath = bracketIO
        (do  -- first
            shake layout
            watchDough <-  forkIO (mainWatchDough layout)   -- calls shake
            watchTemplates <-  forkIO (mainWatchThemes layout) -- calls shake
            scotty bakedPort (site bakedPath)
            return (watchDough,watchTemplates) )
        (\(watchDough,watchTemplates) -> do -- last
                    putIOwords ["main2 end"]
                    killThread watchDough
                    killThread watchTemplates
                    return ()
            )
        (\watch -> do   -- during
                    return ()
            )

希望这可以适应您的情况!