With flakes running in pure mode, builtins.readDir "${pkg}/some/path" fails when any path component of "${pkg}/some/path" is a symlink to a real directory from another derivation. Can I get around this without disabling purity or overriding builds?
The error is: error: access to canonical path '/nix/store/1ql470vbl559rihw7skn5557j66759dq-emacs-28.2/share/applications' is forbidden in restricted mode
More context:
I want to do this to refer to the desktop files of a derivation dynamically in nix, I am trying to builtins.readDir "${pkg}/share/applications" (where pkg.pname == "emacs-with-packages" ).
This has worked fine for all my other pkgs. E.g. pkgs.alacritty, which contains the file "${pkg}/share/applications/Alacritty.desktop" (and "${pkg}/share/applications" is not a symlink).
I don’t have an answer to your question, but just wanted to point out that reading a derivation result from nix like this is IFD, and generally frowned upon, for a few reasons:
Nix handles IFD very poorly, causing it to start eval from scratch every time it encounters it. This means nix evaluation takes O(n^2) time in the number of IFD instances.
Hydra cannot handle IFD at all.
It prevents certain useful processes from working, such as instantiating but not building, and then walking the produced tree of .drvs to list all the FODs.
Try not to do this if you can avoid it.
That said, this sounds like a bug in nix. It really should include the whole closure of the package in the allowed paths when you do use IFD.
Thank you, indeed my evaluation has been very slow (~25s). I’ll try removing these IFDs and that causes a sub-5-second eval, your answer will have helped me more than the intended answer.
I did it, and interestingly, my evaluation time actually went up by 5 seconds. I suspect
Nix handles IFD very poorly, causing it to start eval from scratch every time it encounters it.
may have had improvements in recent nix versions and is no longer true. At any rate, since there is too little documentation around IFD for my liking, I have chosen to keep the change and am avoiding it.
Hmm. Well that was my understanding from some time back. It may have changed, or I might never have been right about it to begin with. The doc does say evaluation is “resumed”, rather than “restarted”, though I wouldn’t count on that level of nuance in wording. Probably the only way to be sure is to actually check the code.