52 lines
4.9 KiB
Markdown
52 lines
4.9 KiB
Markdown
# Den Configuration Framework: Core Concepts & Guidelines
|
|
|
|
## Overview
|
|
This NixOS configuration uses `den`, a declarative pipeline framework that shifts away from static module wiring to a system of **Context Transformation** and **Context-Aware Aspects**.
|
|
|
|
**Important Resource:** The `den` repository is vendored at `_ref/den/` and its official documentation can be found at `_ref/den/docs`. Use these resources (via `read_file`, `grep_search`, or `list_directory`) anytime you need to gain a deeper understanding of den's internal behavior or available features.
|
|
|
|
## 1. Core Principles
|
|
* **Aspects (`__functor` pattern):** Configurations are functions of context, not static sets. An aspect (e.g., `{ host, user, ... }: { ... }`) inspects the context it receives and produces configs across domains (`nixos`, `homeManager`, `darwin`) simultaneously.
|
|
* **Context (`den.ctx`):** Attribute sets containing data (like `host` or `user`). Contexts are *named* (e.g., `ctx.hm-host` vs `ctx.host`) to provide guarantees (e.g., `hm-host` proves Home Manager detection passed).
|
|
* **The Pipeline (`into`):** Data flows through a defined pipeline. One context transforms `into` others (e.g., a single `ctx.host` fans out into multiple `ctx.user` contexts).
|
|
* **Providers (`provides`):** Aspects use `provides` to declare sub-aspects or inject configurations across contexts.
|
|
|
|
## 2. Idiomatic Structure
|
|
* **Declaration vs. Configuration:** `den.hosts` and `den.homes` declare *what* exists (hosts, architectures, users). `den.aspects` define *how* they are configured.
|
|
* **Domain Spanning:** A single aspect file handles all relevant domains (e.g., a `git` aspect defines both `nixos.environment.systemPackages` and `homeManager.programs.git`).
|
|
* **Composition:** High-level aspects `include` lower-level aspect functions.
|
|
|
|
## 3. The Context Pipeline
|
|
1. **`ctx.host` `{ host }`:** Resolves the host's primary aspect (`den.aspects.<hostname>`).
|
|
2. **`ctx.default` `{ host }`:** Activates global defaults for the host.
|
|
3. **`ctx.user` `{ host, user }`:** Fans out to create a context for each user on the host. Resolves user aspects (`den.aspects.<username>`). *Crucially, host aspects can configure users here, and user aspects can configure the host.*
|
|
4. **`ctx.default` `{ host, user }`:** Activates global defaults for the user.
|
|
5. **`ctx.hm-host` `{ host }`:** If the host supports Home Manager and has HM users, this safely imports the HM module.
|
|
6. **`ctx.hm-user` `{ host, user }`:** For HM users, their config is forwarded into the host's `home-manager.users.<name>`.
|
|
|
|
## 4. Configuration Placement
|
|
* **Host Aspect (`den.aspects.<hostname>`):** Hardware, networking, system services. Can define default `homeManager` settings for all its users.
|
|
* **User Aspect (`den.aspects.<username>`):** Dotfiles, user packages, shell preferences. Can define required `nixos` settings for every host the user is on.
|
|
* **Global Defaults (`den.ctx.default`):** Universal settings (e.g., `stateVersion`, `den._.define-user`). **Note:** Prefer using more specific contexts (like `den.ctx.host` or `den.ctx.user`) over `den.ctx.default` whenever possible. Always write it as `den.ctx.default` rather than `den.default` to make it clear it is a context.
|
|
* **Feature Aspects:** Granular aspects included conditionally via `<den/lib> take.exactly` (or `den.lib.take.exactly`).
|
|
|
|
## 5. Common Pitfalls
|
|
* **The "Lax Context" Duplicate Config Bug:** A function like `({ host, ... }: { ... })` in `den.default.includes` runs at both the `ctx.host` and `ctx.user` stages, causing duplicate config errors.
|
|
* **Fix:** Use `<den/lib> take.exactly ({ host }: ...)` to run only at the host stage.
|
|
* **Missing `parametric` Wrapper:** Custom aspect trees (not auto-created by Den) that fail to forward context to their includes will throw `error: function 'anonymous lambda' called without required argument`.
|
|
* **Fix:** Wrap the custom aspect in `<den/lib> parametric`.
|
|
* **Home Manager Silent Failures:** If the detection gate fails (wrong OS, missing `"homeManager"` class on user, or missing `inputs.home-manager`), HM configs won't generate.
|
|
|
|
## 6. Essential Library Functions (`den.lib.*` & Batteries)
|
|
* `take.exactly`: Executes only if context matches arguments exactly.
|
|
* `take.atLeast`: Executes if context has at least the requested arguments.
|
|
* `parametric`: Wrapper to make an aspect forward context to its `includes`.
|
|
* `_.forward`: Translates config from one domain (e.g., custom class) to another.
|
|
* **Batteries (`den._.*`):** Built-in parametric aspects (e.g., `define-user`, `user-shell`, `tty-autologin`, `unfree`).
|
|
|
|
## 7. Useful Commands
|
|
* **`nix-search-tv`:** Use this command to look up docs for relevant options.
|
|
* Examples: `nix-search-tv preview "home-manager/ home.packages"`, `nix-search-tv preview "nixos/ environment.systemPackages"`.
|
|
* Prefix with `nixpkgs/` for nixpkgs docs.
|
|
* Use `nix-search-tv print` to print all available options and packages (filter output to avoid bloating context).
|