1
1
mirror of https://github.com/divnix/digga.git synced 2024-12-22 23:51:39 +03:00

tree: format all nix code with alejandra

This commit is contained in:
Parthiv Seetharaman 2022-04-20 21:14:31 -07:00
parent 2867f0e8e2
commit 41ac43c7e2
51 changed files with 1592 additions and 1507 deletions

View File

@ -1,39 +1,38 @@
{ system ? builtins.currentSystem
, inputs ? (import ../.).inputs
}:
let
{
system ? builtins.currentSystem,
inputs ? (import ../.).inputs,
}: let
inherit (inputs) digga nixpkgs;
lib = nixpkgs.lib // digga.lib;
pkgs = nixpkgs.legacyPackages.${system};
in
{
libTests = pkgs.runCommandNoCC "devos-lib-tests"
in {
libTests =
pkgs.runCommandNoCC "devos-lib-tests"
{
buildInputs = [
pkgs.nix
(
let tests = import ./lib { inherit pkgs lib; }; in
if tests == [ ] then null
else throw (builtins.toJSON tests)
let
tests = import ./lib {inherit pkgs lib;};
in
if tests == []
then null
else throw (builtins.toJSON tests)
)
];
} ''
datadir="${pkgs.nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_BUILD_HOOK=
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
nix-store --init
touch $out
'';
datadir="${pkgs.nix}/share"
export TEST_ROOT=$(pwd)/test-tmp
export NIX_BUILD_HOOK=
export NIX_CONF_DIR=$TEST_ROOT/etc
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export PAGER=cat
cacheDir=$TEST_ROOT/binary-cache
nix-store --init
touch $out
'';
}

View File

@ -1,23 +1,26 @@
{ pkgs, lib }:
{
pkgs,
lib,
}:
with lib;
lib.runTests {
testRakeLeaves = {
expr = rakeLeaves ./profiles;
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
t = {
bar = ./profiles/t/bar.nix;
lib.runTests {
testRakeLeaves = {
expr = rakeLeaves ./profiles;
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
t = {
bar = ./profiles/t/bar.nix;
};
};
};
};
testFlattenTree = {
expr = flattenTree (rakeLeaves ./profiles);
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
"t.bar" = ./profiles/t/bar.nix;
testFlattenTree = {
expr = flattenTree (rakeLeaves ./profiles);
expected = {
f = ./profiles/f.nix;
foo = ./profiles/foo;
"t.bar" = ./profiles/t/bar.nix;
};
};
};
}
}

View File

@ -1 +1 @@
{ }
{}

View File

@ -1 +1 @@
{ }
{}

View File

@ -1,18 +1,24 @@
let
inherit (import
inherit
(
let lock = builtins.fromJSON (builtins.readFile ./flake.lock); in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
import
(
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
)
{src = ./.;}
)
{ src = ./.; }
) defaultNix;
defaultNix
;
in
# Pass this flake as inputs.digga
defaultNix // {
inputs = defaultNix.inputs // { digga = defaultNix; };
shell = import ./devShell.nix { };
defaultNix
// {
inputs = defaultNix.inputs // {digga = defaultNix;};
shell = import ./devShell.nix {};
}

View File

@ -1,16 +1,20 @@
{ lib, flake-utils-plus, internal-modules, importers, nixosModules }:
{
lib,
flake-utils-plus,
internal-modules,
importers,
nixosModules,
}:
lib.warn ''
You are accessing a deprecated item of the digga lib.
Please update timely, it will be remove soon.
''
rec {
importModules =
lib.warn ''
Deprecated Function: lib.importModules.
Use lib.importExportableModules instead to set `exportedModules` option
''
importers.importExportableModules;
importers.importExportableModules;
}

View File

@ -1,12 +1,11 @@
{ system ? builtins.currentSystem
, inputs ? (import ./.).inputs
}:
let
{
system ? builtins.currentSystem,
inputs ? (import ./.).inputs,
}: let
pkgs = inputs.nixpkgs.legacyPackages.${system};
devshell = import inputs.devshell { inherit pkgs system; };
devshell = import inputs.devshell {inherit pkgs system;};
withCategory = category: attrset: attrset // { inherit category; };
withCategory = category: attrset: attrset // {inherit category;};
utils = withCategory "utils";
docs = withCategory "docs";
@ -30,120 +29,117 @@ let
&& cp result "$PRJ_ROOT/doc/api-reference-nixos.md" \
&& chmod 755 "$PRJ_ROOT//doc/api-reference-nixos.md"
'';
};
test = type: name: withCategory "tests" {
name = "check-${name}";
help = "Checks ${name} ${type}";
command = ''
set -e
# set -x
test = type: name:
withCategory "tests" {
name = "check-${name}";
help = "Checks ${name} ${type}";
command = ''
set -e
# set -x
diggaurl=
lockfile_updated=1
lockfile_present=1
tempdigga="\"path:$PRJ_ROOT\""
diggaurl=
lockfile_updated=1
lockfile_present=1
tempdigga="\"path:$PRJ_ROOT\""
cleanup() {
if is $lockfile_present; then
git checkout -- flake.lock
elif is $lockfile_updated; then
git rm -f flake.lock
fi
# ensure: restore input
[ -z $diggaurl ] || ${pkgs.gnused}/bin/sed -i "s|$tempdigga|$diggaurl|g" flake.nix
}
cleanup() {
if is $lockfile_present; then
git checkout -- flake.lock
elif is $lockfile_updated; then
git rm -f flake.lock
fi
# ensure: restore input
[ -z $diggaurl ] || ${pkgs.gnused}/bin/sed -i "s|$tempdigga|$diggaurl|g" flake.nix
}
digga_fixture() {
# ensure: replace input
diggaurl=$({ grep -o '"github:divnix/digga.*"' flake.nix || true; })
[ -z $diggaurl ] || ${pkgs.gnused}/bin/sed -i "s|$diggaurl|$tempdigga|g" flake.nix
}
digga_fixture() {
# ensure: replace input
diggaurl=$({ grep -o '"github:divnix/digga.*"' flake.nix || true; })
[ -z $diggaurl ] || ${pkgs.gnused}/bin/sed -i "s|$diggaurl|$tempdigga|g" flake.nix
}
trap_err() {
local ret=$?
cleanup
echo -e \
"\033[1m\033[31m""exit $ret: \033[0m\033[1m""command [$BASH_COMMAND] failed""\033[0m"
}
is () { [ "$1" -eq "0" ]; }
trap 'trap_err' ERR
# --------------------------------------------------------------------------------
cd $PRJ_ROOT/${type}/${name}
digga_fixture
test -f flake.lock && lockfile_present=$? || true
${pkgs.nixUnstable}/bin/nix flake lock --update-input digga "$@"; lockfile_updated=$?;
${pkgs.nixUnstable}/bin/nix flake show "$@"
${pkgs.nixUnstable}/bin/nix flake check "$@"
trap_err() {
local ret=$?
cleanup
echo -e \
"\033[1m\033[31m""exit $ret: \033[0m\033[1m""command [$BASH_COMMAND] failed""\033[0m"
}
is () { [ "$1" -eq "0" ]; }
trap 'trap_err' ERR
# --------------------------------------------------------------------------------
cd $PRJ_ROOT/${type}/${name}
digga_fixture
test -f flake.lock && lockfile_present=$? || true
${pkgs.nixUnstable}/bin/nix flake lock --update-input digga "$@"; lockfile_updated=$?;
${pkgs.nixUnstable}/bin/nix flake show "$@"
${pkgs.nixUnstable}/bin/nix flake check "$@"
cleanup
'';
};
'';
};
in
devshell.mkShell {
name = "digga";
packages = with pkgs; [
fd
alejandra
nixUnstable
];
devshell.mkShell {
name = "digga";
packages = with pkgs; [
fd
alejandra
nixUnstable
];
env = [
{
name = "NIX_CONFIG";
value =
''extra-experimental-features = nix-command flakes
extra-substituters = https://nrdxp.cachix.org https://nix-community.cachix.org
extra-trusted-public-keys = nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs='';
}
];
env = [
{
name = "NIX_CONFIG";
value = '' extra-experimental-features = nix-command flakes
extra-substituters = https://nrdxp.cachix.org https://nix-community.cachix.org
extra-trusted-public-keys = nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs='';
}
];
# tempfix: remove when merged https://github.com/numtide/devshell/pull/123
devshell.startup.load_profiles = pkgs.lib.mkForce (pkgs.lib.noDepEntry ''
# PATH is devshell's exorbitant privilige:
# fence against its pollution
_PATH=''${PATH}
# Load installed profiles
for file in "$DEVSHELL_DIR/etc/profile.d/"*.sh; do
# If that folder doesn't exist, bash loves to return the whole glob
[[ -f "$file" ]] && source "$file"
done
# Exert exorbitant privilige and leave no trace
export PATH=''${_PATH}
unset _PATH
'');
# tempfix: remove when merged https://github.com/numtide/devshell/pull/123
devshell.startup.load_profiles = pkgs.lib.mkForce (pkgs.lib.noDepEntry ''
# PATH is devshell's exorbitant privilige:
# fence against its pollution
_PATH=''${PATH}
# Load installed profiles
for file in "$DEVSHELL_DIR/etc/profile.d/"*.sh; do
# If that folder doesn't exist, bash loves to return the whole glob
[[ -f "$file" ]] && source "$file"
done
# Exert exorbitant privilige and leave no trace
export PATH=''${_PATH}
unset _PATH
'');
commands = [
(utils {
command = "git rm --ignore-unmatch -f $PRJ_ROOT/{tests,examples}/*/flake.lock";
help = "Remove all lock files";
name = "rm-locks";
})
(utils {
name = "fmt";
help = "Check Nix formatting";
command = "alejandra \${@} $PRJ_ROOT";
})
(utils {
name = "evalnix";
help = "Check Nix parsing";
command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null";
})
commands = [
(utils {
command = "git rm --ignore-unmatch -f $PRJ_ROOT/{tests,examples}/*/flake.lock";
help = "Remove all lock files";
name = "rm-locks";
})
(utils {
name = "fmt";
help = "Check Nix formatting";
command = "alejandra \${@} $PRJ_ROOT";
})
(utils {
name = "evalnix";
help = "Check Nix parsing";
command = "fd --extension nix --exec nix-instantiate --parse --quiet {} >/dev/null";
})
(test "examples" "devos")
(test "examples" "groupByConfig")
(test "examples" "hmOnly")
(test "examples" "all" // { command = "check-devos && check-groupByConfig && check-hmOnly"; })
(docs { package = pkgs.mdbook; })
(docs makeDocs)
];
}
(test "examples" "devos")
(test "examples" "groupByConfig")
(test "examples" "hmOnly")
(test "examples" "all" // {command = "check-devos && check-groupByConfig && check-hmOnly";})
(docs {package = pkgs.mdbook;})
(docs makeDocs)
];
}

View File

@ -9,23 +9,28 @@ let
"x86_64-linux"
];
filterSystems = lib.filterAttrs
filterSystems =
lib.filterAttrs
(system: _: lib.elem system ciSystems);
recurseIntoAttrsRecursive = lib.mapAttrs (_: v:
if lib.isAttrs v
then recurseIntoAttrsRecursive (lib.recurseIntoAttrs v)
else v
recurseIntoAttrsRecursive = lib.mapAttrs (
_: v:
if lib.isAttrs v
then recurseIntoAttrsRecursive (lib.recurseIntoAttrs v)
else v
);
systemOutputs = lib.filterAttrs
(name: set: lib.isAttrs set
&& lib.any
(system: set ? ${system} && name != "legacyPackages")
ciSystems
systemOutputs =
lib.filterAttrs
(
name: set:
lib.isAttrs set
&& lib.any
(system: set ? ${system} && name != "legacyPackages")
ciSystems
)
default.outputs;
ciDrvs = lib.mapAttrs (_: system: filterSystems system) systemOutputs;
in
(recurseIntoAttrsRecursive ciDrvs) // { shell = import ./shell.nix; }
(recurseIntoAttrsRecursive ciDrvs) // {shell = import ./shell.nix;}

View File

@ -5,138 +5,139 @@
nixConfig.extra-substituters = "https://nrdxp.cachix.org https://nix-community.cachix.org";
nixConfig.extra-trusted-public-keys = "nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
inputs =
{
# Track channels with commits tested and built by hydra
nixos.url = "github:nixos/nixpkgs/nixos-21.11";
latest.url = "github:nixos/nixpkgs/nixos-unstable";
inputs = {
# Track channels with commits tested and built by hydra
nixos.url = "github:nixos/nixpkgs/nixos-21.11";
latest.url = "github:nixos/nixpkgs/nixos-unstable";
digga.url = "github:divnix/digga";
digga.inputs.nixpkgs.follows = "nixos";
digga.inputs.nixlib.follows = "nixos";
digga.inputs.home-manager.follows = "home";
digga.inputs.deploy.follows = "deploy";
digga.url = "github:divnix/digga";
digga.inputs.nixpkgs.follows = "nixos";
digga.inputs.nixlib.follows = "nixos";
digga.inputs.home-manager.follows = "home";
digga.inputs.deploy.follows = "deploy";
bud.url = "github:divnix/bud";
bud.inputs.nixpkgs.follows = "nixos";
bud.inputs.devshell.follows = "digga/devshell";
bud.url = "github:divnix/bud";
bud.inputs.nixpkgs.follows = "nixos";
bud.inputs.devshell.follows = "digga/devshell";
home.url = "github:nix-community/home-manager/release-21.11";
home.inputs.nixpkgs.follows = "nixos";
home.url = "github:nix-community/home-manager/release-21.11";
home.inputs.nixpkgs.follows = "nixos";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixos";
darwin.url = "github:LnL7/nix-darwin";
darwin.inputs.nixpkgs.follows = "nixos";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixos";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixos";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixos";
agenix.url = "github:ryantm/agenix";
agenix.inputs.nixpkgs.follows = "nixos";
nvfetcher.url = "github:berberman/nvfetcher";
nvfetcher.inputs.nixpkgs.follows = "nixos";
nvfetcher.url = "github:berberman/nvfetcher";
nvfetcher.inputs.nixpkgs.follows = "nixos";
naersk.url = "github:nmattia/naersk";
naersk.inputs.nixpkgs.follows = "nixos";
naersk.url = "github:nmattia/naersk";
naersk.inputs.nixpkgs.follows = "nixos";
nixos-hardware.url = "github:nixos/nixos-hardware";
nixos-hardware.url = "github:nixos/nixos-hardware";
nixos-generators.url = "github:nix-community/nixos-generators";
};
nixos-generators.url = "github:nix-community/nixos-generators";
};
outputs =
{ self
, digga
, bud
, nixos
, home
, nixos-hardware
, nur
, agenix
, nvfetcher
, deploy
, ...
} @ inputs:
outputs = {
self,
digga,
bud,
nixos,
home,
nixos-hardware,
nur,
agenix,
nvfetcher,
deploy,
...
} @ inputs:
digga.lib.mkFlake
{
inherit self inputs;
{
inherit self inputs;
channelsConfig = { allowUnfree = true; };
channelsConfig = {allowUnfree = true;};
channels = {
nixos = {
imports = [ (digga.lib.importOverlays ./overlays) ];
overlays = [
nur.overlay
agenix.overlay
nvfetcher.overlay
./pkgs/default.nix
];
};
latest = { };
channels = {
nixos = {
imports = [(digga.lib.importOverlays ./overlays)];
overlays = [
nur.overlay
agenix.overlay
nvfetcher.overlay
./pkgs/default.nix
];
};
latest = {};
};
lib = import ./lib {lib = digga.lib // nixos.lib;};
sharedOverlays = [
(final: prev: {
__dontExport = true;
lib = prev.lib.extend (lfinal: lprev: {
our = self.lib;
});
})
];
nixos = {
hostDefaults = {
system = "x86_64-linux";
channelName = "nixos";
imports = [(digga.lib.importExportableModules ./modules)];
modules = [
{lib.our = self.lib;}
digga.nixosModules.bootstrapIso
digga.nixosModules.nixConfig
home.nixosModules.home-manager
agenix.nixosModules.age
bud.nixosModules.bud
];
};
lib = import ./lib { lib = digga.lib // nixos.lib; };
sharedOverlays = [
(final: prev: {
__dontExport = true;
lib = prev.lib.extend (lfinal: lprev: {
our = self.lib;
});
})
];
nixos = {
hostDefaults = {
system = "x86_64-linux";
channelName = "nixos";
imports = [ (digga.lib.importExportableModules ./modules) ];
modules = [
{ lib.our = self.lib; }
digga.nixosModules.bootstrapIso
digga.nixosModules.nixConfig
home.nixosModules.home-manager
agenix.nixosModules.age
bud.nixosModules.bud
];
};
imports = [ (digga.lib.importHosts ./hosts) ];
hosts = {
/* set host specific properties here */
NixOS = { };
};
importables = rec {
profiles = digga.lib.rakeLeaves ./profiles // {
imports = [(digga.lib.importHosts ./hosts)];
hosts = {
/*
set host specific properties here
*/
NixOS = {};
};
importables = rec {
profiles =
digga.lib.rakeLeaves ./profiles
// {
users = digga.lib.rakeLeaves ./users;
};
suites = with profiles; rec {
base = [ core users.nixos users.root ];
};
suites = with profiles; rec {
base = [core users.nixos users.root];
};
};
};
home = {
imports = [ (digga.lib.importExportableModules ./users/modules) ];
modules = [ ];
importables = rec {
profiles = digga.lib.rakeLeaves ./users/profiles;
suites = with profiles; rec {
base = [ direnv git ];
};
home = {
imports = [(digga.lib.importExportableModules ./users/modules)];
modules = [];
importables = rec {
profiles = digga.lib.rakeLeaves ./users/profiles;
suites = with profiles; rec {
base = [direnv git];
};
users = {
nixos = { suites, ... }: { imports = suites.base; };
}; # digga.lib.importers.rakeLeaves ./users/hm;
};
users = {
nixos = {suites, ...}: {imports = suites.base;};
}; # digga.lib.importers.rakeLeaves ./users/hm;
};
devshell = ./shell;
devshell = ./shell;
homeConfigurations = digga.lib.mkHomeConfigurations self.nixosConfigurations;
homeConfigurations = digga.lib.mkHomeConfigurations self.nixosConfigurations;
deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations { };
}
;
deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations {};
};
}

View File

@ -1,5 +1,4 @@
{ suites, ... }:
{
{suites, ...}: {
### root password is empty by default ###
imports = suites.base;
@ -8,5 +7,5 @@
networking.networkmanager.enable = true;
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };
fileSystems."/" = {device = "/dev/disk/by-label/nixos";};
}

View File

@ -1,5 +1,4 @@
{ profiles, ... }:
{
{profiles, ...}: {
# build with: `bud build bootstrap bootstrapIso`
# reachable on the local link via ssh root@fe80::47%eno1
# where 'eno1' is replaced by your own machine's network
@ -14,5 +13,5 @@
boot.loader.systemd-boot.enable = true;
# will be overridden by the bootstrapIso instrumentation
fileSystems."/" = { device = "/dev/disk/by-label/nixos"; };
fileSystems."/" = {device = "/dev/disk/by-label/nixos";};
}

View File

@ -1,6 +1,7 @@
let
rev = "e7e5d481a0e15dcd459396e55327749989e04ce0";
flake = (import
flake =
import
(
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${rev}.tar.gz";
@ -9,6 +10,6 @@ let
)
{
src = ../../.;
});
};
in
flake
flake

View File

@ -1,5 +1,4 @@
{ ... }:
let
{...}: let
inherit (default.inputs.nixos) lib;
host = configs.${hostname} or configs.NixOS;
@ -7,4 +6,4 @@ let
default = (import ../.).defaultNix;
hostname = lib.fileContents /etc/hostname;
in
host
host

View File

@ -1,2 +1,2 @@
{ lib }:
lib.makeExtensible (self: { })
{lib}:
lib.makeExtensible (self: {})

View File

@ -1,4 +1,4 @@
{ config, ... }: {
{config, ...}: {
home-manager.sharedModules = [
{
home.sessionVariables = {

View File

@ -1,4 +1,8 @@
{ channel, inputs, ... }: {
{
channel,
inputs,
...
}: {
nix.nixPath = [
"nixpkgs=${channel.input}"
"nixos-config=${../lib/compat/nixos}"

View File

@ -1,5 +1,5 @@
final: prev: {
manix = prev.manix.overrideAttrs (o: rec{
manix = prev.manix.overrideAttrs (o: rec {
inherit (prev.sources.manix) pname version src;
});
}

View File

@ -1,8 +1,8 @@
channels: final: prev: {
__dontExport = true; # overrides clutter up actual creations
inherit (channels.latest)
inherit
(channels.latest)
cachix
dhall
discord
@ -15,15 +15,17 @@ channels: final: prev: {
deploy-rs
;
haskellPackages = prev.haskellPackages.override
haskellPackages =
prev.haskellPackages.override
(old: {
overrides = prev.lib.composeExtensions (old.overrides or (_: _: { })) (hfinal: hprev:
let version = prev.lib.replaceChars [ "." ] [ "" ] prev.ghc.version;
in
{
# same for haskell packages, matching ghc versions
inherit (channels.latest.haskell.packages."ghc${version}")
haskell-language-server;
});
overrides = prev.lib.composeExtensions (old.overrides or (_: _: {})) (hfinal: hprev: let
version = prev.lib.replaceChars ["."] [""] prev.ghc.version;
in {
# same for haskell packages, matching ghc versions
inherit
(channels.latest.haskell.packages."ghc${version}")
haskell-language-server
;
});
});
}

View File

@ -1,6 +1,8 @@
# This file was generated by nvfetcher, please do not modify it manually.
{ fetchgit, fetchurl }:
{
fetchgit,
fetchurl,
}: {
manix = {
pname = "manix";
version = "d08e7ca185445b929f097f8bfb1243a8ef3e10e4";

View File

@ -1,5 +1,5 @@
final: prev: {
# keep sources this first
sources = prev.callPackage (import ./_sources/generated.nix) { };
sources = prev.callPackage (import ./_sources/generated.nix) {};
# then, call packages with `final.callPackage`
}

View File

@ -1,11 +1,13 @@
{ pkgs, lib, ... }:
let
{
pkgs,
lib,
...
}: let
folder = ./.;
toImport = name: value: folder + ("/" + name);
filterCaches = key: value: value == "regular" && lib.hasSuffix ".nix" key && key != "default.nix";
imports = lib.mapAttrsToList toImport (lib.filterAttrs filterCaches (builtins.readDir folder));
in
{
in {
inherit imports;
nix.binaryCaches = [ "https://cache.nixos.org/" ];
nix.binaryCaches = ["https://cache.nixos.org/"];
}

View File

@ -1,9 +1,14 @@
{ self, config, lib, pkgs, ... }:
let inherit (lib) fileContents;
in
{
self,
config,
lib,
pkgs,
...
}: let
inherit (lib) fileContents;
in {
# Sets nrdxp.cachix.org binary cache which just speeds up some builds
imports = [ ../cachix ];
imports = [../cachix];
# For rage encryption, all hosts need a ssh key pair
services.openssh = {
@ -12,10 +17,9 @@ in
};
# This is just a representation of the nix default
nix.systemFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ];
nix.systemFeatures = ["nixos-test" "benchmark" "big-parallel" "kvm"];
environment = {
# Selection of sysadmin tools that can come in handy
systemPackages = with pkgs; [
binutils
@ -51,79 +55,74 @@ in
}
'';
shellAliases =
let ifSudo = lib.mkIf config.security.sudo.enable;
in
{
# quick cd
".." = "cd ..";
"..." = "cd ../..";
"...." = "cd ../../..";
"....." = "cd ../../../..";
shellAliases = let
ifSudo = lib.mkIf config.security.sudo.enable;
in {
# quick cd
".." = "cd ..";
"..." = "cd ../..";
"...." = "cd ../../..";
"....." = "cd ../../../..";
# git
g = "git";
# git
g = "git";
# grep
grep = "rg";
gi = "grep -i";
# grep
grep = "rg";
gi = "grep -i";
# internet ip
myip = "dig +short myip.opendns.com @208.67.222.222 2>&1";
# internet ip
myip = "dig +short myip.opendns.com @208.67.222.222 2>&1";
# nix
n = "nix";
np = "n profile";
ni = "np install";
nr = "np remove";
ns = "n search --no-update-lock-file";
nf = "n flake";
nepl = "n repl '<nixpkgs>'";
srch = "ns nixos";
orch = "ns override";
nrb = ifSudo "sudo nixos-rebuild";
mn = ''
manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | sk --preview="manix '{}'" | xargs manix
'';
# nix
n = "nix";
np = "n profile";
ni = "np install";
nr = "np remove";
ns = "n search --no-update-lock-file";
nf = "n flake";
nepl = "n repl '<nixpkgs>'";
srch = "ns nixos";
orch = "ns override";
nrb = ifSudo "sudo nixos-rebuild";
mn = ''
manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | sk --preview="manix '{}'" | xargs manix
'';
# fix nixos-option
nixos-option = "nixos-option -I nixpkgs=${self}/lib/compat";
# fix nixos-option
nixos-option = "nixos-option -I nixpkgs=${self}/lib/compat";
# sudo
s = ifSudo "sudo -E ";
si = ifSudo "sudo -i";
se = ifSudo "sudoedit";
# sudo
s = ifSudo "sudo -E ";
si = ifSudo "sudo -i";
se = ifSudo "sudoedit";
# top
top = "btm";
# top
top = "btm";
# systemd
ctl = "systemctl";
stl = ifSudo "s systemctl";
utl = "systemctl --user";
ut = "systemctl --user start";
un = "systemctl --user stop";
up = ifSudo "s systemctl start";
dn = ifSudo "s systemctl stop";
jtl = "journalctl";
};
# systemd
ctl = "systemctl";
stl = ifSudo "s systemctl";
utl = "systemctl --user";
ut = "systemctl --user start";
un = "systemctl --user stop";
up = ifSudo "s systemctl start";
dn = ifSudo "s systemctl stop";
jtl = "journalctl";
};
};
fonts = {
fonts = with pkgs; [ powerline-fonts dejavu_fonts ];
fonts = with pkgs; [powerline-fonts dejavu_fonts];
fontconfig.defaultFonts = {
monospace = ["DejaVu Sans Mono for Powerline"];
monospace = [ "DejaVu Sans Mono for Powerline" ];
sansSerif = [ "DejaVu Sans" ];
sansSerif = ["DejaVu Sans"];
};
};
nix = {
# Improve nix store disk usage
autoOptimiseStore = true;
gc.automatic = true;
@ -133,7 +132,7 @@ in
useSandbox = true;
# give root and @wheel special privileges with nix
trustedUsers = [ "root" "@wheel" ];
trustedUsers = ["root" "@wheel"];
# Generally useful nix option defaults
extraOptions = ''
@ -142,7 +141,6 @@ in
keep-derivations = true
fallback = true
'';
};
programs.bash = {
@ -158,5 +156,4 @@ in
# Service that makes Out of Memory Killer more effective
services.earlyoom.enable = true;
}

View File

@ -2,8 +2,7 @@ let
# set ssh public keys here for your system and user
system = "";
user = "";
allKeys = [ system user ];
in
{
allKeys = [system user];
in {
"secret.age".publicKeys = allKeys;
}

View File

@ -1,5 +1,8 @@
{ self, inputs, ... }:
{
self,
inputs,
...
}: {
modules = with inputs; [
bud.devshellModules.bud
];
@ -7,4 +10,3 @@
./devos.nix
];
}

View File

@ -1,19 +1,20 @@
{ pkgs, extraModulesPath, inputs, ... }:
let
{
pkgs,
extraModulesPath,
inputs,
...
}: let
hooks = import ./hooks;
pkgWithCategory = category: package: { inherit package category; };
pkgWithCategory = category: package: {inherit package category;};
linter = pkgWithCategory "linter";
docs = pkgWithCategory "docs";
devos = pkgWithCategory "devos";
in
{
in {
_file = toString ./.;
imports = [ "${extraModulesPath}/git/hooks.nix" ];
git = { inherit hooks; };
imports = ["${extraModulesPath}/git/hooks.nix"];
git = {inherit hooks;};
# tempfix: remove when merged https://github.com/numtide/devshell/pull/123
devshell.startup.load_profiles = pkgs.lib.mkForce (pkgs.lib.noDepEntry ''
@ -30,26 +31,26 @@ in
unset _PATH
'');
commands = with pkgs; [
(devos nixUnstable)
(devos agenix)
{
category = "devos";
name = pkgs.nvfetcher-bin.pname;
help = pkgs.nvfetcher-bin.meta.description;
command = "cd $PRJ_ROOT/pkgs; ${pkgs.nvfetcher-bin}/bin/nvfetcher -c ./sources.toml $@";
}
(linter alejandra)
(linter editorconfig-checker)
# (docs python3Packages.grip) too many deps
(docs mdbook)
(devos inputs.deploy.packages.${pkgs.system}.deploy-rs)
]
++ lib.optional
commands = with pkgs;
[
(devos nixUnstable)
(devos agenix)
{
category = "devos";
name = pkgs.nvfetcher-bin.pname;
help = pkgs.nvfetcher-bin.meta.description;
command = "cd $PRJ_ROOT/pkgs; ${pkgs.nvfetcher-bin}/bin/nvfetcher -c ./sources.toml $@";
}
(linter alejandra)
(linter editorconfig-checker)
# (docs python3Packages.grip) too many deps
(docs mdbook)
(devos inputs.deploy.packages.${pkgs.system}.deploy-rs)
]
++ lib.optional
(system != "i686-linux")
(devos cachix)
++ lib.optional
++ lib.optional
(system != "aarch64-darwin")
(devos inputs.nixos-generators.defaultPackage.${pkgs.system})
;
(devos inputs.nixos-generators.defaultPackage.${pkgs.system});
}

View File

@ -1,11 +1,10 @@
{ hmUsers, ... }:
{
home-manager.users = { inherit (hmUsers) nixos; };
{hmUsers, ...}: {
home-manager.users = {inherit (hmUsers) nixos;};
users.users.nixos = {
password = "nixos";
description = "default";
isNormalUser = true;
extraGroups = [ "wheel" ];
extraGroups = ["wheel"];
};
}

View File

@ -30,12 +30,9 @@
h1rd = "hard HEAD~1";
# logging
lg =
"log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog =
"log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog =
"log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
rank = "shortlog -sn --no-merges";
# delete merged branches

View File

@ -1,4 +1,4 @@
{ ... }:
{...}:
# recommend using `hashedPassword`
{
users.users.root.password = "";

View File

@ -1,4 +1,3 @@
{ self, ... }:
{
exportedModules = [ ./python.toml ];
{self, ...}: {
exportedModules = [./python.toml];
}

View File

@ -1,29 +1,31 @@
{
description = "A DevOS example. And also a digga test bed.";
inputs =
{
# Track channels with commits tested and built by hydra
nixos.url = "github:nixos/nixpkgs/nixos-21.11";
inputs = {
# Track channels with commits tested and built by hydra
nixos.url = "github:nixos/nixpkgs/nixos-21.11";
digga = {
url = "github:divnix/digga";
inputs.nixpkgs.follows = "nixos";
};
home.url = "github:nix-community/home-manager";
home.inputs.nixpkgs.follows = "nixos";
digga = {
url = "github:divnix/digga";
inputs.nixpkgs.follows = "nixos";
};
home.url = "github:nix-community/home-manager";
home.inputs.nixpkgs.follows = "nixos";
};
outputs = inputs @ { self, nixos, digga, home }:
outputs = inputs @ {
self,
nixos,
digga,
home,
}:
digga.lib.mkFlake {
inherit self inputs;
channels.nixos = { };
channels.nixos = {};
nixos = ./nixos;
home = ./home;
devshell = ./devshell;
};
}

View File

@ -1,7 +1,5 @@
{ self, ... }:
let
{self, ...}: let
lib = self.inputs.digga.lib;
in
{
imports = [ (lib.importExportableModules ./modules) ];
in {
imports = [(lib.importExportableModules ./modules)];
}

View File

@ -30,12 +30,9 @@
h1rd = "hard HEAD~1";
# logging
lg =
"log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog =
"log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog =
"log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
lg = "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit";
plog = "log --graph --pretty='format:%C(red)%d%C(reset) %C(yellow)%h%C(reset) %ar %C(green)%aN%C(reset) %s'";
tlog = "log --stat --since='1 Day Ago' --graph --pretty=oneline --abbrev-commit --date=relative";
rank = "shortlog -sn --no-merges";
# delete merged branches

View File

@ -1,6 +1,11 @@
{ lib, pkgs, config, ... }: {
{
lib,
pkgs,
config,
...
}: {
boot.loader.systemd-boot.enable = true;
boot.loader.efi.canTouchEfiVariables = true;
fileSystems."/" = { device = "/dev/disk/by-label/One"; };
fileSystems."/" = {device = "/dev/disk/by-label/One";};
users.users.root.password = "";
}

View File

@ -1,16 +1,18 @@
{ self, inputs, ... }:
let
inherit (inputs.digga.lib) allProfilesTest;
in
{
self,
inputs,
...
}: let
inherit (inputs.digga.lib) allProfilesTest;
in {
hostDefaults.channelName = "nixos";
hosts = {
Morty.modules = [ ./Morty.nix ];
Morty.tests = [ allProfilesTest ];
Morty.modules = [./Morty.nix];
Morty.tests = [allProfilesTest];
};
importables = rec {
suites = rec {
base = [ ];
base = [];
};
};
}

View File

@ -1,26 +1,28 @@
{
description = "A DevOS example. And also a digga test bed.";
inputs =
{
nixos.url = "github:nixos/nixpkgs/nixos-21.11";
digga.url = "github:divnix/digga";
digga.inputs.nixpkgs.follows = "nixos";
digga.inputs.home-manager.follows = "home";
home.url = "github:nix-community/home-manager/release-21.11";
home.inputs.nixpkgs.follows = "nixos";
};
inputs = {
nixos.url = "github:nixos/nixpkgs/nixos-21.11";
digga.url = "github:divnix/digga";
digga.inputs.nixpkgs.follows = "nixos";
digga.inputs.home-manager.follows = "home";
home.url = "github:nix-community/home-manager/release-21.11";
home.inputs.nixpkgs.follows = "nixos";
};
outputs = inputs @ { self, nixos, digga, home }:
outputs = inputs @ {
self,
nixos,
digga,
home,
}:
digga.lib.mkFlake {
inherit self inputs;
channels.nixos = { };
channels.nixos = {};
nixos.hostDefaults.channelName = "nixos";
home = ./home;
};
}

View File

@ -1,14 +1,16 @@
{ self, inputs, ... }:
let
lib = inputs.digga.lib;
in
{
imports = [ (lib.importExportableModules ./modules) ];
modules = [ ];
self,
inputs,
...
}: let
lib = inputs.digga.lib;
in {
imports = [(lib.importExportableModules ./modules)];
modules = [];
importables = rec {
profiles = lib.rakeLeaves ./profiles;
suites = with profiles; {
shell = with shell; [ direnv ];
shell = with shell; [direnv];
};
};
users = lib.rakeLeaves ./users;

View File

@ -1,12 +1,14 @@
{ pkgs, suites, ... }:
let
{
pkgs,
suites,
...
}: let
name = "Test User";
email = "test@example.com";
in
{
in {
imports = suites.shell;
home.packages = [ pkgs.hello ];
home.packages = [pkgs.hello];
programs.browserpass.enable = true;
programs.starship.enable = true;
@ -15,4 +17,3 @@ in
userEmail = email;
};
}

207
flake.nix
View File

@ -5,129 +5,124 @@
nixConfig.extra-substituters = "https://nrdxp.cachix.org https://nix-community.cachix.org";
nixConfig.extra-trusted-public-keys = "nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4= nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=";
inputs =
{
# Track channels with commits tested and built by hydra
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
inputs = {
# Track channels with commits tested and built by hydra
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixlib.url = "github:nix-community/nixpkgs.lib";
blank.url = "github:divnix/blank";
nixlib.url = "github:nix-community/nixpkgs.lib";
blank.url = "github:divnix/blank";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixpkgs";
deploy.url = "github:serokell/deploy-rs";
deploy.inputs.nixpkgs.follows = "nixpkgs";
home-manager.url = "github:nix-community/home-manager/release-21.11";
home-manager.inputs.nixpkgs.follows = "nixlib";
home-manager.url = "github:nix-community/home-manager/release-21.11";
home-manager.inputs.nixpkgs.follows = "nixlib";
devshell.url = "github:numtide/devshell";
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus";
devshell.url = "github:numtide/devshell";
flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
};
outputs = {
self,
nixlib,
nixpkgs,
deploy,
devshell,
flake-utils-plus,
home-manager,
...
} @ inputs: let
tests = import ./src/tests.nix {inherit (nixlib) lib;};
internal-modules = import ./src/modules.nix {
inherit (nixlib) lib;
};
outputs =
{ self
, nixlib
, nixpkgs
, deploy
, devshell
, flake-utils-plus
, home-manager
, ...
}@inputs:
let
importers = import ./src/importers.nix {
inherit (nixlib) lib;
};
tests = import ./src/tests.nix { inherit (nixlib) lib; };
generators = import ./src/generators.nix {
inherit (nixlib) lib;
inherit deploy;
};
internal-modules = import ./src/modules.nix {
mkFlake = let
mkFlake' = import ./src/mkFlake {
inherit (nixlib) lib;
inherit (flake-utils-plus.inputs) flake-utils;
inherit deploy devshell home-manager flake-utils-plus internal-modules tests;
};
in {
__functor = _: args: (mkFlake' args).flake;
options = args: (mkFlake' args).options;
};
importers = import ./src/importers.nix {
inherit (nixlib) lib;
};
# Unofficial Flakes Roadmap - Polyfills
# This project is committed to the Unofficial Flakes Roadmap!
# .. see: https://demo.hedgedoc.org/s/_W6Ve03GK#
generators = import ./src/generators.nix {
inherit (nixlib) lib;
inherit deploy;
};
# Super Stupid Flakes (ssf) / System As an Input - Style:
supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin"];
mkFlake =
let
mkFlake' = import ./src/mkFlake {
inherit (nixlib) lib;
inherit (flake-utils-plus.inputs) flake-utils;
inherit deploy devshell home-manager flake-utils-plus internal-modules tests;
};
in
{
__functor = _: args: (mkFlake' args).flake;
options = args: (mkFlake' args).options;
};
# Unofficial Flakes Roadmap - Polyfills
# This project is committed to the Unofficial Flakes Roadmap!
# .. see: https://demo.hedgedoc.org/s/_W6Ve03GK#
# Super Stupid Flakes (ssf) / System As an Input - Style:
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];
# Pass this flake(self) as "digga"
polyfillInputs = self.inputs // { digga = self; };
polyfillOutput = loc: nixlib.lib.genAttrs supportedSystems (system:
import loc { inherit system; inputs = polyfillInputs; }
# Pass this flake(self) as "digga"
polyfillInputs = self.inputs // {digga = self;};
polyfillOutput = loc:
nixlib.lib.genAttrs supportedSystems (
system:
import loc {
inherit system;
inputs = polyfillInputs;
}
);
# .. we hope you like this style.
# .. it's adopted by a growing number of projects.
# Please consider adopting it if you want to help to improve flakes.
# .. we hope you like this style.
# .. it's adopted by a growing number of projects.
# Please consider adopting it if you want to help to improve flakes.
# DEPRECATED - will be removed timely
deprecated = import ./deprecated.nix {
inherit (nixlib) lib;
inherit (self) nixosModules;
inherit flake-utils-plus internal-modules importers;
};
in {
# what you came for ...
lib = {
inherit (flake-utils-plus.inputs.flake-utils.lib) defaultSystems eachSystem eachDefaultSystem filterPackages;
inherit (flake-utils-plus.lib) exportModules exportOverlays exportPackages;
inherit mkFlake;
inherit (tests) mkTest allProfilesTest;
inherit (importers) flattenTree rakeLeaves importOverlays importExportableModules importHosts;
inherit (generators) mkDeployNodes mkHomeConfigurations;
# DEPRECATED - will be removed timely
deprecated = import ./deprecated.nix {
inherit (nixlib) lib;
inherit (self) nixosModules;
inherit flake-utils-plus internal-modules importers;
};
in
{
# what you came for ...
lib = {
inherit (flake-utils-plus.inputs.flake-utils.lib) defaultSystems eachSystem eachDefaultSystem filterPackages;
inherit (flake-utils-plus.lib) exportModules exportOverlays exportPackages;
inherit mkFlake;
inherit (tests) mkTest allProfilesTest;
inherit (importers) flattenTree rakeLeaves importOverlays importExportableModules importHosts;
inherit (generators) mkDeployNodes mkHomeConfigurations;
# DEPRECATED - will be removed soon
inherit (deprecated)
# Place any deprecated lib functions here
;
};
# a little extra service ...
overlays = import ./overlays { inherit inputs; };
nixosModules = import ./modules;
defaultTemplate = self.templates.devos;
templates.devos.path = ./examples/devos;
templates.devos.description = ''
an awesome template for NixOS users, with consideration for common tools like home-manager, devshell, and more.
'';
# digga-local use
formatter = nixlib.lib.genAttrs supportedSystems (s: nixpkgs.legacyPackages.${s}.alejandra);
# system-space and pass sytem and input to each file
jobs = polyfillOutput ./jobs;
checks = polyfillOutput ./checks;
devShell = polyfillOutput ./devShell.nix;
# DEPRECATED - will be removed soon
inherit
(deprecated)
# Place any deprecated lib functions here
;
};
# a little extra service ...
overlays = import ./overlays {inherit inputs;};
nixosModules = import ./modules;
defaultTemplate = self.templates.devos;
templates.devos.path = ./examples/devos;
templates.devos.description = ''
an awesome template for NixOS users, with consideration for common tools like home-manager, devshell, and more.
'';
# digga-local use
formatter = nixlib.lib.genAttrs supportedSystems (s: nixpkgs.legacyPackages.${s}.alejandra);
# system-space and pass sytem and input to each file
jobs = polyfillOutput ./jobs;
checks = polyfillOutput ./checks;
devShell = polyfillOutput ./devShell.nix;
};
}

View File

@ -1,13 +1,15 @@
{ system ? builtins.currentSystem
, inputs ? (import ../.).inputs
}:
let
{
system ? builtins.currentSystem,
inputs ? (import ../.).inputs,
}: let
inherit (inputs) digga;
pkgs = inputs.nixpkgs.legacyPackages.${system};
docOptions = digga.lib.mkFlake.options { self = { }; inputs = { }; };
evaledOptions = (pkgs.lib.evalModules { modules = [ docOptions ]; }).options;
docOptions = digga.lib.mkFlake.options {
self = {};
inputs = {};
};
evaledOptions = (pkgs.lib.evalModules {modules = [docOptions];}).options;
mkDocPartMd = part: title: intro:
pkgs.writeText "api-reference-${part}.md" ''
@ -15,13 +17,11 @@ let
${intro}
${(
pkgs.nixosOptionsDoc { options = evaledOptions.${part}; }
).optionsMDDoc}
pkgs.nixosOptionsDoc {options = evaledOptions.${part};}
)
.optionsMDDoc}
'';
in
{
in {
mkApiReferenceTopLevel = pkgs.writeText "api-reference.md" ''
# Top Level API
`digga`'s top level API. API Containers are documented in their respective sub-chapter:
@ -31,17 +31,19 @@ in
- [Devshell](./api-reference-devshell.md)
- [NixOS](./api-reference-nixos.md)
${( pkgs.nixosOptionsDoc {
${(pkgs.nixosOptionsDoc {
options = {
inherit (evaledOptions)
inherit
(evaledOptions)
channelsConfig
self
inputs
outputsBuilder
supportedSystems
;
;
};
}).optionsMDDoc}
})
.optionsMDDoc}
'';
mkApiReferenceChannels = mkDocPartMd "channels" "Channels API Container" ''
@ -60,5 +62,4 @@ in
mkApiReferenceNixos = mkDocPartMd "nixos" "NixOS API Container" ''
Configure your nixos modules, profiles & suites.
'';
}

View File

@ -1,29 +1,39 @@
let
getFqdn = config:
let
net = config.networking;
fqdn =
if net.domain != null
then "${net.hostName}.${net.domain}"
else net.hostName;
in
getFqdn = config: let
net = config.networking;
fqdn =
if net.domain != null
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
protoModule = fullHostConfig: { config, lib, modulesPath, suites, self, inputs, ... }@args: {
imports = [ "${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix" ];
protoModule = fullHostConfig: {
config,
lib,
modulesPath,
suites,
self,
inputs,
...
} @ args: {
imports = ["${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"];
isoImage.isoBaseName = "bootstrap-" + (getFqdn config);
isoImage.contents = [{
source = self;
target = "/devos/";
}];
isoImage.storeContents = [
self.devShell.${config.nixpkgs.system}
# include also closures that are "switched off" by the
# above profile filter on the local config attribute
fullHostConfig.system.build.toplevel
] ++ builtins.attrValues inputs;
isoImage.contents = [
{
source = self;
target = "/devos/";
}
];
isoImage.storeContents =
[
self.devShell.${config.nixpkgs.system}
# include also closures that are "switched off" by the
# above profile filter on the local config attribute
fullHostConfig.system.build.toplevel
]
++ builtins.attrValues inputs;
# still pull in tools of deactivated profiles
environment.systemPackages = fullHostConfig.environment.systemPackages;
@ -63,12 +73,16 @@ let
};
};
in
{ config, ... }:
{
system.build = {
bootstrapIso = (config.lib.digga.mkBuild
(protoModule config)
).config.system.build.isoImage;
};
}
{config, ...}: {
system.build = {
bootstrapIso =
(
config.lib.digga.mkBuild
(protoModule config)
)
.config
.system
.build
.isoImage;
};
}

View File

@ -1,6 +1,4 @@
{ lib, ... }:
let
{lib, ...}: let
experimental-features = [
"flakes"
"nix-command"
@ -13,16 +11,14 @@ let
"nrdxp.cachix.org-1:Fc5PSqY2Jm1TrWfm88l6cvGWwz3s93c6IOifQWnhNW4="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
in
{
in {
# package and option is from fup
nix.generateRegistryFromInputs = lib.mkDefault true;
# missing merge semantics in this option force us to use extra-* for now
nix.extraOptions = ''
extra-experimental-features = ${lib.concatStringsSep " " experimental-features }
extra-substituters = ${lib.concatStringsSep " " substituters }
extra-trusted-public-keys = ${lib.concatStringsSep " " trusted-public-keys }
extra-experimental-features = ${lib.concatStringsSep " " experimental-features}
extra-substituters = ${lib.concatStringsSep " " substituters}
extra-trusted-public-keys = ${lib.concatStringsSep " " trusted-public-keys}
'';
}

View File

@ -1,3 +1,2 @@
{ inputs }: {
{inputs}: {
}

View File

@ -1 +1 @@
import ./devShell.nix { }
import ./devShell.nix {}

View File

@ -1,74 +1,75 @@
{ lib, deploy }:
let
getFqdn = c:
let
net = c.config.networking;
fqdn =
if net.domain != null
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
in
{
lib,
deploy,
}: let
getFqdn = c: let
net = c.config.networking;
fqdn =
if net.domain != null
then "${net.hostName}.${net.domain}"
else net.hostName;
in
fqdn;
in {
mkHomeConfigurations = nixosConfigurations:
/**
Synopsis: mkHomeConfigurations _nixosConfigurations_
Generate the `homeConfigurations` attribute expected by
`home-manager` cli from _nixosConfigurations_ in the form
_user@hostname_.
**/
let
op = attrs: c:
attrs
//
(
lib.mapAttrs'
(user: v: {
name = "${user}@${getFqdn c}";
value = v.home;
})
c.config.home-manager.users
)
;
mkHmConfigs = lib.foldl op { };
in
/*
*
Synopsis: mkHomeConfigurations _nixosConfigurations_
Generate the `homeConfigurations` attribute expected by
`home-manager` cli from _nixosConfigurations_ in the form
_user@hostname_.
*
*/
let
op = attrs: c:
attrs
// (
lib.mapAttrs'
(user: v: {
name = "${user}@${getFqdn c}";
value = v.home;
})
c.config.home-manager.users
);
mkHmConfigs = lib.foldl op {};
in
mkHmConfigs (builtins.attrValues nixosConfigurations);
mkDeployNodes = hosts: extraConfig:
/**
Synopsis: mkNodes _nixosConfigurations_
Generate the `nodes` attribute expected by deploy-rs
where _nixosConfigurations_ are `nodes`.
Example input:
```
{
hostname-1 = {
fastConnection = true;
sshOpts = [ "-p" "25" ];
};
hostname-2 = {
sshOpts = [ "-p" "19999" ];
sshUser = "root";
};
}
```
**/
/*
*
Synopsis: mkNodes _nixosConfigurations_
Generate the `nodes` attribute expected by deploy-rs
where _nixosConfigurations_ are `nodes`.
Example input:
```
{
hostname-1 = {
fastConnection = true;
sshOpts = [ "-p" "25" ];
};
hostname-2 = {
sshOpts = [ "-p" "19999" ];
sshUser = "root";
};
}
```
*
*/
lib.recursiveUpdate
(lib.mapAttrs
(_: c:
{
hostname = getFqdn c;
profiles.system = {
user = "root";
path = deploy.lib.${c.config.nixpkgs.system}.activate.nixos c;
};
}
)
hosts)
extraConfig;
(lib.mapAttrs
(
_: c: {
hostname = getFqdn c;
profiles.system = {
user = "root";
path = deploy.lib.${c.config.nixpkgs.system}.activate.nixos c;
};
}
)
hosts)
extraConfig;
}

View File

@ -1,108 +1,108 @@
{ lib }:
let
{lib}: let
flattenTree =
/**
Synopsis: flattenTree _tree_
Flattens a _tree_ of the shape that is produced by rakeLeaves.
Output Format:
An attrset with names in the spirit of the Reverse DNS Notation form
that fully preserve information about grouping from nesting.
Example input:
```
{
a = {
b = {
c = <path>;
};
};
}
```
Example output:
```
{
"a.b.c" = <path>;
}
```
**/
tree:
let
op = sum: path: val:
let
pathStr = builtins.concatStringsSep "." path; # dot-based reverse DNS notation
in
if builtins.isPath val then
# builtins.trace "${toString val} is a path"
(sum // {
"${pathStr}" = val;
})
else if builtins.isAttrs val then
# builtins.trace "${builtins.toJSON val} is an attrset"
# recurse into that attribute set
/*
*
Synopsis: flattenTree _tree_
Flattens a _tree_ of the shape that is produced by rakeLeaves.
Output Format:
An attrset with names in the spirit of the Reverse DNS Notation form
that fully preserve information about grouping from nesting.
Example input:
```
{
a = {
b = {
c = <path>;
};
};
}
```
Example output:
```
{
"a.b.c" = <path>;
}
```
*
*/
tree: let
op = sum: path: val: let
pathStr = builtins.concatStringsSep "." path; # dot-based reverse DNS notation
in
if builtins.isPath val
then
# builtins.trace "${toString val} is a path"
(sum
// {
"${pathStr}" = val;
})
else if builtins.isAttrs val
then
# builtins.trace "${builtins.toJSON val} is an attrset"
# recurse into that attribute set
(recurse sum path val)
else
# ignore that value
# builtins.trace "${toString path} is something else"
sum
;
# ignore that value
# builtins.trace "${toString path} is something else"
sum;
recurse = sum: path: val:
builtins.foldl'
(sum: key: op sum (path ++ [ key ]) val.${key})
sum
(builtins.attrNames val)
;
(sum: key: op sum (path ++ [key]) val.${key})
sum
(builtins.attrNames val);
in
recurse { } [ ] tree;
recurse {} [] tree;
rakeLeaves =
/**
Synopsis: rakeLeaves _path_
Recursively collect the nix files of _path_ into attrs.
Output Format:
An attribute set where all `.nix` files and directories with `default.nix` in them
are mapped to keys that are either the file with .nix stripped or the folder name.
All other directories are recursed further into nested attribute sets with the same format.
Example file structure:
```
./core/default.nix
./base.nix
./main/dev.nix
./main/os/default.nix
```
Example output:
```
{
core = ./core;
base = base.nix;
main = {
dev = ./main/dev.nix;
os = ./main/os;
};
}
```
**/
dirPath:
let
/*
*
Synopsis: rakeLeaves _path_
Recursively collect the nix files of _path_ into attrs.
Output Format:
An attribute set where all `.nix` files and directories with `default.nix` in them
are mapped to keys that are either the file with .nix stripped or the folder name.
All other directories are recursed further into nested attribute sets with the same format.
Example file structure:
```
./core/default.nix
./base.nix
./main/dev.nix
./main/os/default.nix
```
Example output:
```
{
core = ./core;
base = base.nix;
main = {
dev = ./main/dev.nix;
os = ./main/os;
};
}
```
*
*/
dirPath: let
seive = file: type:
# Only rake `.nix` files or directories
(type == "regular" && lib.hasSuffix ".nix" file) || (type == "directory")
;
# Only rake `.nix` files or directories
(type == "regular" && lib.hasSuffix ".nix" file) || (type == "directory");
collect = file: type: {
name = lib.removeSuffix ".nix" file;
value =
let
path = dirPath + "/${file}";
in
if (type == "regular")
value = let
path = dirPath + "/${file}";
in
if
(type == "regular")
|| (type == "directory" && builtins.pathExists (path + "/default.nix"))
then path
# recurse on directories that don't contain a `default.nix`
@ -111,34 +111,28 @@ let
files = lib.filterAttrs seive (builtins.readDir dirPath);
in
lib.filterAttrs (n: v: v != { }) (lib.mapAttrs' collect files);
in
{
lib.filterAttrs (n: v: v != {}) (lib.mapAttrs' collect files);
in {
inherit rakeLeaves flattenTree;
importOverlays = dir:
{
# Meant to output a module that sets the overlays option
# overlays order matters. mkAfter ensures those in-house
# overlays are loaded later (after external ones), so the latter
# can be modified via internal overlays
overlays = lib.mkAfter (builtins.attrValues (flattenTree (rakeLeaves dir)));
};
importOverlays = dir: {
# Meant to output a module that sets the overlays option
# overlays order matters. mkAfter ensures those in-house
# overlays are loaded later (after external ones), so the latter
# can be modified via internal overlays
overlays = lib.mkAfter (builtins.attrValues (flattenTree (rakeLeaves dir)));
};
importExportableModules = dir:
{
# Meant to output a module that sets the modules option
exportedModules = builtins.attrValues (flattenTree (rakeLeaves dir));
};
importHosts = dir:
{
# Meant to output a module that sets the hosts option (including constructed host names)
hosts = lib.mapAttrs
(n: v: { modules = [ v ]; })
(flattenTree (rakeLeaves dir));
};
importExportableModules = dir: {
# Meant to output a module that sets the modules option
exportedModules = builtins.attrValues (flattenTree (rakeLeaves dir));
};
importHosts = dir: {
# Meant to output a module that sets the hosts option (including constructed host names)
hosts =
lib.mapAttrs
(n: v: {modules = [v];})
(flattenTree (rakeLeaves dir));
};
}

View File

@ -1,28 +1,34 @@
{ lib, deploy, devshell, home-manager, flake-utils-plus, flake-utils, internal-modules, tests } @ injectedDeps:
{ self, inputs, ... } @ args:
let
{
lib,
deploy,
devshell,
home-manager,
flake-utils-plus,
flake-utils,
internal-modules,
tests,
} @ injectedDeps: {
self,
inputs,
...
} @ args: let
# avoid infinite recursions w.r.t. using self or inputs in imports
injectedDeps' = injectedDeps // { inherit self inputs; };
injectedDeps' = injectedDeps // {inherit self inputs;};
options' = import ./options.nix injectedDeps';
fupAdapter' = import ./fup-adapter.nix injectedDeps';
defaultOutputsBuilder' = import ./outputs-builder.nix injectedDeps';
evaled = lib.evalModules { modules = [ args options' ]; };
evaled = lib.evalModules {modules = [args options'];};
defaultOutputsBuilder = defaultOutputsBuilder' evaled.config;
extraArgs = removeAttrs args (builtins.attrNames evaled.options);
in
{
in {
flake = fupAdapter' {
inherit (evaled) config;
inherit extraArgs defaultOutputsBuilder;
};
options = options';
}

View File

@ -1,17 +1,19 @@
# constructor dependencies
{ lib, self, inputs, flake-utils-plus, internal-modules, ... }:
{
lib,
self,
inputs,
flake-utils-plus,
internal-modules,
...
}: {
# evaluated digga configuration
config
config,
# extra arguments that are passed down to fup
, extraArgs
extraArgs,
# pass a custom default fup outputs builder
, defaultOutputsBuilder
}:
let
defaultOutputsBuilder,
}: let
sharedOverlays = [
(final: prev: {
__dontExport = true;
@ -24,59 +26,72 @@ let
defaultHostModules = [
(internal-modules.hmNixosDefaults {
specialArgs = config.home.importables // { inherit self inputs; };
specialArgs = config.home.importables // {inherit self inputs;};
modules = config.home.modules ++ config.home.exportedModules;
})
(internal-modules.globalDefaults {
hmUsers = config.home.users;
})
({ ... }@args: {
lib.specialArgs = args.specialArgs or (builtins.trace ''
WARNING: specialArgs is not accessibly by the module system which means you
are likely using NixOS 20.09. Profiles testing and custom builds (ex: iso)
are not supported in 20.09 and using them could result in infinite
recursion errors. It is recommended to update to 21.05 to use either feature.
''
{ });
({...} @ args: {
lib.specialArgs =
args.specialArgs
or (builtins.trace ''
WARNING: specialArgs is not accessibly by the module system which means you
are likely using NixOS 20.09. Profiles testing and custom builds (ex: iso)
are not supported in 20.09 and using them could result in infinite
recursion errors. It is recommended to update to 21.05 to use either feature.
''
{});
})
];
unifyOverlays = channels: map (o: if builtins.isFunction (o null null) then o channels else o);
unifyOverlays = channels:
map (o:
if builtins.isFunction (o null null)
then o channels
else o);
stripChannel = channel: removeAttrs channel [
# arguments in our channels api that shouldn't be passed to fup
"overlays"
];
stripChannel = channel:
removeAttrs channel [
# arguments in our channels api that shouldn't be passed to fup
"overlays"
];
# evalArgs sets channelName and system to null by default
# but for proper default handling in fup, null args have to be removed
stripHost = args: removeAttrs (lib.filterAttrs (_: arg: arg != null) args) [
# arguments in our hosts/hostDefaults api that shouldn't be passed to fup
"externalModules" # TODO: remove deprecated option
"exportedModules"
"tests"
];
stripHost = args:
removeAttrs (lib.filterAttrs (_: arg: arg != null) args) [
# arguments in our hosts/hostDefaults api that shouldn't be passed to fup
"externalModules" # TODO: remove deprecated option
"exportedModules"
"tests"
];
diggaFupArgs = {
inherit (config)
inherit
(config)
channelsConfig
supportedSystems;
supportedSystems
;
inherit self inputs sharedOverlays;
hosts = builtins.mapAttrs (_: stripHost) config.nixos.hosts;
channels = builtins.mapAttrs
(name: channel:
stripChannel (channel // {
# pass channels if "overlay" has three arguments
overlaysBuilder = channels: unifyOverlays channels channel.overlays;
})
channels =
builtins.mapAttrs
(
name: channel:
stripChannel (channel
// {
# pass channels if "overlay" has three arguments
overlaysBuilder = channels: unifyOverlays channels channel.overlays;
})
)
config.channels;
hostDefaults = flake-utils-plus.lib.mergeAny (stripHost config.nixos.hostDefaults) {
# add `self` & `inputs` as specialargs so their libs can be used in imports
specialArgs = config.nixos.importables // { inherit self inputs; };
specialArgs = config.nixos.importables // {inherit self inputs;};
modules = config.nixos.hostDefaults.exportedModules ++ defaultHostModules;
};
@ -96,13 +111,11 @@ let
outputsBuilder = channels:
flake-utils-plus.lib.mergeAny (defaultOutputsBuilder channels) (config.outputsBuilder channels);
};
in
flake-utils-plus.lib.mkFlake
flake-utils-plus.lib.mkFlake
(
flake-utils-plus.lib.mergeAny
diggaFupArgs
extraArgs # for overlays list order
diggaFupArgs
extraArgs # for overlays list order
)

View File

@ -1,452 +1,485 @@
# constructor dependencies
{ lib, devshell, flake-utils, self, inputs, ... }:
with lib;
{ config, ... }:
let
cfg = config;
# #############
# Resolver
# #############
/**
Synopsis: maybeImport <path|string or obj>
Returns an imported path or string or the object otherwise.
Use when you want to allow specifying an object directly or a path to it.
It saves the end user the additional import statement.
**/
maybeImport = obj:
if (builtins.isPath obj || builtins.isString obj) then
import obj
else obj
;
/**
Synopsis: maybeImportDevshellToml <path|string or obj>
Returns an imported path or string if the filename ends in `toml` or the object or path otherwise.
Use only for devshell modules, as an apply function.
**/
maybeImportDevshellToml = obj:
if ((builtins.isPath obj || builtins.isString obj) && lib.hasSuffix ".toml" obj) then
devshell.lib.importTOML obj
else obj
;
/**
Synopsis: pathToOr <type>
Type resolver: types maybeImport's <obj>.
Use in type declarations.
**/
pathToOr = elemType: with types; coercedTo path maybeImport elemType;
/**
Synopsis: coercedListOf <type>
Type resolver & list flattner: flattens a (evtl. arbitrarily nested) list of type <type>.
Use in type declarations.
**/
coercedListOf = elemType: with types;
coercedTo anything (x: flatten (singleton x)) (listOf elemType);
# #############
# Custom Types
# #############
nixosTestType = pathToOr (mkOptionType {
name = "test";
check = x: builtins.isFunction x || builtins.isAttrs x;
description = "valid NixOS test";
});
moduleType = mkOptionType {
name = "module";
inherit (types.submodule { }) check;
description = "valid module";
};
devshellModuleType = with types; coercedTo path maybeImportDevshellToml moduleType;
overlayType = pathToOr (mkOptionType {
name = "overlay";
check = builtins.isFunction;
description = "valid Nixpkgs overlay";
});
systemType = (types.enum config.supportedSystems) // {
description = "system defined in `supportedSystems`";
};
channelType = (types.enum (builtins.attrNames config.channels)) // {
description = "channel defined in `channels`";
};
flakeType = with types; (addCheck attrs lib.isStorePath) // {
description = "nix flake";
};
userType = with types; pathToOr moduleType // {
description = "HM user config";
};
overlaysType = with types; coercedListOf overlayType;
modulesType = with types; coercedListOf moduleType;
nixosTestsType = with types; coercedListOf nixosTestType;
devshellModulesType = with types; coercedListOf devshellModuleType;
legacyProfilesType = with types; listOf path;
legacySuitesType = with types; functionTo attrs;
suitesType = with types; attrsOf (coercedListOf path);
usersType = with types; attrsOf userType;
inputsType = with types; attrsOf flakeType;
# #############
# Options
# #############
systemOpt = {
system = mkOption {
type = with types; nullOr systemType;
default = null;
description = ''
system for this host
'';
};
};
channelNameOpt = required: {
channelName = mkOption
{
description = ''
Channel this host should follow
'';
}
//
(
if required then {
type = with types; channelType;
} else {
type = with types; nullOr channelType;
default = null;
}
);
};
nixosTestOpt = {
tests = mkOption {
type = with types; nixosTestsType;
default = [ ];
description = ''
tests to run
'';
example = literalExample ''
[
{
name = "testname1";
machine = { ... };
testScript = '''
# ...
''';
}
({ corutils, writers, ... }: {
name = "testname2";
machine = { ... };
testScript = '''
# ...
''';
})
./path/to/test.nix
];
'';
};
};
modulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [ ];
description = ''
modules to include
'';
};
};
exportedModulesOpt' = name: {
type = with types; pathToOr modulesType;
default = [ ];
description = ''
modules to include in all hosts and export to ${name}Modules output
'';
};
exportedModulesOpt = name: { exportedModules = mkOption (exportedModulesOpt' name); };
exportedDevshellModulesOpt = {
exportedModules = mkOption (
(exportedModulesOpt' "devshell") // {
type = with types; devshellModulesType;
}
);
};
# This is only needed for hostDefaults
# modules in each host don't get exported
regularModulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [ ];
description = ''
modules to include that won't be exported
meant importing modules from external flakes
'';
};
};
externalModulesDeprecationMessage = ''
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
'';
legacyExternalModulesMod = { config, options, ... }: {
options = {
externalModules = mkOption {
type = with types; modulesType;
default = [ ];
description = externalModulesDeprecationMessage;
};
};
config = mkIf (config.externalModules != [ ]) {
modules = throw ''
ERROR: ${externalModulesDeprecationMessage}
'';
};
};
hostDefaultsOpt = name: {
hostDefaults = mkOption {
type = with types; hostDefaultsType name;
default = { };
description = ''
Defaults for all hosts.
the modules passed under hostDefaults will be exported
to the '${name}Modules' flake output.
They will also be added to all hosts.
'';
};
};
hostsOpt = name: {
hosts = mkOption {
type = with types; hostType;
default = { };
description = ''
configurations to include in the ${name}Configurations output
'';
};
};
inputOpt = name: {
input = mkOption {
type = flakeType;
default = self.inputs.${name};
defaultText = "self.inputs.<name>";
description = ''
nixpkgs flake input to use for this channel
'';
};
};
overlaysOpt = {
overlays = mkOption {
type = with types; pathToOr overlaysType;
default = [ ];
description = escape [ "<" ">" ] ''
overlays to apply to this channel
these will get exported under the 'overlays' flake output
as <channel>/<name> and any overlay pulled from ''\${inputs}
will be filtered out
'';
};
};
patchesOpt = {
patches = mkOption {
type = with types; listOf path;
default = [ ];
description = ''
patches to apply to this channel
'';
};
};
configOpt = {
config = mkOption {
type = with types; pathToOr attrs;
default = { };
apply = lib.recursiveUpdate cfg.channelsConfig;
description = ''
nixpkgs config for this channel
'';
};
};
importablesOpt = {
importables = mkOption {
type = with types; submoduleWith {
modules = [{
freeformType = attrs;
options = {
suites = mkOption {
type = nullOr (pathToOr suitesType);
default = null;
description = ''
collections of profiles
'';
};
};
}];
};
default = { };
description = ''
Packages of paths to be passed to modules as `specialArgs`.
'';
};
};
usersOpt = {
users = mkOption {
type = with types; usersType;
default = { };
description = ''
HM users that can be deployed portably without a host.
'';
};
};
# #############
# Aggreagate types
# #############
hostType = with types; attrsOf (submoduleWith {
modules = [
# per-host modules not exported, no external modules
{ options = systemOpt // (channelNameOpt false) // modulesOpt // nixosTestOpt; }
];
});
hostDefaultsType = name: with types; submoduleWith {
modules = [
{ options = systemOpt // (channelNameOpt true) // regularModulesOpt // (exportedModulesOpt name); }
legacyExternalModulesMod
];
};
nixosType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = (hostsOpt "nixos") // (hostDefaultsOpt "nixos") // importablesOpt; }
];
};
homeType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = regularModulesOpt // (exportedModulesOpt "home") // importablesOpt // usersOpt; }
legacyExternalModulesMod
];
};
devshellType = with types; submoduleWith {
specialArgs = { inherit self inputs; };
modules = [
{ options = regularModulesOpt // exportedDevshellModulesOpt; }
legacyExternalModulesMod
];
};
channelsType = with types; attrsOf (submoduleWith {
modules = [
({ name, ... }: { options = overlaysOpt // configOpt // (inputOpt name) // patchesOpt; })
];
});
outputsBuilderType = with types; functionTo attrs;
in
{
# this does not get propagated to submodules
# to allow passing flake outputs directly to mkFlake
config._module.check = false;
lib,
devshell,
flake-utils,
self,
inputs,
...
}:
with lib;
{config, ...}: let
cfg = config;
options = with types; {
self = mkOption {
type = flakeType;
readOnly = true;
description = "The flake to create the DevOS outputs for";
# #############
# Resolver
# #############
/*
*
Synopsis: maybeImport <path|string or obj>
Returns an imported path or string or the object otherwise.
Use when you want to allow specifying an object directly or a path to it.
It saves the end user the additional import statement.
*
*/
maybeImport = obj:
if (builtins.isPath obj || builtins.isString obj)
then import obj
else obj;
/*
*
Synopsis: maybeImportDevshellToml <path|string or obj>
Returns an imported path or string if the filename ends in `toml` or the object or path otherwise.
Use only for devshell modules, as an apply function.
*
*/
maybeImportDevshellToml = obj:
if ((builtins.isPath obj || builtins.isString obj) && lib.hasSuffix ".toml" obj)
then devshell.lib.importTOML obj
else obj;
/*
*
Synopsis: pathToOr <type>
Type resolver: types maybeImport's <obj>.
Use in type declarations.
*
*/
pathToOr = elemType: with types; coercedTo path maybeImport elemType;
/*
*
Synopsis: coercedListOf <type>
Type resolver & list flattner: flattens a (evtl. arbitrarily nested) list of type <type>.
Use in type declarations.
*
*/
coercedListOf = elemType:
with types;
coercedTo anything (x: flatten (singleton x)) (listOf elemType);
# #############
# Custom Types
# #############
nixosTestType = pathToOr (mkOptionType {
name = "test";
check = x: builtins.isFunction x || builtins.isAttrs x;
description = "valid NixOS test";
});
moduleType = mkOptionType {
name = "module";
inherit (types.submodule {}) check;
description = "valid module";
};
inputs = mkOption {
type = inputsType;
readOnly = true;
description = "The flake's inputs";
devshellModuleType = with types; coercedTo path maybeImportDevshellToml moduleType;
overlayType = pathToOr (mkOptionType {
name = "overlay";
check = builtins.isFunction;
description = "valid Nixpkgs overlay";
});
systemType =
(types.enum config.supportedSystems)
// {
description = "system defined in `supportedSystems`";
};
channelType =
(types.enum (builtins.attrNames config.channels))
// {
description = "channel defined in `channels`";
};
flakeType = with types;
(addCheck attrs lib.isStorePath)
// {
description = "nix flake";
};
userType = with types;
pathToOr moduleType
// {
description = "HM user config";
};
overlaysType = with types; coercedListOf overlayType;
modulesType = with types; coercedListOf moduleType;
nixosTestsType = with types; coercedListOf nixosTestType;
devshellModulesType = with types; coercedListOf devshellModuleType;
legacyProfilesType = with types; listOf path;
legacySuitesType = with types; functionTo attrs;
suitesType = with types; attrsOf (coercedListOf path);
usersType = with types; attrsOf userType;
inputsType = with types; attrsOf flakeType;
# #############
# Options
# #############
systemOpt = {
system = mkOption {
type = with types; nullOr systemType;
default = null;
description = ''
system for this host
'';
};
};
supportedSystems = mkOption {
type = listOf str;
default = flake-utils.lib.defaultSystems;
channelNameOpt = required: {
channelName =
mkOption
{
description = ''
Channel this host should follow
'';
}
// (
if required
then {
type = with types; channelType;
}
else {
type = with types; nullOr channelType;
default = null;
}
);
};
nixosTestOpt = {
tests = mkOption {
type = with types; nixosTestsType;
default = [];
description = ''
tests to run
'';
example = literalExample ''
[
{
name = "testname1";
machine = { ... };
testScript = '''
# ...
''';
}
({ corutils, writers, ... }: {
name = "testname2";
machine = { ... };
testScript = '''
# ...
''';
})
./path/to/test.nix
];
'';
};
};
modulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [];
description = ''
modules to include
'';
};
};
exportedModulesOpt' = name: {
type = with types; pathToOr modulesType;
default = [];
description = ''
The systems supported by this flake
modules to include in all hosts and export to ${name}Modules output
'';
};
channelsConfig = mkOption {
type = pathToOr attrs;
default = { };
description = ''
nixpkgs config for all channels
'';
exportedModulesOpt = name: {exportedModules = mkOption (exportedModulesOpt' name);};
exportedDevshellModulesOpt = {
exportedModules = mkOption (
(exportedModulesOpt' "devshell")
// {
type = with types; devshellModulesType;
}
);
};
channels = mkOption {
type = pathToOr channelsType;
default = { };
description = ''
nixpkgs channels to create
'';
# This is only needed for hostDefaults
# modules in each host don't get exported
regularModulesOpt = {
modules = mkOption {
type = with types; pathToOr modulesType;
default = [];
description = ''
modules to include that won't be exported
meant importing modules from external flakes
'';
};
};
outputsBuilder = mkOption {
type = pathToOr outputsBuilderType;
default = channels: { };
defaultText = "channels: { }";
description = ''
builder for flake system-spaced outputs
The builder gets passed an attrset of all channels
'';
externalModulesDeprecationMessage = ''
The `externalModules` option has been removed.
Any modules that should be exported should be defined with the `exportedModules`
option and all other modules should just go into the `modules` option.
'';
legacyExternalModulesMod = {
config,
options,
...
}: {
options = {
externalModules = mkOption {
type = with types; modulesType;
default = [];
description = externalModulesDeprecationMessage;
};
};
config = mkIf (config.externalModules != []) {
modules = throw ''
ERROR: ${externalModulesDeprecationMessage}
'';
};
};
nixos = mkOption {
type = pathToOr nixosType;
default = { };
description = ''
hosts, modules, suites, and profiles for NixOS
'';
hostDefaultsOpt = name: {
hostDefaults = mkOption {
type = with types; hostDefaultsType name;
default = {};
description = ''
Defaults for all hosts.
the modules passed under hostDefaults will be exported
to the '${name}Modules' flake output.
They will also be added to all hosts.
'';
};
};
home = mkOption {
type = pathToOr homeType;
default = { };
description = ''
hosts, modules, suites, and profiles for home-manager
'';
hostsOpt = name: {
hosts = mkOption {
type = with types; hostType;
default = {};
description = ''
configurations to include in the ${name}Configurations output
'';
};
};
devshell = mkOption {
type = pathToOr devshellType;
default = { };
description = ''
Modules to include in your DevOS shell. the `modules` argument
will be exported under the `devshellModules` output
'';
inputOpt = name: {
input = mkOption {
type = flakeType;
default = self.inputs.${name};
defaultText = "self.inputs.<name>";
description = ''
nixpkgs flake input to use for this channel
'';
};
};
};
}
overlaysOpt = {
overlays = mkOption {
type = with types; pathToOr overlaysType;
default = [];
description = escape ["<" ">"] ''
overlays to apply to this channel
these will get exported under the 'overlays' flake output
as <channel>/<name> and any overlay pulled from ''\${inputs}
will be filtered out
'';
};
};
patchesOpt = {
patches = mkOption {
type = with types; listOf path;
default = [];
description = ''
patches to apply to this channel
'';
};
};
configOpt = {
config = mkOption {
type = with types; pathToOr attrs;
default = {};
apply = lib.recursiveUpdate cfg.channelsConfig;
description = ''
nixpkgs config for this channel
'';
};
};
importablesOpt = {
importables = mkOption {
type = with types;
submoduleWith {
modules = [
{
freeformType = attrs;
options = {
suites = mkOption {
type = nullOr (pathToOr suitesType);
default = null;
description = ''
collections of profiles
'';
};
};
}
];
};
default = {};
description = ''
Packages of paths to be passed to modules as `specialArgs`.
'';
};
};
usersOpt = {
users = mkOption {
type = with types; usersType;
default = {};
description = ''
HM users that can be deployed portably without a host.
'';
};
};
# #############
# Aggreagate types
# #############
hostType = with types;
attrsOf (submoduleWith {
modules = [
# per-host modules not exported, no external modules
{options = systemOpt // (channelNameOpt false) // modulesOpt // nixosTestOpt;}
];
});
hostDefaultsType = name:
with types;
submoduleWith {
modules = [
{options = systemOpt // (channelNameOpt true) // regularModulesOpt // (exportedModulesOpt name);}
legacyExternalModulesMod
];
};
nixosType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = (hostsOpt "nixos") // (hostDefaultsOpt "nixos") // importablesOpt;}
];
};
homeType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = regularModulesOpt // (exportedModulesOpt "home") // importablesOpt // usersOpt;}
legacyExternalModulesMod
];
};
devshellType = with types;
submoduleWith {
specialArgs = {inherit self inputs;};
modules = [
{options = regularModulesOpt // exportedDevshellModulesOpt;}
legacyExternalModulesMod
];
};
channelsType = with types;
attrsOf (submoduleWith {
modules = [
({name, ...}: {options = overlaysOpt // configOpt // (inputOpt name) // patchesOpt;})
];
});
outputsBuilderType = with types; functionTo attrs;
in {
# this does not get propagated to submodules
# to allow passing flake outputs directly to mkFlake
config._module.check = false;
options = with types; {
self = mkOption {
type = flakeType;
readOnly = true;
description = "The flake to create the DevOS outputs for";
};
inputs = mkOption {
type = inputsType;
readOnly = true;
description = "The flake's inputs";
};
supportedSystems = mkOption {
type = listOf str;
default = flake-utils.lib.defaultSystems;
description = ''
The systems supported by this flake
'';
};
channelsConfig = mkOption {
type = pathToOr attrs;
default = {};
description = ''
nixpkgs config for all channels
'';
};
channels = mkOption {
type = pathToOr channelsType;
default = {};
description = ''
nixpkgs channels to create
'';
};
outputsBuilder = mkOption {
type = pathToOr outputsBuilderType;
default = channels: {};
defaultText = "channels: { }";
description = ''
builder for flake system-spaced outputs
The builder gets passed an attrset of all channels
'';
};
nixos = mkOption {
type = pathToOr nixosType;
default = {};
description = ''
hosts, modules, suites, and profiles for NixOS
'';
};
home = mkOption {
type = pathToOr homeType;
default = {};
description = ''
hosts, modules, suites, and profiles for home-manager
'';
};
devshell = mkOption {
type = pathToOr devshellType;
default = {};
description = ''
Modules to include in your DevOS shell. the `modules` argument
will be exported under the `devshellModules` output
'';
};
};
}

View File

@ -1,142 +1,153 @@
# constructor dependencies
{ lib, self, inputs, deploy, devshell, home-manager, flake-utils-plus, tests, ... }:
config: channels:
let
{
lib,
self,
inputs,
deploy,
devshell,
home-manager,
flake-utils-plus,
tests,
...
}: config: channels: let
pkgs = channels.${config.nixos.hostDefaults.channelName};
system = pkgs.system;
mkPortableHomeManagerConfiguration =
{ username
, configuration
, pkgs
, system ? pkgs.system
}:
let
homeDirectoryPrefix =
if pkgs.stdenv.hostPlatform.isDarwin then "/Users" else "/home";
homeDirectory = "${homeDirectoryPrefix}/${username}";
in
mkPortableHomeManagerConfiguration = {
username,
configuration,
pkgs,
system ? pkgs.system,
}: let
homeDirectoryPrefix =
if pkgs.stdenv.hostPlatform.isDarwin
then "/Users"
else "/home";
homeDirectory = "${homeDirectoryPrefix}/${username}";
in
home-manager.lib.homeManagerConfiguration {
inherit username homeDirectory pkgs system;
extraModules = config.home.modules ++ config.home.exportedModules;
extraSpecialArgs = config.home.importables // { inherit self inputs; };
extraSpecialArgs = config.home.importables // {inherit self inputs;};
configuration = {
imports = [ configuration ];
} // (
if pkgs.stdenv.hostPlatform.isLinux
then { targets.genericLinux.enable = true; }
else { }
);
configuration =
{
imports = [configuration];
}
// (
if pkgs.stdenv.hostPlatform.isLinux
then {targets.genericLinux.enable = true;}
else {}
);
};
homeConfigurationsPortable =
builtins.mapAttrs
(n: v: mkPortableHomeManagerConfiguration {
(n: v:
mkPortableHomeManagerConfiguration {
username = n;
configuration = v;
inherit pkgs system;
})
config.home.users;
in
{
config.home.users;
in {
inherit homeConfigurationsPortable;
packages = flake-utils-plus.lib.exportPackages self.overlays channels;
devShell =
let
eval = import "${devshell}/modules" pkgs;
configuration = {
name = lib.mkDefault config.nixos.hostDefaults.channelName;
imports = config.devshell.modules ++ config.devshell.exportedModules;
};
in
devShell = let
eval = import "${devshell}/modules" pkgs;
configuration = {
name = lib.mkDefault config.nixos.hostDefaults.channelName;
imports = config.devshell.modules ++ config.devshell.exportedModules;
};
in
(eval {
inherit configuration;
extraSpecialArgs = { inherit self inputs; };
}).shell;
extraSpecialArgs = {inherit self inputs;};
})
.shell;
checks =
(
# for self.homeConfigurations if present & non empty
if (
(builtins.hasAttr "homeConfigurations" self) &&
(self.homeConfigurations != { })
) then
let
seive = _: v: v.system == system; # only test for the appropriate system
collectActivationPackages = n: v: { name = "user-" + n; value = v.activationPackage; };
in
if
(
(builtins.hasAttr "homeConfigurations" self)
&& (self.homeConfigurations != {})
)
then let
seive = _: v: v.system == system; # only test for the appropriate system
collectActivationPackages = n: v: {
name = "user-" + n;
value = v.activationPackage;
};
in
lib.filterAttrs seive (lib.mapAttrs' collectActivationPackages self.homeConfigurations)
else { }
else {}
)
//
(
// (
# for portableHomeConfigurations if present & non empty
if (
(homeConfigurationsPortable != { })
) then
let
collectActivationPackages = n: v: { name = "user-" + n; value = v.activationPackage; };
in
if (homeConfigurationsPortable != {})
then let
collectActivationPackages = n: v: {
name = "user-" + n;
value = v.activationPackage;
};
in
lib.mapAttrs' collectActivationPackages homeConfigurationsPortable
else { }
else {}
)
//
(
// (
# for self.deploy if present & non-empty
if (
(builtins.hasAttr "deploy" self) &&
(self.deploy != { })
) then
let
deployChecks = deploy.lib.${system}.deployChecks self.deploy;
renameOp = n: v: { name = "deploy-" + n; value = deployChecks.${n}; };
in
if
(
(builtins.hasAttr "deploy" self)
&& (self.deploy != {})
)
then let
deployChecks = deploy.lib.${system}.deployChecks self.deploy;
renameOp = n: v: {
name = "deploy-" + n;
value = deployChecks.${n};
};
in
lib.mapAttrs' renameOp deployChecks
else { }
else {}
)
//
(
// (
# for self.nixosConfigurations if present & non-empty
if (
(builtins.hasAttr "nixosConfigurations" self) &&
(self.nixosConfigurations != { })
) then
let
systemSieve = _: host: host.config.nixpkgs.system == system;
hostConfigsOnThisSystem = lib.filterAttrs systemSieve self.nixosConfigurations;
if
(
(builtins.hasAttr "nixosConfigurations" self)
&& (self.nixosConfigurations != {})
)
then let
systemSieve = _: host: host.config.nixpkgs.system == system;
hostConfigsOnThisSystem = lib.filterAttrs systemSieve self.nixosConfigurations;
createCustomTestOp = n: host: test:
lib.warnIf (!(test ? name)) ''
'${n}' has a test without a name. To distinguish tests in the flake output
all nixos tests must have names.
''
{
name = "customTestFor-${n}-${test.name}";
value = tests.mkTest host test;
};
createCustomTestsOp = n: host:
let
op = createCustomTestOp n host;
in
builtins.listToAttrs (map op config.nixos.hosts.${n}.tests);
customTests =
if (hostConfigsOnThisSystem != [ ])
then lib.foldl (a: b: a // b) { } (lib.attrValues (lib.mapAttrs createCustomTestsOp hostConfigsOnThisSystem))
else { };
createCustomTestOp = n: host: test:
lib.warnIf (!(test ? name)) ''
'${n}' has a test without a name. To distinguish tests in the flake output
all nixos tests must have names.
''
{
name = "customTestFor-${n}-${test.name}";
value = tests.mkTest host test;
};
createCustomTestsOp = n: host: let
op = createCustomTestOp n host;
in
customTests
else { }
)
;
builtins.listToAttrs (map op config.nixos.hosts.${n}.tests);
customTests =
if (hostConfigsOnThisSystem != [])
then lib.foldl (a: b: a // b) {} (lib.attrValues (lib.mapAttrs createCustomTestsOp hostConfigsOnThisSystem))
else {};
in
customTests
else {}
);
}

View File

@ -1,39 +1,44 @@
{ lib }:
{
hmNixosDefaults = { specialArgs, modules }:
{ options, ... }: {
config = lib.optionalAttrs (options ? home-manager) {
home-manager = {
# always use the system nixpkgs from the host's channel
useGlobalPkgs = true;
# and use the possible future default (see manual)
useUserPackages = lib.mkDefault true;
{lib}: {
hmNixosDefaults = {
specialArgs,
modules,
}: {options, ...}: {
config = lib.optionalAttrs (options ? home-manager) {
home-manager = {
# always use the system nixpkgs from the host's channel
useGlobalPkgs = true;
# and use the possible future default (see manual)
useUserPackages = lib.mkDefault true;
extraSpecialArgs = specialArgs;
sharedModules = modules;
};
extraSpecialArgs = specialArgs;
sharedModules = modules;
};
};
};
globalDefaults = { hmUsers }:
{ config, pkgs, self, ... }: {
users.mutableUsers = lib.mkDefault false;
globalDefaults = {hmUsers}: {
config,
pkgs,
self,
...
}: {
users.mutableUsers = lib.mkDefault false;
hardware.enableRedistributableFirmware = lib.mkDefault true;
hardware.enableRedistributableFirmware = lib.mkDefault true;
# digga lib can be accessed in modules directly as config.lib.digga
lib = {
inherit (pkgs.lib) digga;
};
_module.args = {
inherit hmUsers;
hosts = throw ''
The `hosts` module argument has been removed, you should instead use
`self.nixosConfigurations`, with the `self` module argument.
'';
};
system.configurationRevision = lib.mkIf (self ? rev) self.rev;
# digga lib can be accessed in modules directly as config.lib.digga
lib = {
inherit (pkgs.lib) digga;
};
_module.args = {
inherit hmUsers;
hosts = throw ''
The `hosts` module argument has been removed, you should instead use
`self.nixosConfigurations`, with the `self` module argument.
'';
};
system.configurationRevision = lib.mkIf (self ? rev) self.rev;
};
}

View File

@ -1,42 +1,35 @@
{ lib }:
let
{lib}: let
maybeImport = obj:
if (builtins.isPath obj || builtins.isString obj) then
import obj
else obj
;
if (builtins.isPath obj || builtins.isString obj)
then import obj
else obj;
maybeCallTest = pkgs: obj:
if lib.isFunction obj then
pkgs.callPackage obj { }
else obj
;
if lib.isFunction obj
then pkgs.callPackage obj {}
else obj;
mkTest = host: test:
let
pkgs = host._module.args.pkgs;
nixosTesting =
(import "${toString pkgs.path}/nixos/lib/testing-python.nix" {
inherit pkgs;
inherit (pkgs) system;
inherit (host.config.lib) specialArgs;
extraConfigurations = host._module.args.modules;
});
in
mkTest = host: test: let
pkgs = host._module.args.pkgs;
nixosTesting = import "${toString pkgs.path}/nixos/lib/testing-python.nix" {
inherit pkgs;
inherit (pkgs) system;
inherit (host.config.lib) specialArgs;
extraConfigurations = host._module.args.modules;
};
in
nixosTesting.makeTest (maybeCallTest pkgs (maybeImport test));
allProfilesTest = {
name = "allProfiles";
machine = { suites ? null, ... }: {
imports =
let
allProfiles = lib.foldl
(lhs: rhs: lhs ++ rhs) [ ]
(builtins.attrValues suites);
in
machine = {suites ? null, ...}: {
imports = let
allProfiles =
lib.foldl
(lhs: rhs: lhs ++ rhs) []
(builtins.attrValues suites);
in
allProfiles;
};
@ -44,5 +37,4 @@ let
machines[0].systemctl("is-system-running --wait")
'';
};
in
{ inherit mkTest allProfilesTest; }
in {inherit mkTest allProfilesTest;}