nickel
nickel copied to clipboard
Slightly-advanced use-cases for Nickel
I had a chat with some Tweag folks about Nickel, and I mentioned that it might be a good idea to try and make some examples of slightly more advanced use cases that people may try, to see whether they're nice to do in Nickel. I'm putting this here just to note it down, feel free to delete and move somewhere else.
Here's a few ideas based on somewhat-tricky stuff we've done at work. I don't know much about the project, so quite possibly you already have nice ways to do a lot of these!
- Build matrices
- Simplest version: you have a function
C1 -> C2 -> Derivationand you want to build it for all combinations of C1 and C2 (e.g. "system" and "compiler version") - You might also want to exclude certain combinations (programmatically)
- Conversely, you might want to include some things only in specific combinations
- Simplest version: you have a function
- Configurable derivations
- You need something like this for build matrices (functions work okay), but also to e.g. provide a variety of development shells (e.g. "you can pick the compiler version, and also whether libraries are built with profiling support")
- Also hard to make this discoverable without listing out every combination as a separate derivation.
- Shells might be part of a build matrix, or not
- Convenient adjustment of source or version inputs to a complex build recipe
- You might have a complex build recipe where you want to expose some easier-to-use knobs for less experienced users (e.g. another team member) to adjust. For example, a code formatter where you might want the user to be able to change the version, or maybe the source if you're fetching it from git or similar.
- Cross-compilation
- Also: doing it as part of a build matrix, e.g. "on Linux also build the libraries cross-compiled for Windows"
- Static binaries
- Nixpkgs overlays/package overriding
cc @thufschmitt
Convenient adjustment of source or version inputs to a complex build recipe
You might have a complex build recipe where you want to expose some easier-to-use knobs for less experienced users (e.g. another team member) to adjust. For example, a code formatter where you might want the user to be able to change the version, or maybe the source if you're fetching it from git or similar.
This one should be especially straightforward to do: it's the whole raison d'être of the merging system. You can think the NixOS modules approach, slightly simpler and built in the language. You can offer a bunch of high-level values to override, and in fact you can also override pretty much anything that is exposed as a record field. The thing is that all reverse dependencies of what you override are automatically recomputed and updated, you don't have to do anything special about it.
This probably applies to "configurable derivations" as well. Tf-ncl takes this "module"-like approach based on merging, but unfortunately I think the code is generated programmatically (because we need to include generated contracts which depend on the provider, and are generated on-demand), so I don't have a good location with a clear Nickel example to show right now. But I'll try to find a good example and link to it from here.
A lot of your other requests revolve around the theme of (build) matrices (in one form or the other), and it's an interesting problem to explore. We've done matrices before, but in ways that weren't really very specific to Nickel (we could have done the same in Nix). Now I wonder if there's a clever approach using merging, for example starting from a fairly generic base and merging with patches corresponding to specific combination/tweaks.
I would like to see nix-to-nickel so we can port the entire Nix package base to a saner standard.