1

I have the following build system

module Main where

import Development.Shake

main :: IO ()
main = shakeArgs shakeOptions $ do

  "a" %> \out -> do
    need ["a.in"]
    cmd_ "sleep" "10"
    cmd "touch" [out]

which I build with stack build and run with stack exec myShake -- --progress a.

If I do a clean build and than touch a.in and run again, shake shows me very wrong progress predictions. Sometimes it predicts 1000 minutes and more.

(As I get a progress prediction in the title bar of my terminal every 5 seconds, if I understood this correctly, I only talk about the first progress prediction here, as this is the only one I get with this build system example.)

I use lts-9.6 with stack and shake version 0.16 (via git + an entry in packages in stack.yaml).

typetetris
  • 4,586
  • 16
  • 31

2 Answers2

1

It looks like the first progress estimation message is generally useless. For non trivial build systems this shouldn't be a problem, as they take way longer than five seconds.

Using this build system and --progress=1 one can see, that the first estimation is way of, but the others get better:

module Main where

import Development.Shake

main :: IO ()
main = shakeArgs shakeOptions $ do
  mapM_ (\i ->
    ("a." ++ show i) %> \out ->
      do
        need [out ++ ".in", "a." ++ show (i-1)]
        cmd_ "sleep" "1"
        cmd "touch" [out])
    [1 .. 10]

  "a.0" %> \out -> do
    need ["a.0.in"]
    cmd_ "sleep" "1"
    cmd "touch" [out]

To try this out, you need to do

for i in $(seq 0 10); do touch a.$i.in; done

in the working dir you use with this example build system.

typetetris
  • 4,586
  • 16
  • 31
1

The documentation for how progress works can be found at progressDisplay:

The current implementation is to predict the time remaining (based on timeTodo) and the work already done (timeBuilt). The percentage is then calculated as remaining / (done + remaining), while time left is calculated by scaling remaining by the observed work rate in this build, roughly done / time_elapsed.

In the case of very short build systems which only do a single thing the work-rate is generally garbage - so you end up scaling the work remaining (which is probably predicted at 10s) with a random number (presumably a big number, to get 1000m).

The idea of work rate changing is that sometimes you are on a laptop on battery power vs mains power, and sometimes you pass different parallelism flags. It's quite possible Shake should use either one or number of threads as an approximation of the work rate, at least to begin with.

Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85