I have a project where I use shake to generate a bunch of reports based on input-files, and run as a restful webservice. One reason why I chose Shake is that is should not rebuild anything if input-files have not changed (e.g. based on Digest, configurable via shakeOptions
).
I noticed that the processes would run even if I had just built them and no file change had happened in between runs. So I tried a simple example it should simulate the process of one of my builds
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)
while the %>
rules never run - the action
rule is always done.
If I comment out (4) and create a file "foo.1" manually - the rule (1) is failing because it does not figure out that (2) -> (3) can build the result.
If on the other hand I comment out (2) and (3) and leave (4) - the rule runs even if "foo.3" exists and has been "built" by shake before.
I am using shake-0.15.11 in combination with shake - using shake runhaskell Main.hs --package shake
or shake exec -- testshake
does not make any difference. Compiler is GHC-8.0.2. All of this is done on a Linux (Mint).
I read How does Shake decide whether to rebuild a target? - from which I gathered that shake rebuilds stuff only if either the input-file(s) or the output-file change (where change is determined by the shakeOptions
configuration)