-
-
Notifications
You must be signed in to change notification settings - Fork 35
Permalink
Choose a base ref
{{ refName }}
default
Choose a head ref
{{ refName }}
default
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
base repository: denful/den
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.8.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
...
head repository: denful/den
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.9.0
Could not load branches
Nothing to show
Loading
Could not load tags
Nothing to show
{{ refName }}
default
Loading
- 11 commits
- 148 files changed
- 2 contributors
Commits on Feb 13, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 675524f - Browse repository at this point
Copy the full SHA 675524fView commit details
Commits on Feb 14, 2026
-
Configuration menu - View commit details
-
Copy full SHA for f9563fa - Browse repository at this point
Copy the full SHA f9563faView commit details
Commits on Feb 15, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 36b571d - Browse repository at this point
Copy the full SHA 36b571dView commit details -
The functionality of `homeManager` itself was generalized into `den.provides.forward`, this will pave the road for easily having `hjem`, `nix-maid` and most importantly, allow the user to have custom defined forward classes. See discussion at #160
Configuration menu - View commit details
-
Copy full SHA for 933a84f - Browse repository at this point
Copy the full SHA 933a84fView commit details
Commits on Feb 17, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 2789943 - Browse repository at this point
Copy the full SHA 2789943View commit details -
Configuration menu - View commit details
-
Copy full SHA for 5478f8e - Browse repository at this point
Copy the full SHA 5478f8eView commit details -
Fix usage of obsolete options and remove passthru requirement (#169) (#…
…171) Changes: - Remove need to define `passthru` attribute for hosts - Remove usage of obsolete nixpkgs options - Add descriptive error message if `flake`'s attributes are defined multiple times
Configuration menu - View commit details
-
Copy full SHA for f8cb8c6 - Browse repository at this point
Copy the full SHA f8cb8c6View commit details
Commits on Feb 20, 2026
-
den.ctx. Den declarative context definitions. (#175)
Related #174 # Declarative Context Definitions This introduces [`den.ctx`](#175), a declarative system for defining how context (data) is transformed and which aspects are applied at every stage of the configuration pipeline. ## The Problem Before this release, `den.default` served two purposes: - A place to define global or generic includes for `host`, `user`, and `home` entities. - The backbone of context propagation — moving data from `{ host }` to `{ host, user }` to `{ host, user }` in the HM pipeline, etc. As a consequence, `den.default.includes` was abused by many of us, including Den itself, because it was [where context transformation happened](https://github.com/vic/den/blob/f8cb8c618e1680e99c165d2bf826600170abb5a2/modules/aspects/dependencies.nix#L28) [\[2\]](https://github.com/vic/den/blob/f8cb8c618e1680e99c165d2bf826600170abb5a2/modules/aspects/provides/home-manager/hm-dependencies.nix#L31). This "dependency system" — parametric aspects installed unconditionally at `den.default.includes` — was hard to reason about, hard to document, and hard for people to understand. The symptoms were duplicate configuration values, caused by lax parametric functions matching too many pipeline stages. ## What den.ctx Provides - **Keep `den.default` for what it's good at**: global settings. You can still use `den.default.includes`, but there are better alternatives now. - **Move the dependency system out of `den.default.includes`**: those parametric aspects were not individually testable, and you couldn't change how data flows. They were Den's hardcoded backbone. - **Declarative data stages**: context transformations are now explicit. Given a `host`, you declare how to enumerate users, detect HM support, etc. - **Named contexts**: previously we identified contexts only by their `attrNames` — `{ host }`, `{ host, user }`. Now they have names: `ctx.host`, `ctx.hm-host`. Names allow different contexts with the same structural shape but different semantic guarantees. - **Extensible context flows**: one core principle of Den is not getting in your way. You can create alternative flows, or use Den purely as a library. ## Named Contexts: Transform, Don't Validate Named contexts carry semantic meaning beyond their structure. `ctx.host { host }` and `ctx.hm-host { host }` hold the same data, but `hm-host` **guarantees** that home-manager support was validated: - `inputs.home-manager` exists (or the host has a custom `hm-module`) - The host has at least one user with `class = "homeManager"` You cannot obtain an `hm-host` context unless these conditions hold. This follows the transform-don't-validate principle. ## How a Context Type Works A context type has four components: `desc`, `conf`, `includes`, and `into`. ```nix den.ctx.foo.desc = "The foo context requires { foo } data."; den.ctx.foo.conf = { foo }: my-aspects.${foo.name}; ``` When `ctx.foo` is applied — it works like a function taking `{ foo }` — it locates the responsible aspect via `conf`. For example, `ctx.foo { foo.name = "bar"; }` uses `my-aspects.bar`. The aspect's owned config, static includes, and parametric includes matching `{ foo }` all contribute to whatever `ctx.foo` is being used to configure. Context types are independent of NixOS. Den can be used as a library for network topologies, declarative cloud infrastructure, or anything describable as data transformations. ## How a NixOS Configuration Is Built The initial data for `nixosConfigurations.igloo` is the host itself: ```nix # Nothing NixOS-specific yet — just a graph of dependencies. aspect = den.ctx.host { host = den.hosts.x86_64-linux.igloo; }; ``` The result of `ctxApply` is a new aspect that includes `den.aspects.igloo` plus the entire transformation chain — user enumeration, HM detection, defaults. ```nix # This is where things enter the NixOS domain. nixosModule = aspect.resolve { class = "nixos"; }; nixosConfigurations.igloo = lib.nixosSystem { modules = [ nixosModule ]; }; ``` These two steps can be adapted for any class, for anything Nix-configurable. ## Context Propagation Context transformation is declarative. If your data fans out to other contexts, you specify the transformations using `.into`: ```nix den.ctx.foo.conf = { foo }: ...; den.ctx.moo.conf = { moo }: ...; den.ctx.foo.into.moo = { foo }: lib.singleton { moo = deriveMoo foo; }; ``` All `<source>.into.<target>` transformations are taken into account by `ctxApply`. ### Why Lists? Transformations have the type `source → [ target ]`. This enables: - **Fan-out**: one host produces many `{ host, user }` contexts (`map`) - **Conditional propagation**: zero or one contexts (`lib.optional`) - **Pass-through**: identity transformation (`lib.singleton`) For example, HM detection uses conditional propagation: ```nix den.ctx.host.into.hm-host = { host }: lib.optional (isHmSupported host) { inherit host; }; ``` Same data, but the named context guarantees validation passed. ## Contexts as Aspect Cutting-Points Contexts are aspect-like themselves. They have owned configs and `.includes`: ```nix # Owned config — only for validated HM hosts: den.ctx.hm-host.nixos.home-manager.useGlobalPkgs = true; # Scoped includes — only for validated HM hosts: den.ctx.hm-host.includes = [ ({ host, ... }: { nixos.home-manager.backupFileExtension = "bak"; }) ]; ``` This is like `den.default.includes` **but scoped** — it only activates for hosts with validated home-manager support. ## Extending the Context Flow You can add new transformations to any existing context type: ```nix den.ctx.hm-host.into.foo = { host }: [ { foo = host.name; } ]; den.ctx.foo.conf = { foo }: ...; den.ctx.foo.includes = [ ({ foo, ... }: ...) ]; ``` The module system merges these definitions. You can extend the pipeline without modifying any built-in file. ## Custom Context Flows Each host has a `mainModule` option that defaults to: ```nix (den.ctx.host { host }).resolve { class = "nixos"; } ``` You can override `mainModule` to use a completely alternative context flow, independent of `ctx.host`. Custom flows can be designed and tested in isolation — Den's CI uses a `funny.names` class that has nothing to do with NixOS to verify context mechanics independently. ## What Happened to den.default? `den.default` stays and is still useful for truly global settings. The issue was abusing `den.default.includes` as the context propagation backbone. ### Internal Changes Previously, all host, user, and home aspects had: ```nix includes = [ den.default ] ``` Now they **no longer include `den.default` directly**. Including `den.default` explicitly is discouraged. ### How Defaults Are Applied Now Each context type transforms into `default`: ```nix den.ctx.host.into.default = lib.singleton; # passes { host } den.ctx.user.into.default = lib.singleton; # passes { host, user } den.ctx.home.into.default = lib.singleton; # passes { home } ``` `den.default` is now an alias for `den.ctx.default`. The data that flows into `den.default.includes` comes from these declarative transformations, not from direct aspect inclusion. ### Best Practices | Instead of | Use | |-----------|-----| | `den.default.includes = [ hostFunc ]` | `den.ctx.host.includes = [ hostFunc ]` | | `den.default.includes = [ hmFunc ]` | `den.ctx.hm-host.includes = [ hmFunc ]` | | `den.default.nixos.x = 1` | `den.ctx.host.nixos.x = 1` | `den.default` remains the right place for values that genuinely apply everywhere — like `stateVersion`. Use context-specific includes for anything that belongs to a particular pipeline stage.
Configuration menu - View commit details
-
Copy full SHA for def3ecf - Browse repository at this point
Copy the full SHA def3ecfView commit details -
Configuration menu - View commit details
-
Copy full SHA for 1691a68 - Browse repository at this point
Copy the full SHA 1691a68View commit details
Commits on Mar 29, 2026
-
Configuration menu - View commit details
-
Copy full SHA for 1fa75bf - Browse repository at this point
Copy the full SHA 1fa75bfView commit details
Commits on Mar 30, 2026
-
Configuration menu - View commit details
-
Copy full SHA for fec76cd - Browse repository at this point
Copy the full SHA fec76cdView commit details
Loading
This comparison is taking too long to generate.
Unfortunately it looks like we can’t render this comparison for you right now. It might be too big, or there might be something weird with your repository.
You can try running this command locally to see the comparison on your machine:
git diff v0.8.0...v0.9.0