This works great. Nice and fast too. Returns true or false, based on what that value is set to.
The problem: I want it to default to false if the value is not defined at all (it’s defined in a module, so I want it to assume false if the module is not present). Currently nix eval just returns a non zero error code, so I can’t tell if it wasn’t defined or if there was a syntax error.
The icky details
I’m working on an experimental system for managing robots.
I’ve created this module to automatically revert to a previous generation if the robot doesn’t get confirmation that ssh still works. I want to make my deployment system get grumpy at the user if this module is disabled or not present.
@waffle8946 I’m confused by that answer…
It is defined as an option, with a default here.
The issue is that if the user doesn’t include the module, then that option, with its default, will not be present and the evaluation fails.
@tejing Is this what you had in mind? Looking at the documentation for tryEval, I’m guessing this doesn’t count as a “thrown error”.
[thecarl@the-carl-tower:~/Projects/ros_assistant/packages/rass-cli/example_projects/nvidia-xavier-agx]$ nix eval --read-only --apply builtins.tryEval .#nixosConfigurations.generic-x86.config.auto-revert.enable
error: flake 'git+file:///home/thecarl/Projects/ros_assistant?dir=packages/rass-cli/example_projects/nvidia-xavier-agx' does not provide attribute 'packages.x86_64-linux.nixosConfigurations.generic-x86.config.auto-revert.enable', 'legacyPackages.x86_64-linux.nixosConfigurations.generic-x86.config.auto-revert.enable' or 'nixosConfigurations.generic-x86.config.auto-revert.enable'
You could still use --apply, though. Just call it on nixosConfigurations.generic-x86.config and index into the attrset using the --apply expression, with defaults, and probably still tryEval, for the case where the option is created but never set, since the module system should throw in that case.
I’m starting to suspect what I’m trying to do may just be too far outside of the scope of Nix and I should rethink the whole idea. The ultimate goal is to detect if the auto-revert.nix module has been included into the configuration.
nix eval --read-only --apply 'config: (config.my-feature or false).enabled or false' .#nixosConfigurations.generic-x86.config
It sounds like you don’t need to catch a “not-set” error, since you provide a default value so long as the module is loaded at all. If that’s correct, then you shouldn’t need the tryEval after all.
Thank you so much for your time and patience! I had to massage it a little but that seems to do exactly what I need.
I had tried to do something similar to this but hadn’t figured out that making it a function would let me use it under apply (I still consider myself new to Nix). I’m just trying to make sure I grasp exactly how this works.
# |- If this fails to be resolved, false
# | |- Just kicks back the actual value of "enabled"
# | | |- If enabled failed to resolve, false
# | | | | - Path to our system's config. Is used as the input to the function.
# V V V V
nix eval --read-only --apply 'config: (config.my-feature or false).enabled or false' .#nixosConfigurations.generic-x86.config
Yup, you’ve got that about right. Technically the first false is a bit misleading, since it isn’t actually the return value in the case where my-feature doesn’t exist. It just ensures the second lookup fails because false isn’t an attrset and thus doesn’t have any keys. You could replace the first false with {} and it might be a little clearer how that part works.