3

I use shake to build a bunch of static webpages, which I then have to upload to a remote host, using sftp. Currently, the cronjob runs

git pull # get possibly updated sources
./my-shake-system 
lftp ... # upload

I’d like to avoid running the final command if shake did not actually rebuild anything. Is there a way to tell shake “Run command foo, after everything else, and only if you changed something!”?

Or alternatively, have shake report whether it did something in the process exit code?

I guess I can add a rule that depends on all possibly generated file, but that seems to be redundant and error prone.

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139

1 Answers1

2

Currently there is no direct/simple way to determine if anything built. It's also not such a useful concept as for simpler build systems, as certain rules (especially those that define storedValue to return Nothing) will always "rerun", but then very quickly decide they don't need to run the rules that depend on them. To Shake, that is the same as rerunning. I can think of a few approaches, which one is best probably depends on your situation:

Tag the interesting rules

You could tag each interesting rule (one that produces something that needs uploading) with a function that writes to a specific file. If that specific file exists, then you need to upload. This might work slightly better, as if you do multiple Shake runs, and in the first something changes but the second nothing does, the file will still be present. If it makes sense, use an IORef instead of a file.

Use profiling

Shake has quite advanced profiling. If you pass shakeProfile=["output.json"] it will produce a JSON file detailing what built and when. Runs are indexed by an Int, with 0 for the most recent run, and any runs that built nothing are excluded. If you have one rule that always fires (e.g. write to a dummy file with alwaysRerun) then if anything fired at the same time, it rebuilt.

Watch the .shake.database file size

Shake has a database, stored under shakeFiles. Each uninteresting run it will grow by a fairly small amount (~100 bytes) - but a fixed size given your system. If it changes in size by a greater amount, then it did something interesting.

Of these approaches, tagging the interesting rules is probably the simplest and most direct (although does run the risk of you forgetting to tag something).

Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85
  • Thanks. The tagging looks fine. – Joachim Breitner May 17 '15 at 21:26
  • Although, when done naively, it creates the marker now also when a certain rule is run, but has no effect, by using `writeFileChanged`. And `writeFileChanged` does not tell me whether it actually changed the file. I might have to use my own `writeFileChanged` for that. – Joachim Breitner May 17 '15 at 21:36
  • That's a bit yuk, but yes, would be required (and suggests the other two approaches wouldn't really work, since if you are getting that far, there's been quite a lot of rebuilding). – Neil Mitchell May 18 '15 at 10:41