docs(nix): record flake conventions
This commit is contained in:
@@ -4,13 +4,16 @@ One flake builds every machine I own.
|
|||||||
|
|
||||||
## Repository Conventions
|
## Repository Conventions
|
||||||
|
|
||||||
- Follow `docs/technical-writing.md` for comments, user-facing descriptions, commit prose, pull-request prose, and Markdown documentation.
|
- Use `docs/technical-writing.md` and `docs/dictionary.md` while authoring any file.
|
||||||
|
Apply them to comments, user-facing descriptions, commit prose, pull-request prose, and Markdown documentation.
|
||||||
- Comments posted to the forge under the operator's account must end with `— Pi`.
|
- Comments posted to the forge under the operator's account must end with `— Pi`.
|
||||||
The sign-off identifies the agent as the author instead of the operator.
|
The sign-off identifies the agent as the author instead of the operator.
|
||||||
- Commit messages follow Conventional Commits, defined in `docs/conventional-commits.md`.
|
- Commit messages follow Conventional Commits, defined in `docs/conventional-commits.md`.
|
||||||
Use a scope for the changed module or host, such as `fish`, `nvim`, or `neogaia`.
|
Use a scope for the changed module or host, such as `fish`, `nvim`, or `neogaia`.
|
||||||
- Keep commit messages about the Git history, not the forge workflow.
|
- Keep commit messages about the Git history, not the forge workflow.
|
||||||
Do not reference issue or pull-request numbers unless the commit itself requires a stable external reference.
|
Do not reference issue or pull-request numbers unless the commit itself requires a stable external reference.
|
||||||
|
- During pull-request development, add follow-up commits instead of amending existing commits.
|
||||||
|
Preserve review history until the pull request is ready to merge.
|
||||||
- Use `gitea-axi` for Gitea issues, pull requests, labels, reviews, comments, and milestones.
|
- Use `gitea-axi` for Gitea issues, pull requests, labels, reviews, comments, and milestones.
|
||||||
It resolves this repository from the `origin` remote inside the checkout.
|
It resolves this repository from the `origin` remote inside the checkout.
|
||||||
|
|
||||||
|
|||||||
@@ -45,11 +45,15 @@ Use the simplest accurate word when a term is not listed.
|
|||||||
| operator | Agent tooling | The human driving the development process. Use when distinguishing the human from the agent acting on their behalf. |
|
| operator | Agent tooling | The human driving the development process. Use when distinguishing the human from the agent acting on their behalf. |
|
||||||
| guest | dotfiles | A systemd-nspawn container managed by this flake. Use for configured containers under `guests/`. |
|
| guest | dotfiles | A systemd-nspawn container managed by this flake. Use for configured containers under `guests/`. |
|
||||||
| host | dotfiles | A machine with a NixOS configuration built by this flake. |
|
| host | dotfiles | A machine with a NixOS configuration built by this flake. |
|
||||||
| module | dotfiles | In this repository, a self-contained configuration under `modules/`, usually scoped to one program, service, or subsystem. Use `Nix module` for the language-level module-system concept. |
|
| module | dotfiles | In this repository, a self-contained configuration under `modules/`. Use for one program, service, or subsystem. |
|
||||||
| registry | dotfiles | A typed configuration namespace whose entries can be collected across hosts and reused by other configuration. |
|
| registry | dotfiles | A typed configuration namespace whose entries can be collected across hosts and reused by other configuration. |
|
||||||
| Conventional Commits | Git | A commit-message format defined in `docs/conventional-commits.md`. |
|
| Conventional Commits | Git | A commit-message format defined in `docs/conventional-commits.md`. |
|
||||||
| forge | Git | A web service that hosts Git repositories, pull requests, issues, and code review comments. Use when the exact provider does not matter. |
|
| forge | Git | A web service that hosts Git repositories, pull requests, issues, and code review comments. Use when the exact provider does not matter. |
|
||||||
| flake | Nix | A Nix project with pinned inputs and declared outputs. Use for the repository-level build unit defined by `flake.nix`. |
|
| flake | Nix | A Nix project with pinned inputs and declared outputs. Use for the repository-level build unit defined by `flake.nix`. |
|
||||||
| Nix module | Nix | A Nix language unit that declares or sets options through the Nix module system. |
|
| assembly file | Nix | A Nix file under `flake/` that constructs flake outputs or arguments passed to NixOS modules. |
|
||||||
|
| assembly function | Nix | A project function in `flake/` that creates modules, systems, or output values. |
|
||||||
|
| library file | Nix | A Nix file that defines reusable project functions instead of a NixOS module or flake output. |
|
||||||
|
| library function | Nix | A pure project function exposed under `util`. |
|
||||||
|
| NixOS module | Nix | A Nix file evaluated by `nixosSystem` for a NixOS configuration. |
|
||||||
| overlay | Nix | A function that modifies a Nix package set by adding or replacing packages. |
|
| overlay | Nix | A function that modifies a Nix package set by adding or replacing packages. |
|
||||||
| workspace | Window management | A named or numbered group of windows in a graphical session. Some desktop environments call this a virtual desktop. |
|
| workspace | Window management | A named or numbered group of windows in a graphical session. Some desktop environments call this a virtual desktop. |
|
||||||
|
|||||||
270
docs/nix.md
Normal file
270
docs/nix.md
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
# Nix Conventions
|
||||||
|
|
||||||
|
This document records local Nix style and design conventions.
|
||||||
|
Use these conventions when changing this flake.
|
||||||
|
Read this document with `docs/dictionary.md`.
|
||||||
|
|
||||||
|
## Names
|
||||||
|
|
||||||
|
### Reserve `lib` for `nixpkgs.lib`
|
||||||
|
|
||||||
|
Use `lib` only for the base `nixpkgs.lib` value.
|
||||||
|
Do not use `lib` for project functions.
|
||||||
|
Use `util` for library functions passed through module arguments.
|
||||||
|
Use `flake.mk<Name>` for assembly functions used by flake outputs.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
specialArgs = {
|
||||||
|
lib = util;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
specialArgs = {
|
||||||
|
inherit util;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Then call library functions through `util` inside modules:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
util,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
networking.networkmanager.unmanaged = [ "interface-name:${util.bridgeName 10}" ];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Name project function namespaces by role
|
||||||
|
|
||||||
|
Put pure project functions under `util`.
|
||||||
|
Put functions that create systems or output values under `flake`.
|
||||||
|
This keeps data-only functions separate from functions that carry flake context.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
util.mkHosts { root = self + "/hosts"; }
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
flake.mkHosts { root = self + "/hosts"; }
|
||||||
|
```
|
||||||
|
|
||||||
|
## File Placement
|
||||||
|
|
||||||
|
### Put files in the directory that owns their role
|
||||||
|
|
||||||
|
Choose the file location before writing a Nix file.
|
||||||
|
Put assembly files under `flake/`.
|
||||||
|
Put library files under `lib/`.
|
||||||
|
Put modules under `modules/`.
|
||||||
|
Put host configurations under `hosts/<name>/`.
|
||||||
|
Put host-side guest wiring under `guests/`.
|
||||||
|
Put registry definitions under `registry/`.
|
||||||
|
Keep `flake.nix` focused on inputs and output wiring.
|
||||||
|
Do not add root-level Nix files other than `flake.nix`.
|
||||||
|
|
||||||
|
A module is self-contained configuration under `modules/`.
|
||||||
|
A module configures one program, service, or subsystem.
|
||||||
|
Files under `hosts/`, `guests/`, and `modules/` return NixOS modules.
|
||||||
|
|
||||||
|
### Use `default.nix` for module directories with support files
|
||||||
|
|
||||||
|
Use `default.nix` as the primary module when a module directory owns support files.
|
||||||
|
Keep sibling files for data or code read by that primary module.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```text
|
||||||
|
modules/shell/fish/fish.nix
|
||||||
|
modules/shell/fish/config.fish
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
modules/shell/fish/default.nix
|
||||||
|
modules/shell/fish/config.fish
|
||||||
|
```
|
||||||
|
|
||||||
|
### Use non-module `default.nix` files only for directory assembly
|
||||||
|
|
||||||
|
Outside `modules/`, use `default.nix` to connect files in its directory.
|
||||||
|
Do not define primary assembly functions in `default.nix`.
|
||||||
|
Put primary assembly functions in named files.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```text
|
||||||
|
flake/default.nix # defines mkHost
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```text
|
||||||
|
flake/default.nix # imports ./host.nix
|
||||||
|
flake/host.nix # defines mkHosts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keep assembly files focused on one concept
|
||||||
|
|
||||||
|
Give each assembly file under `flake/` one top-level concept.
|
||||||
|
Keep helper functions private to that file when no other file needs them.
|
||||||
|
Export the constructor for the concept when another assembly file needs it.
|
||||||
|
Name that constructor `mk<Concept>`.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inherit collectNixFiles mkHost mkHosts;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inherit mkHosts;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Function Arguments
|
||||||
|
|
||||||
|
### Use closed interfaces for assembly files and library files
|
||||||
|
|
||||||
|
Use exact function argument patterns for assembly files and library files.
|
||||||
|
The caller owns the argument set for these files.
|
||||||
|
The imported file names each accepted attribute.
|
||||||
|
The imported file rejects stale or accidental extra attributes.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
self,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
lib,
|
||||||
|
self,
|
||||||
|
}:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pass function arguments explicitly
|
||||||
|
|
||||||
|
Pass only the values an assembly file or library file needs.
|
||||||
|
Bind `lib` to the base `nixpkgs.lib` value at the call site.
|
||||||
|
Use `inherit` only for values that keep the same name.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
import ./flake inputs
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
in
|
||||||
|
import ./flake { inherit lib inputs self; }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Keep NixOS module interfaces open
|
||||||
|
|
||||||
|
Files under `hosts/`, `guests/`, and `modules/` return NixOS modules.
|
||||||
|
`nixosSystem` owns their argument shape.
|
||||||
|
Name each argument the module uses.
|
||||||
|
Keep `...` so the module accepts standard arguments and special arguments.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
registry,
|
||||||
|
}:
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
registry,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
```
|
||||||
|
|
||||||
|
## `let` Bindings
|
||||||
|
|
||||||
|
### Use role-specific binding names
|
||||||
|
|
||||||
|
A `let` binding name must explain the value's role in the expression.
|
||||||
|
Avoid names that describe only the value's type.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
names = lib.attrNames hosts;
|
||||||
|
in
|
||||||
|
lib.genAttrs names mkHost
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
hostNames = lib.attrNames hosts;
|
||||||
|
in
|
||||||
|
lib.genAttrs hostNames mkHost
|
||||||
|
```
|
||||||
|
|
||||||
|
## Standard Library Calls
|
||||||
|
|
||||||
|
### Qualify standard library calls in flake assembly
|
||||||
|
|
||||||
|
Use qualified standard library calls inside assembly files.
|
||||||
|
Use `lib.mapAttrs` instead of inheriting `mapAttrs` from `lib`.
|
||||||
|
This keeps the source of each function visible.
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
inherit (lib) mapAttrs;
|
||||||
|
in
|
||||||
|
mapAttrs f attrs
|
||||||
|
```
|
||||||
|
|
||||||
|
Use:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
lib.mapAttrs f attrs
|
||||||
|
```
|
||||||
|
|
||||||
Reference in New Issue
Block a user