I recently wanted to add a small script to a flake and to add a very simple shell completion to it.
First I tried to add a derivationArgs.postInstall to the writeShellApplication argument attrset, but that doesn’t seem to do anything at all - adding lib.traceVal does show the string, but even something simple like mkdir -p $out/share is not executed.
That builder uses writeTextFile underneath, which uses buildCommand rather than the standard stdenv phases, with no clean way to insert something in the middle.
There’s one phase that’s run explicitly (checkPhase) but overwriting that would defeat shellcheck.
It’s clunky, but you could use overrideAttrs for your use case:
Another option is to make a separate derivation with your completions and to symlinkJoin the two, if you really want to use writeShellApplication. Ah, that’s what you do, my bad
I wouldn’t call it ugly, personally, it’s much nicer than any override hacks, anyway, and a pretty clean way to reuse the checks the builder provides for you.
Maybe just work a bit on file structure if you really dislike it. If your issue with that is that you want to do it in one assignment for some reason you can always inline the derivations into the list.
Thanks for both suggestions and clarifications. I’ll probably keep using symlinkJoin but just move the two other derivations into a let binding for the symlinkJoin. I do like re-using the underlying checks and I don’t want to reinvent the wheel by writing a fully custom mkDerivation-based thing.