From 89b779f6bfbd476d5302e740a4ad3263a15a8974 Mon Sep 17 00:00:00 2001 From: Akshay Date: Tue, 5 Oct 2021 22:21:58 +0530 Subject: new post: "Novice Nix: Flake Templates" --- docs/posts/novice_nix:_flake_templates/index.html | 221 ++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 docs/posts/novice_nix:_flake_templates/index.html (limited to 'docs/posts/novice_nix:_flake_templates/index.html') diff --git a/docs/posts/novice_nix:_flake_templates/index.html b/docs/posts/novice_nix:_flake_templates/index.html new file mode 100644 index 0000000..f71c13a --- /dev/null +++ b/docs/posts/novice_nix:_flake_templates/index.html @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + Novice Nix: Flake Templates · peppe.rs + +
+
+ Home + / + Posts + / + Novice Nix: Flake Templates + View Raw +
+
+ 05/10 — 2021 +
+ + 91.51 + + cm +   + + 5.5 + + min +
+
+

+ Novice Nix: Flake Templates +

+
+

Flakes are very handy to setup entirely pure, project-specific dependencies (not just dependencies, but build steps, shell environments and more) in a declarative way. Writing Flake expressions can get repetitive though, oftentimes, you’d much rather start off with a skeleton. Luckily, nix already supports templates!

+

You might already be familiar with nix flake init, that drops a “default” flake expression into your current working directory. If you head over to the manpage:

+
nix flake init --help
+

You will read that nix flake init creates a flake using the “default template”. Additionally, you can create a flake from a specific template by passing the -t flag. Where does this default originate from?

+

Flake Registries

+

Quick detour into registries! Registries are a way to alias popular flakes using identifiers:

+
# list a few predefined registries
+$ nix registry list
+. . . 
+global flake:nixpkgs github:NixOS/nixpkgs
+global flake:patchelf github:NixOS/patchelf
+global flake:nix-serve github:edolstra/nix-serve
+global flake:templates github:NixOS/templates
+global flake:nickel github:tweag/nickel
+. . .
+
+# you can do 
+$ nix flake show nickel
+
+# instead of 
+$ nix flake show github:tweag/nickel
+
+# which is short for
+$ nix flake show git+https://github.com/tweag/nickel
+

You might notice a registry called templates aliased to github:NixOS/templates. Take a peek with nix flake show:

+
$ nix flake show templates
+github:NixOS/templates/79f48a7b822f35c068c5e235da2e9fbd154cecee
+├───defaultTemplate: template: A very basic flake
+└───templates
+    ├───bash-hello: template: An over-engineered Hello World in bash
+    ├───c-hello: template: An over-engineered Hello World in C
+    ├───rust-web-server: template: A Rust web server including a NixOS module
+    ├───simpleContainer: template: A NixOS container running apache-httpd
+    └───trivial: template: A very basic flake
+

Aha! There is a flake output called defaultTemplate. This is the template being sourced when you run nix flake init. Astute readers may conclude the following:

+
$ nix flake init
+
+# is equivalent to
+$ nix flake init -t templates#defaultTemplate
+
+# is equivalent to
+$ nix flake init -t github:NixOS/templates#defaultTemplate
+
+# which is short for
+$ nix flake init -t git+https://NixOS/templates#defaultTemplate
+

Similarly, the other templates can be accessed via:

+
$ nix flake init -t templates#c-hello
+$ nix flake init -t templates#simpleContainer
+# I think you get the drift ...
+

Rolling your own templates

+

Alright, so all we need to do is:

+
    +
  • create a flake with a templates output
  • +
  • populate our template directories with content
  • +
  • (optionally) alias our custom templates flake to an identifier using registries, for easier access
  • +
+

Start off by creating a directory to store your templates in (we will be converting this to a registry later):

+
$ mkdir ~/mytemplates
+

A flake that exposes a “template” as its output looks something like this:

+
# inside ~/mytemplates/flake.nix
+
+{
+  description = "Pepper's flake templates";
+
+  outputs = { self, ... }: {
+    templates = {
+      latex-report = {
+        path = ./latex-report-template;
+        description = "A latex whitepaper project";
+      };
+      rust-hello = {
+        path = ./rust-hello-template;
+        description = "Simple Hello World in Rust";
+      };
+    };
+  };
+}
+

The path attribute to each template is what gets copied over when you initialize a flake. Running nix flake init -t .#latex-report will initialize the current directory with the contents of ./latex-report-template (we are yet to populate these directories).

+

The output of nix flake show should be something like:

+
$ nix flake show
+path:/home/np/code/nix-stuff/template-tests?narHash=sha256-{...}
+└───templates
+    ├───latex-report: template: A latex whitepaper project
+    └───rust-hello: template: Simple Hello World in Rust
+

Populate your template directories with content, here are my template directories for example:

+
$ tree mytemplates
+mytemplates/
+├── flake.nix
+├── latex-report-template
+│   ├── flake.nix
+│   ├── makefile
+│   └── src
+│       ├── meta.sty
+│       └── report.tex
+└── rust-hello-template
+    ├── Cargo.toml
+    ├── flake.nix
+    └── src
+        └── main.rs
+

And that’s it! Start using your templates with:

+
$ nix flake init -t ~/mytemplates#rust-hello
+$ tree .
+.
+├── Cargo.toml
+├── flake.nix
+└── src
+    └── main.rs
+

To avoid writing ~/mytemplates each time, simply alias it to a registry:

+
# alias it to `biscuits`
+$ nix registry add biscuits ~/mytemplates
+
+# you will see it listed under `user` registries
+$ nix registry list
+. . .
+user   flake:biscuits path:/home/np/template-tests
+. . .
+
+$ nix flake init -t biscuits#latex-report
+

Extending the official templates

+

I personally, would like the biscuits registry to include not just my homemade templates, but also the templates from NixOS/templates (and maybe a couple of other repositories in the wild):

+
 {
+   description = "Pepper's flake templates";
+ 
++  inputs = {
++    official-templates.url = github:NixOS/templates;
++    other-templates.url = github:some-other/templates;
++  };
+ 
+   outputs = { self, official-templates, other-templates ... }: {
+ 
+     templates = {
+       latex-report = {
+         path = ./latex-report-template;
+         description = "A latex whitepaper project";
+       };
+       rust-hello = {
+         path = ./rust-hello-template;
+         description = "Simple Hello World in Rust, with overloaded Rust toolchain";
+       };
+     }
++    // official-templates.templates
++    // other-templates.templates;
+ 
+   };
+ }
+

Running nix flake show biscuits will now list templates from the biscuits registry as well as the ones from NixOS/templates. Ensure that the names don’t collide though.

+ +
+ +
+ Hi. + +

I'm Akshay, I go by nerd or nerdypepper on the internet.

+

+ I am a compsci undergrad, Rust programmer and an enthusiastic Vimmer. + I write open-source stuff to pass time. + I also design fonts: + scientifica, + curie. +

+

Send me a mail at nerdy@peppe.rs or a message at nerdypepper@irc.rizon.net.

+
+ + Home + / + Posts + / + Novice Nix: Flake Templates + View Raw +
+
+ + -- cgit v1.2.3