diff --git a/content/posts/why-i-do-not-use-flake-utils.md b/content/posts/why-i-do-not-use-flake-utils.md index 6f79f2c..0a2e428 100644 --- a/content/posts/why-i-do-not-use-flake-utils.md +++ b/content/posts/why-i-do-not-use-flake-utils.md @@ -11,7 +11,9 @@ For me the biggest advantage flakes bring is not additional functionality. Inste When learning flakes, you often see [flake-utils]( https://github.com/numtide/flake-utils) being used. With it, you can shorten your flakes by not having to specify everything per system. -### Without anything +_Edit_: The patterns described here as well as `flake-parts` are also compared in [Practical Nix flake anatomy](https://vtimofeenko.com/posts/practical-nix-flake-anatomy-a-guided-tour-of-flake.nix/#flake-utils-flakeparts-etc). + +## Without anything ```nix { @@ -33,7 +35,7 @@ When learning flakes, you often see [flake-utils]( https://github.com/numtide/fl } ``` -### With flake-utils +## With flake-utils ```nix { @@ -54,7 +56,7 @@ When learning flakes, you often see [flake-utils]( https://github.com/numtide/fl } ``` -### With function in flake +## With function in flake To make a long story short, here is what I usually do instead: @@ -94,16 +96,24 @@ For me, it wasn’t a problem to ignore boilerplate like this at first, slowly l At **[1]**, the supported systems are specified. I personally use `x86_64-linux` and `aarch64-linux`, but I also usually support `x86_64-darwin` and `aarch64-darwin` in public projects. If you want to support any system, you can use [`nixpkgs.lib.system.flake-exposed`](https://github.com/NixOS/nixpkgs/blob/374e6bcc403e02a35e07b650463c01a52b13a7c8/lib/systems/default.nix#L58) at **[2]** instead of defining your own list. -Because the definition is right inside the flake, you can tweak what gets passed to the function. For example, the [flake for RedoxOS-development](https://gitlab.redox-os.org/redox-os/redox/-/blob/cb34b9bd862f46729c0082c37a41782a3b1319c3/flake.nix#L38) I contributed[^1] this to passes the custom rust-toolchain. +### Example variations + +Because the definition is right inside the flake, you can tweak what gets passed to the function. +By doing that, you have to explicitly add the new identifier to each part that uses it, instead of having a global `let` binding that is implicitly used. +`system` being available here is another bonus, as otherwise this would require duplicate `let`s everywhere. + An example for how to do it is already right there: at **[3]**, `pkgs` is provided. +Some real-world usages I wrote or encountered: + +- [servicepoint-life flake](https://git.berlin.ccc.de/vinzenz/servicepoint-life/src/commit/5f5e10d39f09f4d60b4301e76f0158636afee6d1/flake.nix): passes in initialized `naersk` instance and a shorthand to refer to packages defined in the flake itself +- [RedoxOS development flake](https://gitlab.redox-os.org/redox-os/redox/-/blob/cb34b9bd862f46729c0082c37a41782a3b1319c3/flake.nix#L38): uses it to pass a custom rust-toolchain +- [my NixOS flake](https://git.berlin.ccc.de/vinzenz/nixos-configuration/src/commit/3d27f554015ece713fa22fe829d711b430d6bbda/flake.nix): uses something similar for per-host config Another possible tweak: You may want to define separate supported systems for each output. This is useful, for example, if the target environment you're developing for cannot support a development shell. +## Conclusion + For me, the trade-offs are worth it, as they provide greater transparency and control over the flake configuration. - -That being said, I fully acknowledge that `flake-utils` can still be a great choice for many people. -It simplifies things and reduces the need to write boilerplate code, which can be a plus depending on your needs and workflow. +For you, this may be different, in which case keep using it! Ultimately, it's also matter of personal preference. - -[^1]: If you check the history, you will see I am not mentioned. I am still a bit salty about that, as it was my first contribution to a bigger OSS project.