How to know whether evaluation is (im)pure during runtime?

Hello,

I could successfully build disk images to bootstrap NixOS machines and it all works in a pure flake.
Now I’d love to support a “second mode” inside my flake, where I’d like to include host-specific instance data from an external file (absolute path). This works in impure evaluation.

The problem I am facing seems to be a quite general one: How do I know whether the current evaluation is pure or impure?

tryInstanceData = builtins.tryEval (
  builtins.fromJSON (
    builtins.readFile cfg.path));

Works fine in impure mode, whether cfg.path exists or not. But it rightfully throws an error in impure evaluation which I can’t catch.
Docs for try eval do state that it does not catch such errors, but no hint is given on how to catch them.
The environment variable IN_NIX_SHELL would contain the string “pure” or “impure”, but that’s for nix shell only, and isn’t set for nix build.

Any tips on how to solve this issue would be highly appreciated, thanks for reading :slight_smile:

1 Like

builtins ? currentSystem can be used to detect if it’s pure IIRC

2 Likes

Well it’s not intuitive for me, but that seems to do the job in practice - thanks!

Might it be a good Idea to add utility functions like “isPure” to nixpkgs?

There is one already https://github.com/NixOS/nixpkgs/blob/9f43cb37527eb00792cddbf6348f8eb0f364d642/lib/trivial.nix#L238

2 Likes

Thanks, so lib.inPureEvalMode is exactly what I’ve been looking for, not sure how I overlooked it.

1 Like

For the record, you can still pull in files from absolute paths during pure eval using builtins.path or even fetchurl with a file:// shcema so long as you provide a hash.

1 Like

Thanks! In my case I can’t know the hash before building, but that’s good to know!