Nix-select, a pure query language in nix

During Thaigersprint we implemented a small query language for nix. Written in pure nix. Maybe this could be upstreamed into the nix grammar at some point. Happy to hear what people think or what other selectors we should/could support.

Link to the code: clan/nix-select - nix-select - gitea: Gitea Service

here is a little blog post with more text on howto use it (scroll down for non clan usage :slight_smile:)

32 Likes

What is the use case for this?

3 Likes

ah that is indeed a good question.

The main goal is to make the life of nix users easier.

accessing values from lists or filtering nested attributsets feels a bit cumbersome, if you are looking around it in the repl.
sometimes that can be fixed by printing the output as json, but if there is a function or something not serializable in the output that will usually fail. So the main idea is to use this to get values out of a nixos configuration to either debug something or to collect values from different positions in the nixos tree. Usually what jq is used for when working with json, but less powerful and confusing.

4 Likes

this is really cool! i have a good bit of code that would be much cleaner and using this!

This looks really helpful. Just wondering, how might filtering / joining work? I tried coming up with an idea in my head but it fell short. My basic idea was to add a where function that took in a list of filter attrsets, but combining it with the select syntax gets a little hairy.

Awesome. I’ve implemented something like this with * and set based selection but without the index based access (also no cli and caching, just a function for programmatic usage).

Do you have a version of select function which can be used with list of tokens instead of . separated string (for programmatic usage)?

how might filtering / joining work?

Not sure what you mean by those filtering / joining here, maybe you could give an example of how it could look like so I know what you mean?

I’m currently thinking of adding some more operators, like things inside the set selection {} could be recursive, so we could allow things like nixosConfigurations.ignavia.config.{networking.hostName,services.sshd.enable} but I’m still unsure how the output would look like in that case.

Another idea for an operator would be ? so you can get a key if it exists and not otherwise, It could be used inside sets or outside of it.

example:
nixosConfigurations.{mors,ignavia,?bert}.config.networking.hostName

this could return either

{ mors = "mors"; ignavia = "ignavia"; }

or maybe

{ mors = "mors"; ignavia = "ignavia"; bert = null; }
4 Likes

This is pretty cool!

It’d be neat to see a full lens library done in this style, which enabled updates and sets as well, instead of just querying.

2 Likes

@adrian-gierakowski

There is lib.atrrVals which lets you select multiple keys from a an attrset with a list. Sounds like this? or am I missing something?

@cdepillabout

for updating/changing nested attrsets recursiveUpdate with a new attrset of changes seems easier? not sure if this syntax would bring more upside for hat usecase than simple merging. There is also a version of recursiveUpdate that can merge lists in disko: disko/lib/default.nix at 15dbf8cebd8e2655a883b74547108e089f051bf0 · nix-community/disko · GitHub

2 Likes