2015-08-21 25 views
2

我试图找出我如何可以从进展型(在Development.Shake.Progress)进度信息输出它执行命令。可能期望的输出将是:如何在摇动中显示进度?

[1/9] Compiling src/Window/Window.cpp 
[2/9] Compiling src/Window/GlfwError.cpp 
[3/9] Compiling src/Window/GlfwContext.cpp 
[4/9] Compiling src/Util/MemTrack.cpp 
... 

现在我模拟此使用一些IOREF,保持总(最初设置为源文件的总和)和计数,我执行每个构建命令之前增加,但这对我来说似乎是一个骇人听闻的解决方案。

在这个解决方案的顶部似乎正确地清洁构建工作,但行为不端偏基础,因为所显示的金额仍然是总的所有的源文件。

通过访问Progress数据类型,我将能够使用它的countSkipped,countBuild和countTodo成员正确计算此分数(请参阅Progress.hs:53),但我仍然不确定如何实现此目的。

任何帮助表示赞赏。 Progress类型的

+0

似乎有不为那么多的支持。请参阅https://groups.google.com/forum/#!topic/shake-build-system/ZPyTIfVL-dA以获取关于摇动邮件列表上相关提案的最新讨论。 –

回答

1

值是目前仅可作为一个参数存储在shakeProgress的功能。您可以获取Progress,只要你想:

{-# LANGUAGE RecordWildCards #-} 
import Development.Shake 
import Data.IORef 
import Data.Monoid 
import Control.Monad 

main = do 
    ref <- newIORef $ return mempty 
    shakeArgs shakeOptions{shakeProgress = writeIORef ref} $ do 
     want ["test" ++ show i | i <- [1..5]] 
     "test*" %> \out -> do 
      Progress{..} <- liftIO $ join $ readIORef ref 
      putNormal $ 
       "[" ++ show (countBuilt + countSkipped + 1) ++ 
       "/" ++ show (countBuilt + countSkipped + countTodo) ++ 
       "] " ++ out 
      writeFile' out "" 

在这里,我们创建一个IORef到松鼠远传给shakeProgress参数,然后运行该规则时,取回后。运行上面的代码中,我看到:

[1/5] test5 
[2/5] test4 
[3/5] test3 
[4/5] test2 
[5/5] test1 

运行在并行的更高水平给出了不太精确的结果 - 最初出现在待办事项只有3项(摇增量countTodo在找到项目的待办事项,并尽快派生项目它知道它们中的任何一个),并且在相同索引下经常运行两个规则(没有关于正在进行多少的信息)。了解您的特定规则后,您可以细化输出,例如存储一个IORef你增加,以确保索引是单调的。

原因这个代码是有点令人费解的是,Progress信息的目的是用于异步进度消息,虽然你的做法似乎完全有效的。可能值得引入同步进度消息的getProgress :: Action Progress函数。

+0

梦幻般的解决方案!仍然会是不错的一个syncronous版本,你说.. – Fr0stBit

+0

@TheArtist:我提出一票,将其添加 - 应该不会太难:https://github.com/ndmitchell/shake/issues/293 –

+0

我会说这种方法对于更复杂的构建系统来说效果并不好,因为可能有大量的规则你不想打印输出,但他们会在计数中出现。 (另外,countTodo并不完全准确。) –