mktemp -d is definitely the way to go! Most notably mktemp -d ensures that it’s a fresh directory. So you don’t have to worry about the path potentially being polluted already.
Does Nix do anything to ensure that mktemp -d directories are cleaned up after a build? Or are package authors responsible for putting a trap 'rm -rf $whatever' EXIT in the relevant phase script?
nix-shell doesn’t have any clean-up phase like nix-build, so I think it’s best if temporary directories are created inside the build directory/current working directory and/or using trap 'rm -rf...' EXIT.
Do nix-shell and nix-build have the same value for TMPDIR? Because if nix-shell sets it to a tmpfs partition — e. g., /run —, the created directory would be cleaned up after a reboot and, thus, there would be no need for the trap call.
Sorry for digging this up, but it still seems like the most relevant issue, and I’ve been thinking about how to deal with this.
It looks like nix-shell respects TMPDIR and if it’s set, will use it for both TMPDIR and NIX_BUILD_TOP inside the shell.
nix develop goes a step further and invokes the shell with a fresh mktemp -d set as both TMPDIR and NIX_BUILD_TOP, which it cleans up when the shell exits.
I don’t think traps are really an option because you need some way to compose them, and stdenv already sets an EXIT trap. It does expose failureHook and exitHook, but only calls one or the other, and I don’t see anything in nixpkgs using these for cleanup.
Based on all that, I think the best option is just to use mktemp and either use nix develop, or be careful about the TMPDIR used with nix-shell.
Expecting NIX_BUILD_TOP (or TMPDIR) to be empty seems like a bad idea, given how nix-shell works. So I would avoid doing things like:
I don’t have the best sense of whether working around trap’s limitations here is enough to meet your needs, but here’s a post showing how to work around this with a trap-shimming shell library I wrote: