Search code examples
haskellshake-build-system

How to define a Shake rule that depends on some modification of an input


Using Shake, I want to define a rule that depends on a bunch of executables (e.g. exe, dll, etc.). However, before using them, they need to be digitally signed. Since "signing" doesn't actually produce a new file, how can I ensure that my rule depends only on files after they have been signed?

Edit: Disambiguation is in order. My rules generate some of these files, but not all of them. Some are third-party and are part of our repository. So somehow I need to depend on those static files after they have been signed.


Solution

  • One simple approach is to make the signing step do a copy first, so:

    "signed//*" *> \out -> do
        copyFile ("unsigned" </> dropDirectory1 out) out
        cmd "signer" out
    

    Another is to generate a file when signing that serves as a reminder the file has been signed:

    "programs//*.key" *> \out -> do
        writeFile' out ""
        cmd "signer" $ dropExtension out
    

    The second formulation is discouraged since generally rules shouldn't modify the value produced by other rules - it's easy to get excessive rebuilds (I think you probably would here).

    If you extra files, for exes you generate, just generate and sign them in one step - that's a fairly common pattern if you are generating a file and then editing its properties (editbin on Windows). For files you don't generate, you could sign them before you check them in, but modifying source files in the repo (which is what the 3rd party stuff looks like) is probably a bad idea anyway, so a copy is probably better.