Initial commit
This commit is contained in:
commit
cfcc57a8bd
353 changed files with 18756 additions and 0 deletions
13
flake/den/checkmate.nix
Normal file
13
flake/den/checkmate.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
imports =
|
||||
let
|
||||
files = builtins.readDir ./checkmate/tests;
|
||||
names = builtins.attrNames files;
|
||||
nixes = builtins.filter (lib.hasSuffix ".nix") names;
|
||||
tests = map (file: "${./checkmate/tests}/${file}") nixes;
|
||||
in
|
||||
tests;
|
||||
|
||||
perSystem.treefmt.settings.global.excludes = [ ".github/*/*.md" ];
|
||||
}
|
||||
1
flake/den/checkmate/.gitignore
vendored
Normal file
1
flake/den/checkmate/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
flake.lock
|
||||
7
flake/den/checkmate/flake.nix
Normal file
7
flake/den/checkmate/flake.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
inputs.target.url = "path:..";
|
||||
inputs.checkmate.url = "github:vic/checkmate";
|
||||
inputs.checkmate.inputs.target.follows = "target";
|
||||
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
outputs = inputs: inputs.checkmate.lib.newFlake;
|
||||
}
|
||||
198
flake/den/checkmate/tests/aspect-functor.nix
Normal file
198
flake/den/checkmate/tests/aspect-functor.nix
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
{
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
den.lib = inputs.target.lib { inherit lib inputs config; };
|
||||
|
||||
inherit (den.lib) parametric canTake;
|
||||
|
||||
aspect-example = {
|
||||
__functor = parametric.atLeast;
|
||||
nixos.foo = 99;
|
||||
includes = [
|
||||
{ nixos.static = 100; }
|
||||
(
|
||||
{ host, ... }:
|
||||
{
|
||||
nixos.host = host;
|
||||
}
|
||||
)
|
||||
(
|
||||
{ host, user, ... }:
|
||||
{
|
||||
nixos.host-user = [
|
||||
host
|
||||
user
|
||||
];
|
||||
}
|
||||
)
|
||||
(
|
||||
{
|
||||
OS,
|
||||
user,
|
||||
host,
|
||||
...
|
||||
}:
|
||||
{
|
||||
nixos.os-user-host = [
|
||||
OS
|
||||
user
|
||||
host
|
||||
];
|
||||
}
|
||||
)
|
||||
(
|
||||
{ user, ... }:
|
||||
{
|
||||
nixos.user = user;
|
||||
}
|
||||
)
|
||||
(
|
||||
{ user, ... }@ctx:
|
||||
if canTake.exactly ctx ({ user }: user) then
|
||||
{
|
||||
nixos.user-only = user;
|
||||
}
|
||||
else
|
||||
{ nixos.user-only = false; }
|
||||
)
|
||||
(
|
||||
{ home, ... }:
|
||||
{
|
||||
nixos.home = home;
|
||||
}
|
||||
)
|
||||
(_any: {
|
||||
nixos.any = 10;
|
||||
})
|
||||
];
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with empty attrs" = {
|
||||
expr = (aspect-example { });
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with host only" = {
|
||||
expr = (
|
||||
aspect-example {
|
||||
host = 2;
|
||||
}
|
||||
);
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.host = 2; } # host
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with home only" = {
|
||||
expr = (
|
||||
aspect-example {
|
||||
home = 2;
|
||||
}
|
||||
);
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.home = 2; } # home
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with home and unknown" = {
|
||||
expr = (
|
||||
aspect-example {
|
||||
home = 2;
|
||||
unknown = 1;
|
||||
}
|
||||
);
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.home = 2; }
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with user only" = {
|
||||
expr = (
|
||||
aspect-example {
|
||||
user = 2;
|
||||
}
|
||||
);
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.user = 2; } # user
|
||||
{ nixos.user-only = 2; } # user-only
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with user and host" = {
|
||||
expr = (
|
||||
aspect-example {
|
||||
user = 2;
|
||||
host = 1;
|
||||
}
|
||||
);
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.host = 1; }
|
||||
{
|
||||
nixos.host-user = [
|
||||
1
|
||||
2
|
||||
];
|
||||
}
|
||||
{ nixos.user = 2; }
|
||||
{ nixos.user-only = false; }
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
flake.tests."test functor applied with host/user/OS" = {
|
||||
expr = (
|
||||
aspect-example {
|
||||
OS = 0;
|
||||
user = 2;
|
||||
host = 1;
|
||||
}
|
||||
);
|
||||
expected = {
|
||||
includes = [
|
||||
{ nixos.host = 1; }
|
||||
{
|
||||
nixos.host-user = [
|
||||
1
|
||||
2
|
||||
];
|
||||
}
|
||||
{
|
||||
nixos.os-user-host = [
|
||||
0
|
||||
2
|
||||
1
|
||||
];
|
||||
}
|
||||
{ nixos.user = 2; }
|
||||
{ nixos.user-only = false; }
|
||||
{ nixos.any = 10; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
inherit flake;
|
||||
}
|
||||
40
flake/den/checkmate/tests/den-brackets.nix
Normal file
40
flake/den/checkmate/tests/den-brackets.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
{ ... }@top:
|
||||
let
|
||||
lib = top.inputs.nixpkgs.lib;
|
||||
|
||||
# deadnix: skip
|
||||
__findFile =
|
||||
if true then
|
||||
import "${top.inputs.target}/nix/den-brackets.nix" { inherit lib config inputs; }
|
||||
else
|
||||
__findFile;
|
||||
|
||||
inputs = {
|
||||
|
||||
};
|
||||
|
||||
config.den = {
|
||||
default.foo = 1;
|
||||
|
||||
provides.foo.a = 2;
|
||||
provides.foo.provides.bar.b = 3;
|
||||
provides.foo.provides.c = 4;
|
||||
|
||||
d = 5;
|
||||
|
||||
aspects.foo.a = 6;
|
||||
aspects.foo.provides.bar.b = 7;
|
||||
aspects.foo.provides.c = 8;
|
||||
|
||||
};
|
||||
in
|
||||
{
|
||||
flake.tests."<den.default>" =
|
||||
let
|
||||
expr = <den.default>;
|
||||
expected.foo = 2;
|
||||
in
|
||||
{
|
||||
inherit expr expected;
|
||||
};
|
||||
}
|
||||
85
flake/den/checkmate/tests/function_can_take.nix
Normal file
85
flake/den/checkmate/tests/function_can_take.nix
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
{
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
den.lib = inputs.target.lib { inherit inputs lib config; };
|
||||
takes = den.lib.canTake;
|
||||
|
||||
flake.tests."test exactly fails" = {
|
||||
expr = takes.exactly {
|
||||
a = 1;
|
||||
b = 2;
|
||||
} ({ a }: a);
|
||||
expected = false;
|
||||
};
|
||||
|
||||
flake.tests."test exactly succeeds" = {
|
||||
expr = takes.exactly { a = 1; } ({ a }: a);
|
||||
expected = true;
|
||||
};
|
||||
|
||||
flake.tests."test function with no named arguments can take anything" = {
|
||||
expr = takes { } (x: x);
|
||||
expected = true;
|
||||
};
|
||||
|
||||
flake.tests."test function called with non attrs" = {
|
||||
expr = takes 22 ({ host }: [ host ]);
|
||||
expected = false;
|
||||
};
|
||||
|
||||
flake.tests."test function missing required attr" = {
|
||||
expr = takes { } ({ host }: [ host ]);
|
||||
expected = false;
|
||||
};
|
||||
|
||||
flake.tests."test function satisfied required attr" = {
|
||||
expr = takes {
|
||||
host = 1;
|
||||
} ({ host, ... }: [ host ]);
|
||||
expected = true;
|
||||
};
|
||||
|
||||
flake.tests."test function missing second required attr" = {
|
||||
expr =
|
||||
takes
|
||||
{
|
||||
host = 1;
|
||||
}
|
||||
(
|
||||
{ host, user }:
|
||||
[
|
||||
host
|
||||
user
|
||||
]
|
||||
);
|
||||
expected = false;
|
||||
};
|
||||
|
||||
flake.tests."test function optional second attr" = {
|
||||
expr =
|
||||
takes
|
||||
{
|
||||
host = 1;
|
||||
foo = 9;
|
||||
}
|
||||
(
|
||||
{
|
||||
host,
|
||||
user ? 0,
|
||||
}:
|
||||
[
|
||||
host
|
||||
user
|
||||
]
|
||||
);
|
||||
expected = true;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
inherit flake;
|
||||
}
|
||||
16
flake/den/flake.nix
Normal file
16
flake/den/flake.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
outputs = _: {
|
||||
flakeModule = ./nix/flakeModule.nix;
|
||||
templates = {
|
||||
default.path = ./templates/default;
|
||||
default.description = "Minimal configuration";
|
||||
examples.path = ./templates/examples;
|
||||
examples.description = "API examples and CI";
|
||||
bogus.path = ./templates/bogus;
|
||||
bogus.description = "For bug reproduction";
|
||||
};
|
||||
packages = import ./nix/template-packages.nix;
|
||||
namespace = import ./nix/namespace.nix;
|
||||
lib = import ./nix/lib.nix;
|
||||
};
|
||||
}
|
||||
205
flake/den/modules/_types.nix
Normal file
205
flake/den/modules/_types.nix
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
{
|
||||
inputs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config) den;
|
||||
|
||||
hostsOption = lib.mkOption {
|
||||
description = "den hosts definition";
|
||||
default = { };
|
||||
type = lib.types.attrsOf systemType;
|
||||
};
|
||||
|
||||
systemType = lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
freeformType = lib.types.attrsOf (hostType name);
|
||||
}
|
||||
);
|
||||
|
||||
hostType =
|
||||
system:
|
||||
lib.types.submodule (
|
||||
{ name, config, ... }:
|
||||
{
|
||||
freeformType = lib.types.attrsOf lib.types.anything;
|
||||
options = {
|
||||
name = strOpt "host configuration name" name;
|
||||
hostName = strOpt "Network hostname" config.name;
|
||||
system = strOpt "platform system" system;
|
||||
class = strOpt "os-configuration nix class for host" (
|
||||
if lib.hasSuffix "darwin" config.system then "darwin" else "nixos"
|
||||
);
|
||||
aspect = strOpt "main aspect name of <class>" config.name;
|
||||
description = strOpt "host description" "${config.class}.${config.hostName}@${config.system}";
|
||||
users = lib.mkOption {
|
||||
description = "user accounts";
|
||||
default = { };
|
||||
type = lib.types.attrsOf userType;
|
||||
};
|
||||
instantiate = lib.mkOption {
|
||||
description = ''
|
||||
Function used to instantiate the OS configuration.
|
||||
|
||||
Depending on class, defaults to:
|
||||
`darwin`: inputs.darwin.lib.darwinSystem
|
||||
`nixos`: inputs.nixpkgs.lib.nixosSystem
|
||||
`systemManager`: inputs.system-manager.lib.makeSystemConfig
|
||||
|
||||
Set explicitly if you need:
|
||||
|
||||
- a custom input name, eg, nixos-unstable.
|
||||
- adding specialArgs when absolutely required.
|
||||
'';
|
||||
example = lib.literalExpression "inputs.nixpkgs.lib.nixosSystem";
|
||||
type = lib.types.unspecified;
|
||||
default =
|
||||
{
|
||||
nixos = inputs.nixpkgs.lib.nixosSystem;
|
||||
darwin = inputs.darwin.lib.darwinSystem;
|
||||
systemManager = inputs.system-manager.lib.makeSystemConfig;
|
||||
}
|
||||
.${config.class};
|
||||
};
|
||||
intoAttr = lib.mkOption {
|
||||
description = ''
|
||||
Flake attr where to add the named result of this configuration.
|
||||
flake.<intoAttr>.<name>
|
||||
|
||||
Depending on class, defaults to:
|
||||
`darwin`: darwinConfigurations
|
||||
`nixos`: nixosConfigurations
|
||||
`systemManager`: systemConfigs
|
||||
'';
|
||||
example = lib.literalExpression ''"nixosConfigurations"'';
|
||||
type = lib.types.str;
|
||||
default =
|
||||
{
|
||||
nixos = "nixosConfigurations";
|
||||
darwin = "darwinConfigurations";
|
||||
systemManager = "systemConfigs";
|
||||
}
|
||||
.${config.class};
|
||||
};
|
||||
mainModule = lib.mkOption {
|
||||
internal = true;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
type = lib.types.deferredModule;
|
||||
default = mainModule config "OS" "host";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
userType = lib.types.submodule (
|
||||
{ name, config, ... }:
|
||||
{
|
||||
freeformType = lib.types.attrsOf lib.types.anything;
|
||||
options = {
|
||||
name = strOpt "user configuration name" name;
|
||||
userName = strOpt "user account name" config.name;
|
||||
class = strOpt "home management nix class" "homeManager";
|
||||
aspect = strOpt "main aspect name" config.name;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
strOpt =
|
||||
description: default:
|
||||
lib.mkOption {
|
||||
type = lib.types.str;
|
||||
inherit description default;
|
||||
};
|
||||
|
||||
homesOption = lib.mkOption {
|
||||
description = "den standalone home-manager configurations";
|
||||
default = { };
|
||||
type = lib.types.attrsOf homeSystemType;
|
||||
};
|
||||
|
||||
homeSystemType = lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
freeformType = lib.types.attrsOf (homeType name);
|
||||
}
|
||||
);
|
||||
|
||||
homeType =
|
||||
system:
|
||||
lib.types.submodule (
|
||||
{ name, config, ... }:
|
||||
{
|
||||
freeformType = lib.types.attrsOf lib.types.anything;
|
||||
options = {
|
||||
name = strOpt "home configuration name" name;
|
||||
userName = strOpt "user account name" config.name;
|
||||
system = strOpt "platform system" system;
|
||||
class = strOpt "home management nix class" "homeManager";
|
||||
aspect = strOpt "main aspect name" config.name;
|
||||
description = strOpt "home description" "home.${config.userName}@${config.system}";
|
||||
instantiate = lib.mkOption {
|
||||
description = ''
|
||||
Function used to instantiate the home configuration.
|
||||
|
||||
Depending on class, defaults to:
|
||||
`homeManager`: inputs.home-manager.lib.homeManagerConfiguration
|
||||
|
||||
Set explicitly if you need:
|
||||
|
||||
- a custom input name, eg, home-manager-unstable.
|
||||
- adding extraSpecialArgs when absolutely required.
|
||||
'';
|
||||
example = lib.literalExpression "inputs.home-manager.lib.homeManagerConfiguration";
|
||||
type = lib.types.unspecified;
|
||||
default =
|
||||
{
|
||||
homeManager = inputs.home-manager.lib.homeManagerConfiguration;
|
||||
}
|
||||
.${config.class};
|
||||
};
|
||||
intoAttr = lib.mkOption {
|
||||
description = ''
|
||||
Flake attr where to add the named result of this configuration.
|
||||
flake.<intoAttr>.<name>
|
||||
|
||||
Depending on class, defaults to:
|
||||
`homeManager`: homeConfigurations
|
||||
'';
|
||||
example = lib.literalExpression ''"homeConfigurations"'';
|
||||
type = lib.types.str;
|
||||
default =
|
||||
{
|
||||
homeManager = "homeConfigurations";
|
||||
}
|
||||
.${config.class};
|
||||
};
|
||||
mainModule = lib.mkOption {
|
||||
internal = true;
|
||||
visible = false;
|
||||
readOnly = true;
|
||||
type = lib.types.deferredModule;
|
||||
default = mainModule config "HM" "home";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
mainModule =
|
||||
from: intent: name:
|
||||
let
|
||||
asp = den.aspects.${from.aspect};
|
||||
ctx = {
|
||||
${intent} = asp;
|
||||
${name} = from;
|
||||
};
|
||||
mod = (asp ctx).resolve { inherit (from) class; };
|
||||
in
|
||||
mod;
|
||||
in
|
||||
{
|
||||
inherit hostsOption homesOption;
|
||||
}
|
||||
8
flake/den/modules/aspects/defaults.nix
Normal file
8
flake/den/modules/aspects/defaults.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# creates den.default aspect
|
||||
{ lib, den, ... }:
|
||||
{
|
||||
config.den.default.__functor = den.lib.parametric.atLeast;
|
||||
options.den.default = lib.mkOption {
|
||||
type = den.lib.aspects.types.aspectSubmodule;
|
||||
};
|
||||
}
|
||||
34
flake/den/modules/aspects/definition.nix
Normal file
34
flake/den/modules/aspects/definition.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# create aspect dependencies from hosts/users
|
||||
{
|
||||
lib,
|
||||
den,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (den.lib) parametric;
|
||||
|
||||
makeAspect = from: {
|
||||
${from.aspect} = {
|
||||
${from.class} = { };
|
||||
includes = [ den.default ];
|
||||
__functor = parametric.atLeast;
|
||||
};
|
||||
};
|
||||
|
||||
hosts = map builtins.attrValues (builtins.attrValues den.hosts);
|
||||
homes = map builtins.attrValues (builtins.attrValues den.homes);
|
||||
aspectClass = from: { inherit (from) aspect class; };
|
||||
|
||||
deps = lib.pipe hosts [
|
||||
(lib.flatten)
|
||||
(map (h: builtins.attrValues h.users))
|
||||
(users: users ++ hosts ++ homes)
|
||||
(lib.flatten)
|
||||
(map aspectClass)
|
||||
(lib.unique)
|
||||
(map makeAspect)
|
||||
];
|
||||
in
|
||||
{
|
||||
den.aspects = lib.mkMerge deps;
|
||||
}
|
||||
97
flake/den/modules/aspects/dependencies.nix
Normal file
97
flake/den/modules/aspects/dependencies.nix
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
den,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (den.lib)
|
||||
owned
|
||||
statics
|
||||
parametric
|
||||
;
|
||||
|
||||
inherit (den.lib.take) exactly;
|
||||
|
||||
dependencies = [
|
||||
(exactly osDependencies)
|
||||
(exactly hmUserDependencies)
|
||||
(exactly hmStandaloneDependencies)
|
||||
];
|
||||
|
||||
osDependencies =
|
||||
{ OS, host }:
|
||||
{
|
||||
includes = [
|
||||
(owned den.default)
|
||||
(statics den.default)
|
||||
(owned OS)
|
||||
(statics OS)
|
||||
{
|
||||
includes =
|
||||
let
|
||||
users = builtins.attrValues host.users;
|
||||
contrib = osUserDependencies { inherit OS host; };
|
||||
in
|
||||
map contrib users;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
osUserDependencies =
|
||||
{ OS, host }:
|
||||
user:
|
||||
let
|
||||
USR = den.aspects.${user.aspect};
|
||||
in
|
||||
{
|
||||
includes = [
|
||||
(owned USR)
|
||||
(statics USR)
|
||||
(USR { inherit OS host user; })
|
||||
];
|
||||
};
|
||||
|
||||
# from OS home-managed integration.
|
||||
hmUserDependencies =
|
||||
{
|
||||
OS-HM,
|
||||
host,
|
||||
user,
|
||||
}:
|
||||
let
|
||||
inherit (OS-HM) OS HM;
|
||||
in
|
||||
{
|
||||
includes = [
|
||||
(owned den.default)
|
||||
(statics den.default)
|
||||
(owned HM)
|
||||
(statics HM)
|
||||
(owned OS)
|
||||
(statics OS)
|
||||
(parametric {
|
||||
inherit
|
||||
OS
|
||||
HM
|
||||
user
|
||||
host
|
||||
;
|
||||
} OS)
|
||||
];
|
||||
};
|
||||
|
||||
hmStandaloneDependencies =
|
||||
{ HM, home }:
|
||||
{
|
||||
includes = [
|
||||
(owned den.default)
|
||||
(statics den.default)
|
||||
(owned HM)
|
||||
(statics HM)
|
||||
];
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
den.default.includes = dependencies;
|
||||
}
|
||||
17
flake/den/modules/aspects/provides.nix
Normal file
17
flake/den/modules/aspects/provides.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{ lib, config, ... }:
|
||||
{
|
||||
options.den = lib.mkOption {
|
||||
type = lib.types.submodule {
|
||||
imports = [
|
||||
(lib.mkAliasOptionModule [ "_" ] [ "provides" ])
|
||||
];
|
||||
options.provides = lib.mkOption {
|
||||
default = { };
|
||||
description = "Batteries Included - re-usable high-level aspects";
|
||||
type = lib.types.submodule {
|
||||
freeformType = lib.types.attrsOf config.den.lib.aspects.types.providerType;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
55
flake/den/modules/aspects/provides/define-user.nix
Normal file
55
flake/den/modules/aspects/provides/define-user.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
{ lib, den, ... }:
|
||||
let
|
||||
description = ''
|
||||
Defines a user at OS and Home levels.
|
||||
|
||||
Works in NixOS/Darwin and standalone Home-Manager
|
||||
|
||||
## Usage
|
||||
|
||||
# for NixOS/Darwin
|
||||
den.aspects.my-user.includes = [ den._.define-user ]
|
||||
|
||||
# for standalone home-manager
|
||||
den.aspects.my-home.includes = [ den._.define-user ]
|
||||
|
||||
or globally (automatically applied depending on context):
|
||||
|
||||
den.default.includes = [ den._.define-user ]
|
||||
'';
|
||||
|
||||
homeDir =
|
||||
host: user:
|
||||
if lib.hasSuffix "darwin" host.system then "/Users/${user.userName}" else "/home/${user.userName}";
|
||||
|
||||
userContext =
|
||||
{ host, user, ... }:
|
||||
{
|
||||
nixos.users.users.${user.userName}.isNormalUser = true;
|
||||
darwin.users.users.${user.userName} = {
|
||||
name = user.userName;
|
||||
home = homeDir host user;
|
||||
};
|
||||
homeManager = {
|
||||
home.username = user.userName;
|
||||
home.homeDirectory = homeDir host user;
|
||||
};
|
||||
};
|
||||
|
||||
hmContext =
|
||||
{ home, ... }:
|
||||
userContext {
|
||||
host.system = home.system;
|
||||
user.userName = home.userName;
|
||||
};
|
||||
in
|
||||
{
|
||||
den.provides.define-user = {
|
||||
inherit description;
|
||||
includes = [
|
||||
userContext
|
||||
hmContext
|
||||
];
|
||||
__functor = den.lib.parametric.atLeast;
|
||||
};
|
||||
}
|
||||
76
flake/den/modules/aspects/provides/home-manager.nix
Normal file
76
flake/den/modules/aspects/provides/home-manager.nix
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
inputs,
|
||||
lib,
|
||||
den,
|
||||
...
|
||||
}:
|
||||
let
|
||||
description = ''
|
||||
integrates home-manager into nixos/darwin OS classes.
|
||||
|
||||
usage:
|
||||
|
||||
for using home-manager in just a particular host:
|
||||
|
||||
den.aspects.my-laptop.includes = [ den._.home-manager ];
|
||||
|
||||
for enabling home-manager by default on all hosts:
|
||||
|
||||
den.default.includes = [ den._.home-manager ];
|
||||
|
||||
Does nothing for hosts that have no users with `homeManager` class.
|
||||
Expects `inputs.home-manager` to exist. If `<host>.hm-module` exists
|
||||
it is the home-manager.{nixos/darwin}Modules.home-manager.
|
||||
|
||||
For each user resolves den.aspects.''${user.aspect} and imports its homeManager class module.
|
||||
'';
|
||||
|
||||
homeManager =
|
||||
{ OS, host }:
|
||||
{ class, aspect-chain }:
|
||||
let
|
||||
hmClass = "homeManager";
|
||||
hmUsers = builtins.filter (u: u.class == hmClass) (lib.attrValues host.users);
|
||||
|
||||
hmUserModule =
|
||||
user:
|
||||
let
|
||||
ctx = {
|
||||
inherit aspect-chain;
|
||||
class = hmClass;
|
||||
};
|
||||
HM = den.aspects.${user.aspect};
|
||||
aspect = HM {
|
||||
inherit host user;
|
||||
OS-HM = { inherit OS HM; };
|
||||
};
|
||||
module = aspect.resolve ctx;
|
||||
in
|
||||
module;
|
||||
|
||||
users = map (user: {
|
||||
name = user.userName;
|
||||
value.imports = [ (hmUserModule user) ];
|
||||
}) hmUsers;
|
||||
|
||||
hmModule = host.hm-module or inputs.home-manager."${class}Modules".home-manager;
|
||||
aspect.${class} = {
|
||||
imports = [ hmModule ];
|
||||
home-manager.users = lib.listToAttrs users;
|
||||
};
|
||||
|
||||
supportedOS = builtins.elem class [
|
||||
"nixos"
|
||||
"darwin"
|
||||
];
|
||||
enabled = supportedOS && builtins.length hmUsers > 0;
|
||||
in
|
||||
if enabled then aspect else { };
|
||||
|
||||
in
|
||||
{
|
||||
den.provides.home-manager = {
|
||||
inherit description;
|
||||
__functor = _: den.lib.take.exactly homeManager;
|
||||
};
|
||||
}
|
||||
77
flake/den/modules/aspects/provides/import-tree.nix
Normal file
77
flake/den/modules/aspects/provides/import-tree.nix
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
inputs,
|
||||
den,
|
||||
...
|
||||
}:
|
||||
{
|
||||
den.provides.import-tree.description = ''
|
||||
Recursively imports non-dendritic .nix files depending on their Nix configuration `class`.
|
||||
|
||||
This can be used to help migrating from huge existing setups.
|
||||
|
||||
|
||||
```
|
||||
# this is at <repo>/modules/non-dendritic.nix
|
||||
den.aspects.my-laptop.includes = [
|
||||
(den._.import-tree._.host ../non-dendritic)
|
||||
]
|
||||
```
|
||||
|
||||
With following structure, it will automatically load modules depending on their class.
|
||||
|
||||
```
|
||||
<repo>/
|
||||
modules/
|
||||
non-dendritic.nix # configures this aspect
|
||||
non-dendritic/ # name is just an example here
|
||||
hosts/
|
||||
my-laptop/
|
||||
_nixos/ # a directory for `nixos` class
|
||||
auto-generated-hardware.nix # any nixos module
|
||||
_darwin/
|
||||
foo.nix
|
||||
_homeManager/
|
||||
me.nix
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- inputs.import-tree
|
||||
|
||||
## Usage
|
||||
|
||||
this aspect can be included explicitly on any aspect:
|
||||
|
||||
# example: will import ./disko/_nixos files automatically.
|
||||
den.aspects.my-disko.includes = [ (den._.import-tree ./disko/) ];
|
||||
|
||||
or it can be default imported per host/user/home:
|
||||
|
||||
# load from ./hosts/<host>/_nixos
|
||||
den.default.includes = [ (den._.import-tree._.host ./hosts) ];
|
||||
|
||||
# load from ./users/<user>/{_homeManager, _nixos}
|
||||
den.default.includes = [ (den._.import-tree._.user ./users) ];
|
||||
|
||||
# load from ./homes/<home>/_homeManager
|
||||
den.default.includes = [ (den._.import-tree._.home ./homes) ];
|
||||
|
||||
you are also free to create your own auto-imports layout following the implementation of these.
|
||||
'';
|
||||
|
||||
den._.import-tree.__functor =
|
||||
_: root:
|
||||
# deadnix: skip
|
||||
{ class, aspect-chain }:
|
||||
let
|
||||
path = "${toString root}/_${class}";
|
||||
aspect.${class}.imports = [ (inputs.import-tree path) ];
|
||||
in
|
||||
if builtins.pathExists path then aspect else { };
|
||||
|
||||
den._.import-tree.provides = {
|
||||
host = root: { host, ... }: den._.import-tree "${toString root}/${host.name}";
|
||||
home = root: { home, ... }: den._.import-tree "${toString root}/${home.name}";
|
||||
user = root: { user, ... }: den._.import-tree "${toString root}/${user.name}";
|
||||
};
|
||||
}
|
||||
37
flake/den/modules/aspects/provides/primary-user.nix
Normal file
37
flake/den/modules/aspects/provides/primary-user.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
description = ''
|
||||
Sets user as *primary*.
|
||||
|
||||
On NixOS adds wheel and networkmanager groups.
|
||||
On Darwin sets user as system.primaryUser
|
||||
On WSL sets wsl.defaultUser if host has an `wsl` attribute.
|
||||
|
||||
## Usage
|
||||
|
||||
den.aspects.my-user.includes = [ den._.primary-user ];
|
||||
|
||||
'';
|
||||
|
||||
userToHostContext =
|
||||
{ user, host, ... }:
|
||||
let
|
||||
on-wsl.nixos.wsl.defaultUser = user.userName;
|
||||
in
|
||||
{
|
||||
inherit description;
|
||||
includes = lib.optionals (host ? wsl) [ on-wsl ];
|
||||
darwin.system.primaryUser = user.userName;
|
||||
nixos.users.users.${user.userName} = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [
|
||||
"wheel"
|
||||
"networkmanager"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
den.provides.primary-user = userToHostContext;
|
||||
}
|
||||
22
flake/den/modules/aspects/provides/unfree.nix
Normal file
22
flake/den/modules/aspects/provides/unfree.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{ lib, ... }:
|
||||
{
|
||||
den.provides.unfree.description = ''
|
||||
A class generic aspect that enables unfree packages by name.
|
||||
|
||||
Works for any class (nixos/darwin/homeManager,etc) on any host/user/home context.
|
||||
|
||||
## Usage
|
||||
|
||||
den.aspects.my-laptop.includes = [ (den._.unfree [ "code" ]) ];
|
||||
|
||||
It will dynamically provide a module for each class when accessed.
|
||||
'';
|
||||
|
||||
den.provides.unfree.__functor =
|
||||
_self: allowed-names:
|
||||
# deadnix: allow
|
||||
{ class, aspect-chain }:
|
||||
{
|
||||
${class}.nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) allowed-names;
|
||||
};
|
||||
}
|
||||
41
flake/den/modules/aspects/provides/user-shell.nix
Normal file
41
flake/den/modules/aspects/provides/user-shell.nix
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{ den, ... }:
|
||||
let
|
||||
|
||||
description = ''
|
||||
Sets a user default shell, enables the shell at OS and Home level.
|
||||
|
||||
Usage:
|
||||
|
||||
den.aspects.vic.includes = [
|
||||
# will always love red snappers.
|
||||
(den._.user-shell "fish")
|
||||
];
|
||||
'';
|
||||
|
||||
userShell =
|
||||
shell: user:
|
||||
let
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.${shell}.enable = true;
|
||||
users.users.${user.userName}.shell = pkgs.${shell};
|
||||
};
|
||||
darwin = nixos;
|
||||
homeManager.programs.${shell}.enable = true;
|
||||
in
|
||||
{
|
||||
inherit nixos darwin homeManager;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
den.provides.user-shell = shell: {
|
||||
inherit description;
|
||||
__functor = den.lib.parametric.atLeast;
|
||||
includes = [
|
||||
({ user, ... }: userShell shell user)
|
||||
({ home, ... }: userShell shell home)
|
||||
];
|
||||
};
|
||||
}
|
||||
58
flake/den/modules/config.nix
Normal file
58
flake/den/modules/config.nix
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
withSystem,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
build =
|
||||
builder: cfg:
|
||||
let
|
||||
items = map builtins.attrValues (builtins.attrValues cfg);
|
||||
buildItem = item: {
|
||||
inherit (item) name intoAttr;
|
||||
value = builder item;
|
||||
};
|
||||
in
|
||||
map buildItem (lib.flatten items);
|
||||
|
||||
osConfiguration =
|
||||
host:
|
||||
host.instantiate {
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
};
|
||||
modules = [
|
||||
host.mainModule
|
||||
{ nixpkgs.hostPlatform = lib.mkDefault host.system; }
|
||||
];
|
||||
};
|
||||
|
||||
homeConfiguration =
|
||||
home:
|
||||
withSystem home.system (
|
||||
{ pkgs, ... }:
|
||||
home.instantiate {
|
||||
inherit pkgs;
|
||||
extraSpecialArgs = { inherit inputs; };
|
||||
modules = [ home.mainModule ];
|
||||
}
|
||||
);
|
||||
|
||||
cfgs = (build osConfiguration config.den.hosts) ++ (build homeConfiguration config.den.homes);
|
||||
|
||||
outputs =
|
||||
acc: item:
|
||||
acc
|
||||
// {
|
||||
${item.intoAttr} = (acc.${item.intoAttr} or { }) // {
|
||||
${item.name} = item.value;
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
flake = lib.foldl outputs { } cfgs;
|
||||
}
|
||||
14
flake/den/modules/lib.nix
Normal file
14
flake/den/modules/lib.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
lib,
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config.den.lib = inputs.den.lib { inherit inputs lib config; };
|
||||
options.den.lib = lib.mkOption {
|
||||
internal = true;
|
||||
visible = false;
|
||||
type = lib.types.attrsOf lib.types.raw;
|
||||
};
|
||||
}
|
||||
13
flake/den/modules/options.nix
Normal file
13
flake/den/modules/options.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
inputs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
types = import ./_types.nix { inherit inputs lib config; };
|
||||
in
|
||||
{
|
||||
options.den.hosts = types.hostsOption;
|
||||
options.den.homes = types.homesOption;
|
||||
}
|
||||
10
flake/den/modules/scope.nix
Normal file
10
flake/den/modules/scope.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
config._module.args.den = config.den;
|
||||
imports = [ ((inputs.flake-aspects.lib lib).new-scope "den") ];
|
||||
}
|
||||
55
flake/den/nix/den-brackets.nix
Normal file
55
flake/den/nix/den-brackets.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# __findFile implementation to resolve deep aspects.
|
||||
# inspired by https://fzakaria.com/2025/08/10/angle-brackets-in-a-nix-flake-world
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
_nixPath: name:
|
||||
let
|
||||
|
||||
findAspect =
|
||||
path:
|
||||
let
|
||||
head = lib.head path;
|
||||
tail = lib.tail path;
|
||||
|
||||
notFound = "Aspect not found: ${lib.concatStringsSep "." path}";
|
||||
|
||||
headIsDen = head == "den";
|
||||
readFromDen = lib.getAttrFromPath ([ "den" ] ++ tail) config;
|
||||
|
||||
headIsAspect = builtins.hasAttr head config.den.aspects;
|
||||
aspectsPath = [
|
||||
"den"
|
||||
"aspects"
|
||||
] ++ path;
|
||||
readFromAspects = lib.getAttrFromPath aspectsPath config;
|
||||
|
||||
headIsDenful = lib.hasAttrByPath [ "ful" head ] config.den;
|
||||
denfulTail = if lib.head tail == "provides" then lib.tail tail else tail;
|
||||
denfulPath = [
|
||||
"den"
|
||||
"ful"
|
||||
head
|
||||
] ++ denfulTail;
|
||||
readFromDenful = lib.getAttrFromPath denfulPath config;
|
||||
|
||||
found =
|
||||
if headIsDen then
|
||||
readFromDen
|
||||
else if headIsAspect then
|
||||
readFromAspects
|
||||
else if headIsDenful then
|
||||
readFromDenful
|
||||
else
|
||||
throw notFound;
|
||||
in
|
||||
found;
|
||||
|
||||
in
|
||||
lib.pipe name [
|
||||
(lib.strings.replaceStrings [ "/" ] [ ".provides." ])
|
||||
(lib.strings.splitString ".")
|
||||
(findAspect)
|
||||
]
|
||||
4
flake/den/nix/flakeModule.nix
Normal file
4
flake/den/nix/flakeModule.nix
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [ (inputs.import-tree ../modules) ];
|
||||
}
|
||||
24
flake/den/nix/fn-can-take.nix
Normal file
24
flake/den/nix/fn-can-take.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
lib:
|
||||
let
|
||||
check =
|
||||
params: func:
|
||||
let
|
||||
givenArgs = builtins.isAttrs params;
|
||||
fargs = lib.functionArgs func;
|
||||
provided = builtins.attrNames params;
|
||||
args = lib.mapAttrsToList (name: optional: { inherit name optional; }) fargs;
|
||||
required = map (x: x.name) (lib.filter (x: !x.optional) args);
|
||||
intersection = lib.intersectLists required provided;
|
||||
satisfied = givenArgs && lib.length required == lib.length intersection;
|
||||
noExtras = lib.length required == lib.length provided;
|
||||
exactly = satisfied && noExtras;
|
||||
in
|
||||
{
|
||||
inherit satisfied exactly;
|
||||
};
|
||||
in
|
||||
{
|
||||
__functor = self: self.atLeast;
|
||||
atLeast = params: func: (check params func).satisfied;
|
||||
exactly = params: func: (check params func).exactly;
|
||||
}
|
||||
101
flake/den/nix/lib.nix
Normal file
101
flake/den/nix/lib.nix
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
{
|
||||
inputs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
||||
# "Just Give 'Em One of These" - Moe Szyslak
|
||||
# A __functor that applies context to parametric includes (functions)
|
||||
funk =
|
||||
apply: aspect:
|
||||
aspect
|
||||
// {
|
||||
__functor = self: ctx: {
|
||||
includes = builtins.filter (x: x != { }) (map (apply ctx) (builtins.filter isFn self.includes));
|
||||
};
|
||||
};
|
||||
|
||||
isFn = f: (builtins.isFunction f) || (f ? __functor);
|
||||
canTake = import ./fn-can-take.nix lib;
|
||||
|
||||
# creates an aspect that inherits class from fromAspect.
|
||||
owned =
|
||||
aspect:
|
||||
aspect
|
||||
// {
|
||||
includes = [ ];
|
||||
__functor =
|
||||
self:
|
||||
# deadnix: skip
|
||||
{ class, aspect-chain }:
|
||||
self;
|
||||
};
|
||||
|
||||
# only static includes from an aspect.
|
||||
statics =
|
||||
aspect:
|
||||
aspect
|
||||
// {
|
||||
__functor =
|
||||
self:
|
||||
# deadnix: skip
|
||||
{ class, aspect-chain }@ctx:
|
||||
funk applyStatics self ctx;
|
||||
};
|
||||
|
||||
applyStatics =
|
||||
ctx: f:
|
||||
if isStatic f then
|
||||
f ctx
|
||||
else if !isFn f then
|
||||
f
|
||||
else
|
||||
{ };
|
||||
|
||||
isStatic = canTake {
|
||||
class = "";
|
||||
aspect-chain = [ ];
|
||||
};
|
||||
|
||||
take.unused = _unused: used: used;
|
||||
take.exactly = take canTake.exactly;
|
||||
take.atLeast = take canTake.atLeast;
|
||||
take.__functor =
|
||||
_: takes: fn: ctx:
|
||||
if takes ctx fn then fn ctx else { };
|
||||
|
||||
parametric.atLeast = funk (lib.flip take.atLeast);
|
||||
parametric.exactly = funk (lib.flip take.exactly);
|
||||
parametric.fixedTo = lib.flip parametric.atLeast;
|
||||
parametric.expands = attrs: funk (ctx: (lib.flip take.atLeast) (ctx // attrs));
|
||||
parametric.__functor =
|
||||
self: ctx:
|
||||
if ctx == true then
|
||||
self.atLeast
|
||||
else if ctx == false then
|
||||
self.exactly
|
||||
else if isFn ctx then
|
||||
funk ctx
|
||||
else
|
||||
self.fixedTo ctx;
|
||||
|
||||
aspects = inputs.flake-aspects.lib lib;
|
||||
|
||||
__findFile = import ./den-brackets.nix { inherit lib config; };
|
||||
|
||||
den-lib = {
|
||||
inherit
|
||||
parametric
|
||||
aspects
|
||||
__findFile
|
||||
statics
|
||||
owned
|
||||
isFn
|
||||
canTake
|
||||
take
|
||||
;
|
||||
};
|
||||
in
|
||||
den-lib
|
||||
29
flake/den/nix/namespace.nix
Normal file
29
flake/den/nix/namespace.nix
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
name: input:
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
isLocal = !builtins.isAttrs input;
|
||||
isOutput = isLocal && input == true;
|
||||
|
||||
aliasModule = lib.mkAliasOptionModule [ name ] [ "den" "ful" name ];
|
||||
|
||||
type = lib.types.attrsOf config.den.lib.aspects.types.providerType;
|
||||
|
||||
source = if isLocal then { } else input.denful.${name};
|
||||
output =
|
||||
if isOutput then
|
||||
{
|
||||
config.flake.denful.${name} = config.den.ful.${name};
|
||||
options.flake.denful.${name} = lib.mkOption { inherit type; };
|
||||
}
|
||||
else
|
||||
{ };
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
aliasModule
|
||||
output
|
||||
];
|
||||
config._module.args.${name} = config.den.ful.${name};
|
||||
config.den.ful.${name} = source;
|
||||
options.den.ful.${name} = lib.mkOption { inherit type; };
|
||||
}
|
||||
13
flake/den/nix/template-packages.nix
Normal file
13
flake/den/nix/template-packages.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
let
|
||||
rev = "9100a0f";
|
||||
narHash = "sha256:09m84vsz1py50giyfpx0fpc7a4i0r1xsb54dh0dpdg308lp4p188";
|
||||
compat = fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/${rev}.tar.gz";
|
||||
sha256 = narHash;
|
||||
};
|
||||
flake = import compat { src = ../templates/default; };
|
||||
pkgs = flake.outputs.packages;
|
||||
in
|
||||
{
|
||||
x86_64-linux.default = pkgs.x86_64-linux.vm;
|
||||
}
|
||||
21
flake/den/templates/bogus/.github/workflows/test.yml
vendored
Normal file
21
flake/den/templates/bogus/.github/workflows/test.yml
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
on:
|
||||
pull_request:
|
||||
push:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
flake-check:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
name: Nix flake check
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: wimpysworld/nothing-but-nix@main
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- uses: actions/checkout@v5
|
||||
- run: nix flake metadata
|
||||
- run: nix flake check
|
||||
17
flake/den/templates/bogus/README.md
Normal file
17
flake/den/templates/bogus/README.md
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Bug Reproduction den
|
||||
|
||||
Use this small template to reproduce bugs in den.
|
||||
|
||||
Create a **minimal** bug reproduction at [`modules/bug.nix`](modules/bug.nix)
|
||||
|
||||
Then run tests:
|
||||
|
||||
```console
|
||||
nix flake check
|
||||
```
|
||||
|
||||
Format code with:
|
||||
|
||||
```console
|
||||
nix fmt
|
||||
```
|
||||
222
flake/den/templates/bogus/flake.lock
generated
Normal file
222
flake/den/templates/bogus/flake.lock
generated
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"nodes": {
|
||||
"den": {
|
||||
"locked": {
|
||||
"lastModified": 1763285091,
|
||||
"narHash": "sha256-F2OsALSm86dfNA2grd5MVRPpAWZf4ZuuCzpYG7H0P9g=",
|
||||
"owner": "vic",
|
||||
"repo": "den",
|
||||
"rev": "227451c9a99fb084bc6b66878c7f6f3e75f625d2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"ref": "main",
|
||||
"repo": "den",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-aspects": {
|
||||
"locked": {
|
||||
"lastModified": 1763284357,
|
||||
"narHash": "sha256-mPMHkhpOIsj2lg+KIcapFd4uj2N/9mZZ6RZBo/p5O1c=",
|
||||
"owner": "vic",
|
||||
"repo": "flake-aspects",
|
||||
"rev": "6a6d47f531ad57ac854cee689e84f2e28861ec49",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "flake-aspects",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-file": {
|
||||
"locked": {
|
||||
"lastModified": 1762466468,
|
||||
"narHash": "sha256-OTAbN2Vmdn6Km2AYN+G6QrCdQUtbqaJKAJATP0tGkB8=",
|
||||
"owner": "vic",
|
||||
"repo": "flake-file",
|
||||
"rev": "6a7da81583a42ba339a06aed2d0f3ee4a164f265",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "flake-file",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs-lib"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762440070,
|
||||
"narHash": "sha256-xxdepIcb39UJ94+YydGP221rjnpkDZUlykKuF54PsqI=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "26d05891e14c88eb4a5d5bee659c0db5afb609d8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762463325,
|
||||
"narHash": "sha256-33YUsWpPyeBZEWrKQ2a1gkRZ7i0XCC/2MYpU6BVeQSU=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "0562fef070a1027325dd4ea10813d64d2c967b39",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"import-tree": {
|
||||
"locked": {
|
||||
"lastModified": 1762327901,
|
||||
"narHash": "sha256-AJ96FNj50DU0bTyIzAPkPOjCZTHqjURVjok8qoXvmqM=",
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"rev": "90fa129798be99cde036b78658e89475710966a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-auto-follow": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1754073254,
|
||||
"narHash": "sha256-CQp/v2HQ7AtGJQqFGRZLHt4MZAK3NF94I6GDaRyhbsc=",
|
||||
"owner": "fzakaria",
|
||||
"repo": "nix-auto-follow",
|
||||
"rev": "5baa00b79d4cc46523da0b8b3532c5163d151be4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "fzakaria",
|
||||
"repo": "nix-auto-follow",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-unit": {
|
||||
"inputs": {
|
||||
"flake-parts": [
|
||||
"flake-parts"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"treefmt-nix": [
|
||||
"treefmt-nix"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762507096,
|
||||
"narHash": "sha256-dE3CbZR8KRDdb3b4fhMnpvhEl6XB+UnrLezuFekQ2ME=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-unit",
|
||||
"rev": "0d7230bc54783b812a5817398885aec660a93051",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-unit",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1762361079,
|
||||
"narHash": "sha256-lz718rr1BDpZBYk7+G8cE6wee3PiBUpn8aomG/vLLiY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "ffcdcf99d65c61956d882df249a9be53e5902ea5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"den": "den",
|
||||
"flake-aspects": "flake-aspects",
|
||||
"flake-file": "flake-file",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"import-tree": "import-tree",
|
||||
"nix-auto-follow": "nix-auto-follow",
|
||||
"nix-unit": "nix-unit",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762410071,
|
||||
"narHash": "sha256-aF5fvoZeoXNPxT0bejFUBXeUjXfHLSL7g+mjR/p5TEg=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "97a30861b13c3731a84e09405414398fbf3e109f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
77
flake/den/templates/bogus/flake.nix
Normal file
77
flake/den/templates/bogus/flake.nix
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
# DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file.
|
||||
# Use `nix run .#write-flake` to regenerate it.
|
||||
{
|
||||
|
||||
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);
|
||||
|
||||
inputs = {
|
||||
den = {
|
||||
url = "github:vic/den/main";
|
||||
};
|
||||
flake-aspects = {
|
||||
url = "github:vic/flake-aspects";
|
||||
};
|
||||
flake-file = {
|
||||
url = "github:vic/flake-file";
|
||||
};
|
||||
flake-parts = {
|
||||
inputs = {
|
||||
nixpkgs-lib = {
|
||||
follows = "nixpkgs-lib";
|
||||
};
|
||||
};
|
||||
url = "github:hercules-ci/flake-parts";
|
||||
};
|
||||
home-manager = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:nix-community/home-manager";
|
||||
};
|
||||
import-tree = {
|
||||
url = "github:vic/import-tree";
|
||||
};
|
||||
nix-auto-follow = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:fzakaria/nix-auto-follow";
|
||||
};
|
||||
nix-unit = {
|
||||
inputs = {
|
||||
flake-parts = {
|
||||
follows = "flake-parts";
|
||||
};
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
treefmt-nix = {
|
||||
follows = "treefmt-nix";
|
||||
};
|
||||
};
|
||||
url = "github:nix-community/nix-unit";
|
||||
};
|
||||
nixpkgs = {
|
||||
url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
nixpkgs-lib = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
systems = {
|
||||
url = "github:nix-systems/default";
|
||||
};
|
||||
treefmt-nix = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:numtide/treefmt-nix";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
27
flake/den/templates/bogus/modules/bug.nix
Normal file
27
flake/den/templates/bogus/modules/bug.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{ inputs, lib, ... }:
|
||||
{
|
||||
den.hosts.x86_64-linux.igloo.users.tux = { };
|
||||
den.hosts.aarch64-darwin.apple.users.tim = { };
|
||||
|
||||
# Use aspects to create a **minimal** bug reproduction
|
||||
den.aspects.igloo.nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
users.users.tux.packages = [ pkgs.hello ];
|
||||
};
|
||||
|
||||
# rename "it works", evidently it has bugs
|
||||
flake.tests."test it works" =
|
||||
let
|
||||
tux = inputs.self.nixosConfigurations.igloo.config.users.users.tux;
|
||||
|
||||
expr.len = lib.length tux.packages;
|
||||
expr.names = map lib.getName tux.packages;
|
||||
|
||||
expected.len = 1;
|
||||
expected.names = [ "hello" ];
|
||||
in
|
||||
{
|
||||
inherit expr expected;
|
||||
};
|
||||
}
|
||||
7
flake/den/templates/bogus/modules/dendritic.nix
Normal file
7
flake/den/templates/bogus/modules/dendritic.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{ inputs, lib, ... }:
|
||||
{
|
||||
flake-file.inputs.flake-file.url = lib.mkDefault "github:vic/flake-file";
|
||||
imports = [
|
||||
inputs.flake-file.flakeModules.dendritic
|
||||
];
|
||||
}
|
||||
33
flake/den/templates/bogus/modules/flakes.nix
Normal file
33
flake/den/templates/bogus/modules/flakes.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# DO-NOT-CHANGE. Keep your reproduction minimalistic!
|
||||
#
|
||||
# try not adding new inputs
|
||||
# but if you have no options (pun intended)
|
||||
# here's the place.
|
||||
#
|
||||
# IF you make any change to this file, use:
|
||||
# `nix run .#write-flake`
|
||||
#
|
||||
# We provide nix-unit and home-manager for common
|
||||
# usage.
|
||||
{ inputs, ... }:
|
||||
{
|
||||
# change "main" with a commit where bug is present
|
||||
flake-file.inputs.den.url = "github:vic/den/main";
|
||||
|
||||
flake-file.inputs.nix-unit = {
|
||||
url = "github:nix-community/nix-unit";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.flake-parts.follows = "flake-parts";
|
||||
inputs.treefmt-nix.follows = "treefmt-nix";
|
||||
};
|
||||
|
||||
flake-file.inputs.home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
imports = [
|
||||
inputs.nix-unit.modules.flake.default
|
||||
];
|
||||
|
||||
}
|
||||
12
flake/den/templates/bogus/modules/formatter.nix
Normal file
12
flake/den/templates/bogus/modules/formatter.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
perSystem = {
|
||||
treefmt = {
|
||||
projectRootFile = "flake.nix";
|
||||
programs.nixfmt.enable = true;
|
||||
programs.nixfmt.excludes = [ ".direnv" ];
|
||||
programs.deadnix.enable = true;
|
||||
programs.mdformat.enable = true;
|
||||
programs.yamlfmt.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
8
flake/den/templates/bogus/modules/nix-unit.nix
Normal file
8
flake/den/templates/bogus/modules/nix-unit.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# DO-NOT-EDIT: nix-unit configuration.
|
||||
{ lib, inputs, ... }:
|
||||
{
|
||||
perSystem.nix-unit = {
|
||||
allowNetwork = lib.mkDefault true;
|
||||
inputs = lib.mkDefault inputs;
|
||||
};
|
||||
}
|
||||
17
flake/den/templates/bogus/modules/test-base.nix
Normal file
17
flake/den/templates/bogus/modules/test-base.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{ den, ... }:
|
||||
{
|
||||
den.default.nixos.system.stateVersion = "25.11";
|
||||
den.default.homeManager.home.stateVersion = "25.11";
|
||||
den.default.darwin.system.stateVersion = 6;
|
||||
|
||||
den.default.includes = [
|
||||
den._.home-manager
|
||||
den._.define-user
|
||||
den.aspects.no-boot
|
||||
];
|
||||
|
||||
den.aspects.no-boot.nixos = {
|
||||
boot.loader.grub.enable = false;
|
||||
fileSystems."/".device = "/dev/fake";
|
||||
};
|
||||
}
|
||||
27
flake/den/templates/default/.github/workflows/test.yml
vendored
Normal file
27
flake/den/templates/default/.github/workflows/test.yml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
on:
|
||||
pull_request:
|
||||
push:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
flake-check:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
name: Nix flake check ${{matrix.os}}
|
||||
runs-on: ${{matrix.os}}
|
||||
steps:
|
||||
- uses: wimpysworld/nothing-but-nix@main
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
- uses: DeterminateSystems/nix-installer-action@main
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- uses: actions/checkout@v5
|
||||
- run: nix flake metadata
|
||||
- run: |
|
||||
cat <<-EOF > modules/ci-runtime.nix
|
||||
{
|
||||
_module.args.CI = true;
|
||||
}
|
||||
EOF
|
||||
- run: nix flake check
|
||||
35
flake/den/templates/default/README.md
Normal file
35
flake/den/templates/default/README.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Getting Started Guide
|
||||
|
||||
Steps you can follow after cloning this template:
|
||||
|
||||
- Be sure to read the [den documentation](https://vic.github.io/den)
|
||||
|
||||
- Update den input.
|
||||
|
||||
```console
|
||||
nix flake update den
|
||||
```
|
||||
|
||||
- Run checks to test everything works.
|
||||
|
||||
```console
|
||||
nix flake check
|
||||
```
|
||||
|
||||
- Read [modules/den.nix](modules/den.nix) where hosts and homes definitions are for this example.
|
||||
|
||||
- Read [modules/namespace.nix](modules/namespace.nix) where a new `eg` (an example) aspects namespace is created.
|
||||
|
||||
- Read [modules/aspects/igloo.nix](modules/aspects/igloo.nix) where the `igloo` host is configured.
|
||||
|
||||
- Read [modules/aspects/alice.nix](modules/aspects/alice.nix) where the `alice` user is configured.
|
||||
|
||||
- Run the VM.
|
||||
|
||||
```console
|
||||
nix run .#vm
|
||||
```
|
||||
|
||||
- Edit and run VM loop.
|
||||
|
||||
Feel free to add more aspects, organize things to your liking.
|
||||
173
flake/den/templates/default/flake.lock
generated
Normal file
173
flake/den/templates/default/flake.lock
generated
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
{
|
||||
"nodes": {
|
||||
"darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762627886,
|
||||
"narHash": "sha256-/QLk1bzmbcqJt9sU43+y/3tHtXhAy0l8Ck0MoO2+evQ=",
|
||||
"owner": "nix-darwin",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "5125a3cd414dc98bbe2c528227aa6b62ee61f733",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-darwin",
|
||||
"repo": "nix-darwin",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"den": {
|
||||
"locked": {
|
||||
"lastModified": 1763285091,
|
||||
"narHash": "sha256-F2OsALSm86dfNA2grd5MVRPpAWZf4ZuuCzpYG7H0P9g=",
|
||||
"owner": "vic",
|
||||
"repo": "den",
|
||||
"rev": "227451c9a99fb084bc6b66878c7f6f3e75f625d2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "den",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-aspects": {
|
||||
"locked": {
|
||||
"lastModified": 1763284357,
|
||||
"narHash": "sha256-mPMHkhpOIsj2lg+KIcapFd4uj2N/9mZZ6RZBo/p5O1c=",
|
||||
"owner": "vic",
|
||||
"repo": "flake-aspects",
|
||||
"rev": "6a6d47f531ad57ac854cee689e84f2e28861ec49",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "flake-aspects",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-file": {
|
||||
"locked": {
|
||||
"lastModified": 1762732765,
|
||||
"narHash": "sha256-sVxN4q4V8jhIAF44aPSMULIJMJ5eG5HtzcQgbr2UEBg=",
|
||||
"owner": "vic",
|
||||
"repo": "flake-file",
|
||||
"rev": "7b037ae446102d3ccc5e23d3c52d5ada8e0fc4f3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "flake-file",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs-lib"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762810396,
|
||||
"narHash": "sha256-dxFVgQPG+R72dkhXTtqUm7KpxElw3u6E+YlQ2WaDgt8=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "0bdadb1b265fb4143a75bd1ec7d8c915898a9923",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762787259,
|
||||
"narHash": "sha256-t2U/GLLXHa2+kJkwnFNRVc2fEJ/lUfyZXBE5iKzJdcs=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "37a3d97f2873e0f68711117c34d04b7c7ead8f4e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"import-tree": {
|
||||
"locked": {
|
||||
"lastModified": 1762327901,
|
||||
"narHash": "sha256-AJ96FNj50DU0bTyIzAPkPOjCZTHqjURVjok8qoXvmqM=",
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"rev": "90fa129798be99cde036b78658e89475710966a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1762482733,
|
||||
"narHash": "sha256-g/da4FzvckvbiZT075Sb1/YDNDr+tGQgh4N8i5ceYMg=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e1ebeec86b771e9d387dd02d82ffdc77ac753abc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"darwin": "darwin",
|
||||
"den": "den",
|
||||
"flake-aspects": "flake-aspects",
|
||||
"flake-file": "flake-file",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"import-tree": "import-tree",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"systems": "systems"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
55
flake/den/templates/default/flake.nix
Normal file
55
flake/den/templates/default/flake.nix
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
# DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file.
|
||||
# Use `nix run .#write-flake` to regenerate it.
|
||||
{
|
||||
|
||||
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);
|
||||
|
||||
inputs = {
|
||||
darwin = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:nix-darwin/nix-darwin";
|
||||
};
|
||||
den = {
|
||||
url = "github:vic/den";
|
||||
};
|
||||
flake-aspects = {
|
||||
url = "github:vic/flake-aspects";
|
||||
};
|
||||
flake-file = {
|
||||
url = "github:vic/flake-file";
|
||||
};
|
||||
flake-parts = {
|
||||
inputs = {
|
||||
nixpkgs-lib = {
|
||||
follows = "nixpkgs-lib";
|
||||
};
|
||||
};
|
||||
url = "github:hercules-ci/flake-parts";
|
||||
};
|
||||
home-manager = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:nix-community/home-manager";
|
||||
};
|
||||
import-tree = {
|
||||
url = "github:vic/import-tree";
|
||||
};
|
||||
nixpkgs = {
|
||||
url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
nixpkgs-lib = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
systems = {
|
||||
url = "github:nix-systems/default";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
70
flake/den/templates/default/modules/aspects/alice.nix
Normal file
70
flake/den/templates/default/modules/aspects/alice.nix
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
{ den, eg, ... }:
|
||||
{
|
||||
den.aspects.alice = {
|
||||
|
||||
# Alice can include other aspects.
|
||||
# For small, private one-shot aspects, use let-bindings like here.
|
||||
# for more complex or re-usable ones, define on their own modules,
|
||||
# as part of any aspect-subtree.
|
||||
includes =
|
||||
let
|
||||
# deadnix: skip # not required, showcasing angle-brackets syntax.
|
||||
inherit (den.lib) __findFile;
|
||||
|
||||
customEmacs.homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.emacs.enable = true;
|
||||
programs.emacs.package = pkgs.emacs30-nox;
|
||||
};
|
||||
in
|
||||
[
|
||||
# from local bindings.
|
||||
customEmacs
|
||||
# from the aspect tree, cooper example is defined bellow
|
||||
den.aspects.cooper
|
||||
den.aspects.setHost
|
||||
# from the `eg` namespace.
|
||||
eg.autologin
|
||||
# den included batteries that provide common configs.
|
||||
<den/primary-user> # alice is admin always.
|
||||
(<den/user-shell> "fish") # default user shell
|
||||
];
|
||||
|
||||
# Alice configures NixOS hosts it lives on.
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
users.users.alice.packages = [ pkgs.vim ];
|
||||
};
|
||||
|
||||
# Alice home-manager.
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [ pkgs.htop ];
|
||||
};
|
||||
|
||||
# <user>.provides.<host>, via eg/routes.nix
|
||||
provides.igloo =
|
||||
{ host, ... }:
|
||||
{
|
||||
nixos.programs.nh.enable = host.name == "igloo";
|
||||
};
|
||||
};
|
||||
|
||||
# This is a context-aware aspect, that emits configurations
|
||||
# **anytime** at least the `user` data is in context.
|
||||
# read more at https://vic.github.io/den/context-aware.html
|
||||
den.aspects.cooper =
|
||||
{ user, ... }:
|
||||
{
|
||||
nixos.users.users.${user.userName}.description = "Alice Cooper";
|
||||
};
|
||||
|
||||
den.aspects.setHost =
|
||||
{ host, ... }:
|
||||
{
|
||||
networking.hostName = host.hostName;
|
||||
};
|
||||
}
|
||||
48
flake/den/templates/default/modules/aspects/defaults.nix
Normal file
48
flake/den/templates/default/modules/aspects/defaults.nix
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
config,
|
||||
# deadnix: skip # enable <den/brackets> syntax for demo.
|
||||
__findFile ? __findFile,
|
||||
den,
|
||||
...
|
||||
}:
|
||||
{
|
||||
# Lets also configure some defaults using aspects.
|
||||
# These are global static settings.
|
||||
den.default = {
|
||||
darwin.system.stateVersion = 6;
|
||||
nixos.system.stateVersion = "25.05";
|
||||
homeManager.home.stateVersion = "25.05";
|
||||
};
|
||||
|
||||
# These are functions that produce configs
|
||||
den.default.includes = [
|
||||
# ${user}.provides.${host} and ${host}.provides.${user}
|
||||
<eg/routes>
|
||||
|
||||
# Enable home-manager on all hosts.
|
||||
<den/home-manager>
|
||||
|
||||
# Automatically create the user on host.
|
||||
<den/define-user>
|
||||
|
||||
# Disable booting when running on CI on all NixOS hosts.
|
||||
(if config ? _module.args.CI then <eg/ci-no-boot> else { })
|
||||
|
||||
# NOTE: be cautious when adding fully parametric functions to defaults.
|
||||
# defaults are included on EVERY host/user/home, and IF you are not careful
|
||||
# you could be duplicating config values. For example:
|
||||
#
|
||||
# # This will append 42 into foo option for the {host} and for EVERY {host,user}
|
||||
# ({ host, ... }: { nixos.foo = [ 42 ]; }) # DO-NOT-DO-THIS.
|
||||
#
|
||||
# # Instead try to be explicit if a function is intended for ONLY { host }.
|
||||
(den.lib.take.exactly (
|
||||
# deadnix: skip
|
||||
{ OS, host }:
|
||||
{
|
||||
nixos.networking.hostName = host.hostName;
|
||||
}
|
||||
))
|
||||
|
||||
];
|
||||
}
|
||||
15
flake/den/templates/default/modules/aspects/eg/autologin.nix
Normal file
15
flake/den/templates/default/modules/aspects/eg/autologin.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
# autologin is context-aware, parametric aspect.
|
||||
# it applies only if the context has at least { user }
|
||||
# meaning that has access to user data
|
||||
eg.autologin =
|
||||
{ user, ... }:
|
||||
{
|
||||
nixos =
|
||||
{ config, lib, ... }:
|
||||
lib.mkIf config.services.displayManager.enable {
|
||||
services.displayManager.autoLogin.enable = true;
|
||||
services.displayManager.autoLogin.user = user.userName;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
eg.ci-no-boot = {
|
||||
description = "Disables booting during CI";
|
||||
nixos = {
|
||||
boot.loader.grub.enable = false;
|
||||
fileSystems."/".device = "/dev/null";
|
||||
};
|
||||
};
|
||||
}
|
||||
37
flake/den/templates/default/modules/aspects/eg/routes.nix
Normal file
37
flake/den/templates/default/modules/aspects/eg/routes.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# This example implements an aspect "routing" pattern.
|
||||
#
|
||||
# Unlike `den.default` which is `parametric.atLeast`
|
||||
# we use `parametric.fixedTo` here, which help us
|
||||
# propagate an already computed context to all includes.
|
||||
#
|
||||
# This aspect, when installed in a `parametric.atLeast`
|
||||
# will just forward the same context.
|
||||
# The `mutual` helper returns an static configuration which
|
||||
# is ignored by parametric aspects, thus allowing
|
||||
# non-existing aspects to be just ignored.
|
||||
#
|
||||
# Be sure to read: https://vic.github.io/den/dependencies.html
|
||||
# See usage at: defaults.nix, alice.nix, igloo.nix
|
||||
#
|
||||
{ den, eg, ... }:
|
||||
{
|
||||
# Usage: `den.default.includes [ eg.routes ]`
|
||||
eg.routes =
|
||||
let
|
||||
inherit (den.lib) parametric;
|
||||
|
||||
# eg, `<user>._.<host>` and `<host>._.<user>`
|
||||
mutual = from: to: den.aspects.${from.aspect}._.${to.aspect} or { };
|
||||
|
||||
routes =
|
||||
{ host, user, ... }@ctx:
|
||||
{
|
||||
__functor = parametric.fixedTo ctx;
|
||||
includes = [
|
||||
(mutual user host)
|
||||
(mutual host user)
|
||||
];
|
||||
};
|
||||
in
|
||||
routes;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
let
|
||||
installer = variant: {
|
||||
nixos =
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-${variant}.nix") ];
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
# make USB/VM installers.
|
||||
eg.vm-bootable.provides = {
|
||||
tui = installer "minimal";
|
||||
gui = installer "graphical-base";
|
||||
};
|
||||
}
|
||||
15
flake/den/templates/default/modules/aspects/eg/vm.nix
Normal file
15
flake/den/templates/default/modules/aspects/eg/vm.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ eg, ... }:
|
||||
{
|
||||
eg.vm.provides = {
|
||||
gui.includes = [
|
||||
eg.vm
|
||||
eg.vm-bootable._.gui
|
||||
eg.xfce-desktop
|
||||
];
|
||||
|
||||
tui.includes = [
|
||||
eg.vm
|
||||
eg.vm-bootable._.tui
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
eg.xfce-desktop.nixos =
|
||||
{ lib, ... }:
|
||||
{
|
||||
# https://gist.github.com/nat-418/1101881371c9a7b419ba5f944a7118b0
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
desktopManager = {
|
||||
xterm.enable = false;
|
||||
xfce.enable = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.displayManager = {
|
||||
defaultSession = lib.mkDefault "xfce";
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
20
flake/den/templates/default/modules/aspects/igloo.nix
Normal file
20
flake/den/templates/default/modules/aspects/igloo.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
den.aspects.igloo = {
|
||||
# igloo host provides some home-manager defaults to its users.
|
||||
homeManager.programs.direnv.enable = true;
|
||||
|
||||
# NixOS configuration for igloo.
|
||||
nixos =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
environment.systemPackages = [ pkgs.hello ];
|
||||
};
|
||||
|
||||
# <host>.provides.<user>, via eg/routes.nix
|
||||
provides.alice =
|
||||
{ user, ... }:
|
||||
{
|
||||
homeManager.programs.helix.enable = user.name == "alice";
|
||||
};
|
||||
};
|
||||
}
|
||||
5
flake/den/templates/default/modules/den.nix
Normal file
5
flake/den/templates/default/modules/den.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
den.hosts.x86_64-linux.igloo.users.alice = { };
|
||||
den.hosts.aarch64-darwin.apple.users.alice = { };
|
||||
den.homes.x86_64-linux.alice = { };
|
||||
}
|
||||
6
flake/den/templates/default/modules/dendritic.nix
Normal file
6
flake/den/templates/default/modules/dendritic.nix
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.flake-file.flakeModules.dendritic
|
||||
];
|
||||
}
|
||||
37
flake/den/templates/default/modules/inputs.nix
Normal file
37
flake/den/templates/default/modules/inputs.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# This repo was generated with github:vic/flake-file#dendritic template.
|
||||
# Run `nix run .#write-flake` after changing any input.
|
||||
#
|
||||
# Inputs can be placed in any module, the best practice is to have them
|
||||
# as close as possible to their actual usage.
|
||||
# See: https://vic.github.io/dendrix/Dendritic.html#minimal-and-focused-flakenix
|
||||
#
|
||||
# For our template, we enable home-manager and nix-darwin by default, but
|
||||
# you are free to remove them if not being used by you.
|
||||
{ inputs, ... }:
|
||||
{
|
||||
|
||||
flake-file.inputs = {
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
darwin = {
|
||||
url = "github:nix-darwin/nix-darwin";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
## these stable inputs are for wsl
|
||||
#nixpkgs-stable.url = "github:nixos/nixpkgs/release-25.05";
|
||||
#home-manager-stable.url = "github:nix-community/home-manager/release-25.05";
|
||||
#home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||
|
||||
#nixos-wsl = {
|
||||
# url = "github:nix-community/nixos-wsl";
|
||||
# inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||
# inputs.flake-compat.follows = "";
|
||||
#};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
14
flake/den/templates/default/modules/namespace.nix
Normal file
14
flake/den/templates/default/modules/namespace.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{ inputs, den, ... }:
|
||||
{
|
||||
# create an `eg` (example!) namespace.
|
||||
imports = [ (inputs.den.namespace "eg" false) ];
|
||||
|
||||
# you can have more than one namespace, create yours.
|
||||
# imports = [ (inputs.den.namespace "yours" true) ];
|
||||
|
||||
# you can also import namespaces from remote flakes.
|
||||
# imports = [ (inputs.den.namespace "ours" inputs.theirs) ];
|
||||
|
||||
# this line enables den angle brackets syntax in modules.
|
||||
_module.args.__findFile = den.lib.__findFile;
|
||||
}
|
||||
34
flake/den/templates/default/modules/tests.nix
Normal file
34
flake/den/templates/default/modules/tests.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Some CI checks to ensure this template always works.
|
||||
# Feel free to adapt or remove when this repo is yours.
|
||||
{ inputs, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
self',
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
checkCond = name: cond: pkgs.runCommandLocal name { } (if cond then "touch $out" else "");
|
||||
apple = inputs.self.darwinConfigurations.apple.config;
|
||||
igloo = inputs.self.nixosConfigurations.igloo.config;
|
||||
alice-at-igloo = igloo.home-manager.users.alice;
|
||||
vmBuilds = !pkgs.stdenvNoCC.isLinux || builtins.pathExists (self'.packages.vm + "/bin/vm");
|
||||
iglooBuilds = !pkgs.stdenvNoCC.isLinux || builtins.pathExists (igloo.system.build.toplevel);
|
||||
appleBuilds = !pkgs.stdenvNoCC.isDarwin || builtins.pathExists (apple.system.build.toplevel);
|
||||
in
|
||||
{
|
||||
checks."igloo builds" = checkCond "igloo-builds" iglooBuilds;
|
||||
checks."apple builds" = checkCond "apple-builds" appleBuilds;
|
||||
checks."vm builds" = checkCond "vm-builds" vmBuilds;
|
||||
|
||||
checks."alice enabled igloo nh" = checkCond "alice.provides.igloo" igloo.programs.nh.enable;
|
||||
checks."igloo enabled alice helix" =
|
||||
checkCond "igloo.provides.alice" alice-at-igloo.programs.helix.enable;
|
||||
|
||||
checks."alice-custom-emacs" = checkCond "hm.programs.emacs.package" (
|
||||
"emacs-nox" == lib.getName alice-at-igloo.programs.emacs.package
|
||||
);
|
||||
};
|
||||
}
|
||||
22
flake/den/templates/default/modules/vm.nix
Normal file
22
flake/den/templates/default/modules/vm.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# enables `nix run .#vm`. it is very useful to have a VM
|
||||
# you can edit your config an launch the VM to test stuff
|
||||
# instead of having to reboot each time.
|
||||
{ inputs, eg, ... }:
|
||||
{
|
||||
|
||||
den.aspects.igloo.includes = [
|
||||
eg.vm._.gui
|
||||
# eg.vm._.tui
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
packages.vm = pkgs.writeShellApplication {
|
||||
name = "vm";
|
||||
text = ''
|
||||
${inputs.self.nixosConfigurations.igloo.config.system.build.vm}/bin/run-igloo-vm "$@"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
276
flake/den/templates/examples/flake.lock
generated
Normal file
276
flake/den/templates/examples/flake.lock
generated
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
{
|
||||
"nodes": {
|
||||
"darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762039661,
|
||||
"narHash": "sha256-oM5BwAGE78IBLZn+AqxwH/saqwq3e926rNq5HmOulkc=",
|
||||
"owner": "nix-darwin",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "c3c8c9f2a5ed43175ac4dc030308756620e6e4e4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-darwin",
|
||||
"repo": "nix-darwin",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"den": {
|
||||
"locked": {
|
||||
"lastModified": 1763285091,
|
||||
"narHash": "sha256-F2OsALSm86dfNA2grd5MVRPpAWZf4ZuuCzpYG7H0P9g=",
|
||||
"owner": "vic",
|
||||
"repo": "den",
|
||||
"rev": "227451c9a99fb084bc6b66878c7f6f3e75f625d2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "den",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-aspects": {
|
||||
"locked": {
|
||||
"lastModified": 1763284357,
|
||||
"narHash": "sha256-mPMHkhpOIsj2lg+KIcapFd4uj2N/9mZZ6RZBo/p5O1c=",
|
||||
"owner": "vic",
|
||||
"repo": "flake-aspects",
|
||||
"rev": "6a6d47f531ad57ac854cee689e84f2e28861ec49",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "flake-aspects",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-file": {
|
||||
"locked": {
|
||||
"lastModified": 1761535278,
|
||||
"narHash": "sha256-OPZ7XpG778i9CIJfchAwgrZGZ9z1dWJzfN18VFxCyS4=",
|
||||
"owner": "vic",
|
||||
"repo": "flake-file",
|
||||
"rev": "57b2a65831ae49e4f9218dbba1c2dc9700f6cd68",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "flake-file",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs-lib"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762040540,
|
||||
"narHash": "sha256-z5PlZ47j50VNF3R+IMS9LmzI5fYRGY/Z5O5tol1c9I4=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "0010412d62a25d959151790968765a70c436598b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1762087455,
|
||||
"narHash": "sha256-hpbPma1eUKwLAmiVRoMgIHbHiIKFkcACobJLbDt6ABw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "43e205606aeb253bfcee15fd8a4a01d8ce8384ca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager-stable": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs-stable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758463745,
|
||||
"narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"ref": "release-25.05",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"import-tree": {
|
||||
"locked": {
|
||||
"lastModified": 1761120675,
|
||||
"narHash": "sha256-TEbh9zISiQcU82VwVoEbmXHnSGlUxTwvjJA9g9ErSDA=",
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"rev": "a037ed2a58fc0ebed9e93b9ef79b0646e648f719",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "vic",
|
||||
"repo": "import-tree",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-auto-follow": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1754073254,
|
||||
"narHash": "sha256-CQp/v2HQ7AtGJQqFGRZLHt4MZAK3NF94I6GDaRyhbsc=",
|
||||
"owner": "fzakaria",
|
||||
"repo": "nix-auto-follow",
|
||||
"rev": "5baa00b79d4cc46523da0b8b3532c5163d151be4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "fzakaria",
|
||||
"repo": "nix-auto-follow",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixos-wsl": {
|
||||
"inputs": {
|
||||
"flake-compat": [],
|
||||
"nixpkgs": [
|
||||
"nixpkgs-stable"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1761969132,
|
||||
"narHash": "sha256-0me4+e+1VxNuvySSw0voqMCWU/eUmTuth7f4+Q2jbUY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-wsl",
|
||||
"rev": "761582d6ab431549fe1396d2cd681e3fe9376020",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-wsl",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1761880412,
|
||||
"narHash": "sha256-QoJjGd4NstnyOG4mm4KXF+weBzA2AH/7gn1Pmpfcb0A=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a7fc11be66bdfb5cdde611ee5ce381c183da8386",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-stable": {
|
||||
"locked": {
|
||||
"lastModified": 1762081535,
|
||||
"narHash": "sha256-+j+CUiaUoa87EhnSOqG5pwXdJWahP8vo6BE0ekssdzs=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2afc9d6e79b59ea9bcaf620d335623b0f7c2ce96",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "release-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"darwin": "darwin",
|
||||
"den": "den",
|
||||
"flake-aspects": "flake-aspects",
|
||||
"flake-file": "flake-file",
|
||||
"flake-parts": "flake-parts",
|
||||
"home-manager": "home-manager",
|
||||
"home-manager-stable": "home-manager-stable",
|
||||
"import-tree": "import-tree",
|
||||
"nix-auto-follow": "nix-auto-follow",
|
||||
"nixos-wsl": "nixos-wsl",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-stable": "nixpkgs-stable",
|
||||
"systems": "systems",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1761311587,
|
||||
"narHash": "sha256-Msq86cR5SjozQGCnC6H8C+0cD4rnx91BPltZ9KK613Y=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "2eddae033e4e74bf581c2d1dfa101f9033dbd2dc",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
93
flake/den/templates/examples/flake.nix
Normal file
93
flake/den/templates/examples/flake.nix
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
# DO-NOT-EDIT. This file was auto-generated using github:vic/flake-file.
|
||||
# Use `nix run .#write-flake` to regenerate it.
|
||||
{
|
||||
|
||||
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./modules);
|
||||
|
||||
inputs = {
|
||||
darwin = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:nix-darwin/nix-darwin";
|
||||
};
|
||||
den = {
|
||||
url = "github:vic/den";
|
||||
};
|
||||
flake-aspects = {
|
||||
url = "github:vic/flake-aspects";
|
||||
};
|
||||
flake-file = {
|
||||
url = "github:vic/flake-file";
|
||||
};
|
||||
flake-parts = {
|
||||
inputs = {
|
||||
nixpkgs-lib = {
|
||||
follows = "nixpkgs-lib";
|
||||
};
|
||||
};
|
||||
url = "github:hercules-ci/flake-parts";
|
||||
};
|
||||
home-manager = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:nix-community/home-manager";
|
||||
};
|
||||
home-manager-stable = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs-stable";
|
||||
};
|
||||
};
|
||||
url = "github:nix-community/home-manager/release-25.05";
|
||||
};
|
||||
import-tree = {
|
||||
url = "github:vic/import-tree";
|
||||
};
|
||||
nix-auto-follow = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:fzakaria/nix-auto-follow";
|
||||
};
|
||||
nixos-wsl = {
|
||||
inputs = {
|
||||
flake-compat = {
|
||||
follows = "";
|
||||
};
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs-stable";
|
||||
};
|
||||
};
|
||||
url = "github:nix-community/nixos-wsl";
|
||||
};
|
||||
nixpkgs = {
|
||||
url = "github:nixos/nixpkgs/nixpkgs-unstable";
|
||||
};
|
||||
nixpkgs-lib = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
nixpkgs-stable = {
|
||||
url = "github:nixos/nixpkgs/release-25.05";
|
||||
};
|
||||
systems = {
|
||||
url = "github:nix-systems/default";
|
||||
};
|
||||
treefmt-nix = {
|
||||
inputs = {
|
||||
nixpkgs = {
|
||||
follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
url = "github:numtide/treefmt-nix";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
5
flake/den/templates/examples/modules/_example/README.md
Normal file
5
flake/den/templates/examples/modules/_example/README.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
User TODO: REMOVE this directory (or disable its import from den.nix)
|
||||
|
||||
It is used to implement tests for all den features so we can validate at CI.
|
||||
|
||||
Use it as reference to see how den features are used, however, be aware that this might not be the best practices for file/aspect organization.
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# this is a non-dendritic darwin class module file.
|
||||
# automatically discovered by `den.import-tree` as enabled in auto-imports.nix
|
||||
{ ... }:
|
||||
{
|
||||
# see nix-darwin options.
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# this is a non-dendritic nix class module file.
|
||||
# automatically discovered by `den.import-tree` as enabled in auto-imports.nix
|
||||
#
|
||||
# USER TODO: Remove this file.
|
||||
# suppose this file was auto-generated by nixos-generate-config or some other hardware tooling.
|
||||
{ lib, ... }:
|
||||
{
|
||||
# used in CI to test this file was actually imported.
|
||||
options.auto-imported = lib.mkOption {
|
||||
readOnly = true;
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
};
|
||||
}
|
||||
27
flake/den/templates/examples/modules/_example/ci/builds.nix
Normal file
27
flake/den/templates/examples/modules/_example/ci/builds.nix
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Adds some checks for CI
|
||||
{
|
||||
perSystem =
|
||||
{
|
||||
pkgs,
|
||||
checkFile,
|
||||
rockhopper,
|
||||
honeycrisp,
|
||||
cam,
|
||||
bob,
|
||||
...
|
||||
}:
|
||||
let
|
||||
checks.x86_64-linux = {
|
||||
vm = checkFile "vm-builds" "${rockhopper.config.system.build.vm}/bin/run-rockhopper-vm";
|
||||
hosts-rockhopper = checkFile "nixos-builds" rockhopper.config.system.build.toplevel;
|
||||
homes-cam = checkFile "home-builds" cam.activation-script;
|
||||
};
|
||||
checks.aarch64-darwin = {
|
||||
hosts-honeycrisp = checkFile "darwin-builds" honeycrisp.config.system.build.toplevel;
|
||||
homes-bob = checkFile "darwin-home-builds" bob.activation-script;
|
||||
};
|
||||
in
|
||||
{
|
||||
checks = checks.${pkgs.system} or { };
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
# Including an static aspect should not cause duplicate definitions
|
||||
den.aspects.alice.includes = [
|
||||
{
|
||||
homeManager =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
programs.emacs.enable = true;
|
||||
programs.emacs.package = pkgs.emacs30-nox;
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
alice-at-rockhopper,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks.alice-custom-emacs = checkCond "set uniquely via a static includes" (
|
||||
let
|
||||
expr = lib.getName alice-at-rockhopper.programs.emacs.package;
|
||||
expected = "emacs-nox";
|
||||
in
|
||||
expr == expected
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
# A custom `nixos` class module that defines an option `names`.
|
||||
# Used to test that we are not duplicating values from owned configs.
|
||||
nixosNames = names: { options.${names} = lib.mkOption { type = lib.types.listOf lib.types.str; }; };
|
||||
in
|
||||
{
|
||||
den.default.nixos.imports = [ (nixosNames "people") ];
|
||||
den.default.includes = [
|
||||
(
|
||||
{ user, ... }:
|
||||
{
|
||||
nixos.people = [ user.name ];
|
||||
}
|
||||
)
|
||||
];
|
||||
|
||||
den.aspects.rockhopper.includes = [
|
||||
# Example: importing a third-party nixos module.
|
||||
{ nixos.imports = [ (nixosNames "names") ]; }
|
||||
];
|
||||
|
||||
den.aspects.rockhopper.nixos.names = [ "tux" ];
|
||||
|
||||
perSystem =
|
||||
{ checkCond, rockhopper, ... }:
|
||||
{
|
||||
checks.rockhopper-default-people = checkCond "set from den.default for each user" (
|
||||
rockhopper.config.people == [ "alice" ]
|
||||
);
|
||||
checks.rockhopper-names-single-entry = checkCond "custom nixos array option set once" (
|
||||
rockhopper.config.names == [ "tux" ]
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
{ den, ... }:
|
||||
{
|
||||
den.default.includes = [
|
||||
# Example: parametric over many contexts: { home }, { host, user }, { fromUser, toHost }
|
||||
den.provides.define-user
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
rockhopper,
|
||||
adelie,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
checks.alice-exists-on-rockhopper = checkCond "den.default.user.includes defines user on host" (
|
||||
rockhopper.config.users.users.alice.isNormalUser
|
||||
);
|
||||
checks.alice-not-exists-on-adelie = checkCond "den.default.user.includes defines user on host" (
|
||||
!adelie.config.users.users ? alice
|
||||
);
|
||||
checks.will-exists-on-adelie = checkCond "den.default.user.includes defines user on host" (
|
||||
adelie.config.users.users.will.isNormalUser
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
# Example: adelie host using github:nix-community/NixOS-WSL
|
||||
den.aspects.adelie.nixos = {
|
||||
imports = [ inputs.nixos-wsl.nixosModules.default ];
|
||||
wsl.enable = true;
|
||||
};
|
||||
}
|
||||
37
flake/den/templates/examples/modules/_example/ci/helpers.nix
Normal file
37
flake/den/templates/examples/modules/_example/ci/helpers.nix
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
{ self, ... }:
|
||||
{
|
||||
perSystem =
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
checkFile =
|
||||
name: file:
|
||||
pkgs.runCommandLocal name { } ''
|
||||
ls -la ${file} | tee $out
|
||||
'';
|
||||
|
||||
checkCond =
|
||||
name: cond:
|
||||
let
|
||||
code = if cond then "touch $out" else ''echo "Cond-Failed: ${name}"'';
|
||||
in
|
||||
pkgs.runCommandLocal name { } code;
|
||||
|
||||
rockhopper = self.nixosConfigurations.rockhopper;
|
||||
honeycrisp = self.darwinConfigurations.honeycrisp;
|
||||
adelie = self.wslConfigurations.adelie;
|
||||
cam = self.homeConfigurations.cam;
|
||||
bob = self.homeConfigurations.bob;
|
||||
luke = self.homeConfigurations.luke;
|
||||
|
||||
alice-at-rockhopper = rockhopper.config.home-manager.users.alice;
|
||||
alice-at-honeycrisp = honeycrisp.config.home-manager.users.alice;
|
||||
in
|
||||
{
|
||||
_module.args = {
|
||||
inherit checkCond checkFile;
|
||||
inherit rockhopper honeycrisp adelie;
|
||||
inherit cam bob luke;
|
||||
inherit alice-at-rockhopper alice-at-honeycrisp;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
|
||||
# Example: host provides static config to all its users hm.
|
||||
den.aspects.rockhopper.homeManager.programs.direnv.enable = true;
|
||||
|
||||
perSystem =
|
||||
{ checkCond, alice-at-rockhopper, ... }:
|
||||
{
|
||||
checks.host-contributes-to-user = checkCond "rockhopper contributes to all its users" (
|
||||
alice-at-rockhopper.programs.direnv.enable
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
# Example: configuration that depends on both host and user. provides only to HM.
|
||||
host-to-user-conditional =
|
||||
{
|
||||
user,
|
||||
host,
|
||||
...
|
||||
}:
|
||||
if user.userName == "alice" && !lib.hasSuffix "darwin" host.system then
|
||||
{
|
||||
homeManager.programs.git.enable = true;
|
||||
}
|
||||
else
|
||||
{ };
|
||||
in
|
||||
{
|
||||
|
||||
den.aspects.rockhopper.includes = [
|
||||
# Example: host provides parametric user configuration.
|
||||
host-to-user-conditional
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
alice-at-rockhopper,
|
||||
alice-at-honeycrisp,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
checks.alice-hm-git-enabled-on = checkCond "home-managed git for alice at rockhopper" (
|
||||
alice-at-rockhopper.programs.git.enable
|
||||
);
|
||||
checks.alice-hm-git-enabled-off = checkCond "home-managed git for alice at honeycrisp" (
|
||||
!alice-at-honeycrisp.programs.git.enable
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
# configures class-automatic module auto imports for hosts/users/homes.
|
||||
# See documentation at modules/aspects/provides/import-tree.nix
|
||||
{
|
||||
# deadnix: skip
|
||||
__findFile ? __findFile,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
# alice imports non-dendritic <class> modules from _non_dendritic/alice/_<class>/*.nix
|
||||
den.aspects.alice.includes = [ (<den/import-tree> ./_non_dendritic/alice) ];
|
||||
|
||||
# See the documentation at batteries/import-tree.nix
|
||||
den.default.includes = [
|
||||
(<den/import-tree/host> ./_non_dendritic/hosts)
|
||||
(<den/import-tree/user> ./_non_dendritic/users)
|
||||
(<den/import-tree/home> ./_non_dendritic/homes)
|
||||
];
|
||||
|
||||
# tests
|
||||
perSystem =
|
||||
{ checkCond, rockhopper, ... }:
|
||||
{
|
||||
checks.import-tree = checkCond "auto-imported from rockhopper/_nixos" (
|
||||
rockhopper.config.auto-imported
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{ inputs, den, ... }:
|
||||
{
|
||||
imports = [ (inputs.den.namespace "eg" false) ];
|
||||
_module.args.__findFile = den.lib.__findFile;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
let
|
||||
|
||||
# Example: adds hello into each user. provides only to OS.
|
||||
hello-package-for-user =
|
||||
{
|
||||
user,
|
||||
host,
|
||||
...
|
||||
}:
|
||||
{
|
||||
${host.class} =
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
users.users.${user.userName}.packages = [ pkgs.hello ];
|
||||
};
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
|
||||
den.default.includes = [ hello-package-for-user ];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
rockhopper,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks.alice-hello-enabled-by-default = checkCond "added hello at user packages" (
|
||||
let
|
||||
progs = rockhopper.config.users.users.alice.packages;
|
||||
expr = map lib.getName progs;
|
||||
expected = [ "hello" ];
|
||||
in
|
||||
expr == expected
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{ den, ... }:
|
||||
{
|
||||
den.aspects.alice.includes = [
|
||||
# alice is always admin in all its hosts
|
||||
den._.primary-user
|
||||
];
|
||||
|
||||
den.aspects.will.includes = [
|
||||
# will is primary user in WSL NixOS.
|
||||
den._.primary-user
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
honeycrisp,
|
||||
adelie,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks.alice-primary-on-macos = checkCond "den._.primary-user sets macos primary" (
|
||||
honeycrisp.config.system.primaryUser == "alice"
|
||||
);
|
||||
|
||||
checks.will-is-wsl-default = checkCond "wsl.defaultUser defined" (
|
||||
adelie.config.wsl.defaultUser == "will"
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
den.default.includes =
|
||||
let
|
||||
# Example: parametric host aspect to automatically set hostName on any host.
|
||||
set-host-name =
|
||||
{ host, ... }:
|
||||
{
|
||||
${host.class}.networking.hostName = host.name;
|
||||
};
|
||||
in
|
||||
[ set-host-name ];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
rockhopper,
|
||||
honeycrisp,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks.rockhopper-hostname = checkCond "den.default.host.includes sets hostName" (
|
||||
rockhopper.config.networking.hostName == "rockhopper"
|
||||
);
|
||||
|
||||
checks.honeycrisp-hostname = checkCond "den.default.host.includes sets hostName" (
|
||||
honeycrisp.config.networking.hostName == "honeycrisp"
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
let
|
||||
|
||||
# Example: luke standalone home-manager has access to rockhopper osConfig specialArg.
|
||||
os-conditional-hm =
|
||||
{ home, ... }:
|
||||
{
|
||||
# access osConfig, wired via extraSpecialArgs in homes.nix.
|
||||
homeManager =
|
||||
{ osConfig, ... }:
|
||||
{
|
||||
programs.bat.enable = osConfig.programs.${home.programToDependOn}.enable;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
# Example: standalone-hm config depends on osConfig (non-recursive)
|
||||
# NOTE: this will only work for standalone hm, and not for hosted hm
|
||||
# since a hosted hm configuration cannot depend on the os configuration.
|
||||
den.aspects.luke.includes = [
|
||||
os-conditional-hm
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{ checkCond, luke, ... }:
|
||||
{
|
||||
checks.luke-hm-depends-on-osConfig = checkCond "standalone hm can depend on osConfig" (
|
||||
luke.config.programs.bat.enable
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
# it is possible for top-level aspects directly under
|
||||
# den.aspects to take a context argument.
|
||||
{ den, lib, ... }:
|
||||
let
|
||||
# A module to test that toplevel had context.
|
||||
topLevel = name: {
|
||||
config.tops = name;
|
||||
options.tops = lib.mkOption { type = lib.types.str; };
|
||||
};
|
||||
in
|
||||
{
|
||||
|
||||
den.aspects.toplevel-user =
|
||||
{ user, ... }:
|
||||
{
|
||||
nixos.imports = [ (topLevel user.name) ];
|
||||
};
|
||||
|
||||
den.aspects.toplevel-host =
|
||||
{ host, ... }:
|
||||
{
|
||||
homeManager.imports = [ (topLevel host.name) ];
|
||||
};
|
||||
|
||||
den.aspects.alice.includes = [
|
||||
den.aspects.toplevel-host
|
||||
den.aspects.toplevel-user
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
alice-at-rockhopper,
|
||||
rockhopper,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks.alice-toplevel-user = checkCond "alice toplevel param aspect" (
|
||||
rockhopper.config.tops == "alice"
|
||||
);
|
||||
|
||||
checks.alice-toplevel-host = checkCond "alice toplevel param aspect" (
|
||||
alice-at-rockhopper.tops == "rockhopper"
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{ den, ... }:
|
||||
{
|
||||
# cam uses unfree vscode.
|
||||
den.aspects.cam.homeManager.programs.vscode.enable = true;
|
||||
den.aspects.cam.includes = [ (den._.unfree [ "vscode" ]) ];
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
# Example: user provides static config to all its nixos hosts.
|
||||
den.aspects.alice.nixos.users.users.alice.description = "Alice Q. User";
|
||||
|
||||
perSystem =
|
||||
{ checkCond, rockhopper, ... }:
|
||||
{
|
||||
checks.user-contributes-to-host = checkCond "alice.nixos sets on rockhopper host" (
|
||||
rockhopper.config.users.users.alice.description == "Alice Q. User"
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
# globally enable fish on all homes ever.
|
||||
den.default.homeManager.programs.fish.enable = true;
|
||||
|
||||
perSystem =
|
||||
{ checkCond, alice-at-rockhopper, ... }:
|
||||
{
|
||||
checks.alice-hm-fish-enabled-by-default = checkCond "home-managed fish for alice" (
|
||||
alice-at-rockhopper.programs.fish.enable
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
{ lib, ... }:
|
||||
let
|
||||
|
||||
# Example: configuration that depends on both host and user. provides anytime { user, host } is in context.
|
||||
user-to-host-conditional =
|
||||
{ user, host, ... }:
|
||||
if user.userName == "alice" && !lib.hasSuffix "darwin" host.system then
|
||||
{
|
||||
nixos.programs.tmux.enable = true;
|
||||
}
|
||||
else
|
||||
{ };
|
||||
in
|
||||
{
|
||||
|
||||
# Example: user provides parametric host configuration.
|
||||
den.aspects.alice.includes = [
|
||||
user-to-host-conditional
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{
|
||||
checkCond,
|
||||
rockhopper,
|
||||
honeycrisp,
|
||||
...
|
||||
}:
|
||||
{
|
||||
checks.alice-os-tmux-enabled-on = checkCond "os tmux for hosts having alice" (
|
||||
rockhopper.config.programs.tmux.enable
|
||||
);
|
||||
checks.alice-os-tmux-enabled-off = checkCond "os tmux for hosts having alice" (
|
||||
!honeycrisp.config.programs.tmux.enable
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{ den, lib, ... }:
|
||||
{
|
||||
|
||||
den.aspects.will.includes = [
|
||||
# will has always loved red snappers
|
||||
(den._.user-shell "fish")
|
||||
];
|
||||
|
||||
perSystem =
|
||||
{ checkCond, adelie, ... }:
|
||||
{
|
||||
checks.will-always-love-you = checkCond "red-snapper fish is default shell" (
|
||||
"fish" == lib.getName adelie.config.users.users.will.shell
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
# Example: enable helix for alice on all its home-managed hosts.
|
||||
den.aspects.alice.homeManager.programs.helix.enable = true;
|
||||
|
||||
perSystem =
|
||||
{ checkCond, alice-at-rockhopper, ... }:
|
||||
{
|
||||
checks.alice-hm-helix-enabled-by-user = checkCond "home-managed helix for alice" (
|
||||
alice-at-rockhopper.programs.helix.enable
|
||||
);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
let
|
||||
# Example: A static aspect for vm installers.
|
||||
vm-bootable = {
|
||||
nixos =
|
||||
{ modulesPath, ... }:
|
||||
{
|
||||
imports = [ (modulesPath + "/installer/cd-dvd/installation-cd-minimal.nix") ];
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
den.default.includes = [
|
||||
# Example: static aspect
|
||||
vm-bootable
|
||||
];
|
||||
}
|
||||
14
flake/den/templates/examples/modules/_example/defaults.nix
Normal file
14
flake/den/templates/examples/modules/_example/defaults.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
# User TODO: Remove this file.
|
||||
{
|
||||
# default aspect can be used for global static settings.
|
||||
den.default = {
|
||||
# static values.
|
||||
darwin.system.stateVersion = 6;
|
||||
nixos.system.stateVersion = "25.05";
|
||||
homeManager.home.stateVersion = "25.05";
|
||||
|
||||
# these defaults are set for checking with CI.
|
||||
nixos.programs.vim.enable = true;
|
||||
darwin.programs.zsh.enable = true;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
{ den, ... }:
|
||||
{
|
||||
# see batteries/home-manager.nix
|
||||
den.default.includes = [ den._.home-manager ];
|
||||
|
||||
# enable home-manager dependency.
|
||||
flake-file.inputs.home-manager = {
|
||||
url = "github:nix-community/home-manager";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
}
|
||||
31
flake/den/templates/examples/modules/_example/homes.nix
Normal file
31
flake/den/templates/examples/modules/_example/homes.nix
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# Example standalone home-manager configurations.
|
||||
# These are independent of any host configuration.
|
||||
# See documentation at <den>/nix/types.nix
|
||||
{ inputs, ... }:
|
||||
{
|
||||
den.homes.x86_64-linux.cam = { };
|
||||
|
||||
den.homes.aarch64-darwin.bob = {
|
||||
userName = "robert";
|
||||
aspect = "developer";
|
||||
};
|
||||
|
||||
# Example: custom home-manager instantiate for passing extraSpecialArgs.
|
||||
den.homes.x86_64-linux.luke =
|
||||
let
|
||||
osConfig = inputs.self.nixosConfigurations.rockhopper.config;
|
||||
in
|
||||
{
|
||||
# Example: luke standalone-homemanager needs access to rockhopper osConfig.
|
||||
instantiate =
|
||||
{ pkgs, modules }:
|
||||
inputs.home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs modules;
|
||||
extraSpecialArgs.osConfig = osConfig;
|
||||
};
|
||||
|
||||
# Example: custom attribute instead of specialArgs
|
||||
programToDependOn = "vim";
|
||||
};
|
||||
|
||||
}
|
||||
50
flake/den/templates/examples/modules/_example/hosts.nix
Normal file
50
flake/den/templates/examples/modules/_example/hosts.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# This is a fully working example configuration.
|
||||
# Feel free to remove it, adapt or split into several modules.
|
||||
# See documentation at <den>/nix/types.nix
|
||||
{ inputs, ... }:
|
||||
{
|
||||
den.hosts.aarch64-darwin.honeycrisp.users.alice = { };
|
||||
|
||||
den.hosts.aarch64-linux.emperor.users.alice = { };
|
||||
|
||||
den.hosts.x86_64-linux = {
|
||||
rockhopper = {
|
||||
description = "rockhopper is a kind of penguin";
|
||||
users.alice = { };
|
||||
};
|
||||
|
||||
adelie = {
|
||||
description = "wsl on windows";
|
||||
users.will = { };
|
||||
intoAttr = "wslConfigurations";
|
||||
# custom nixpkgs channel.
|
||||
instantiate = inputs.nixpkgs-stable.lib.nixosSystem;
|
||||
# custom attribute (see home-manager.nix)
|
||||
hm-module = inputs.home-manager-stable.nixosModules.home-manager;
|
||||
# custom attribute (see primary-user.nix)
|
||||
wsl = { };
|
||||
};
|
||||
};
|
||||
|
||||
# move these inputs to any module you want.
|
||||
# they are here for all our examples to work on CI.
|
||||
flake-file.inputs = {
|
||||
|
||||
# these stable inputs are for wsl
|
||||
nixpkgs-stable.url = "github:nixos/nixpkgs/release-25.05";
|
||||
home-manager-stable.url = "github:nix-community/home-manager/release-25.05";
|
||||
home-manager-stable.inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||
|
||||
nixos-wsl = {
|
||||
url = "github:nix-community/nixos-wsl";
|
||||
inputs.nixpkgs.follows = "nixpkgs-stable";
|
||||
inputs.flake-compat.follows = "";
|
||||
};
|
||||
|
||||
darwin = {
|
||||
url = "github:nix-darwin/nix-darwin";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
10
flake/den/templates/examples/modules/den.nix
Normal file
10
flake/den/templates/examples/modules/den.nix
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# USER TODO: remove this file.
|
||||
# copy any desired module to your ./modules and let it be auto-imported.
|
||||
{ inputs, ... }:
|
||||
{
|
||||
imports = [
|
||||
# The _example directory contains CI tests for all den features.
|
||||
# use it as reference of usage, but not of best practices.
|
||||
(inputs.import-tree ./_example)
|
||||
];
|
||||
}
|
||||
7
flake/den/templates/examples/modules/dendritic.nix
Normal file
7
flake/den/templates/examples/modules/dendritic.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{ inputs, lib, ... }:
|
||||
{
|
||||
flake-file.inputs.flake-file.url = lib.mkDefault "github:vic/flake-file";
|
||||
imports = [
|
||||
inputs.flake-file.flakeModules.dendritic
|
||||
];
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue