diff --git a/CHANGELOG.md b/CHANGELOG.md index c273c7f..d3fbb56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - A quick question. [\#428](https://github.com/divnix/digga/issues/428) - infinite recursion error related to whether a git repo exists \#408 [\#413](https://github.com/divnix/digga/issues/413) -- Support aarch64-darwin [\#335](https://github.com/divnix/digga/issues/335) +- Support aarch64-darwin [\#335](https://github.com/divnix/digga/issues/335) - pkgs in home-manager profiles [\#309](https://github.com/divnix/digga/issues/309) - Allow the same user profile to behave differently based on hostname [\#308](https://github.com/divnix/digga/issues/308) - Home-manager inside ./modules or ./profiles to set user settings in a user agnostic way [\#303](https://github.com/divnix/digga/issues/303) @@ -126,7 +126,7 @@ **Fixed bugs:** -- My emacsGcc overlay is not working [\#146](https://github.com/divnix/digga/issues/146) +- My emacsGcc overlay is not working [\#146](https://github.com/divnix/digga/issues/146) - local flake registry freezes branches [\#142](https://github.com/divnix/digga/issues/142) - nixos-option no longer works after collect garbage [\#138](https://github.com/divnix/digga/issues/138) - Profiles imports are brittle, causing failure if imported twice [\#136](https://github.com/divnix/digga/issues/136) @@ -158,6 +158,4 @@ ## [07092020](https://github.com/divnix/digga/tree/07092020) (2020-07-09) - - -\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* +\* _This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)_ diff --git a/README.md b/README.md index 21fe28d..e1ed4b4 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![NixOS](https://img.shields.io/badge/NixOS-unstable-blue.svg?style=flat&logo=NixOS&logoColor=white)](https://nixos.org) [![Chat](https://img.shields.io/badge/chat-join%20us-brightgreen.svg?style=flat&logo=matrix&logoColor=white)](https://matrix.to/#/#devos:nixos.org) - Digga — slangy German for "good friend" — is a flake utility library that helps you declaratively craft and manage all three layers of your system environment within a single [nix flakes][flakes] repository: @@ -14,28 +13,32 @@ environment within a single [nix flakes][flakes] repository: This library is based on [flake-utils-plus][]. # Status: Beta + Although this project has already matured quite a bit, a fair amount of api polishing is still expected. There are unstable versions (0._x_._x_) to help users keep track of changes and progress. # Usage + The best way to make use of library is with the [Official template][template]. Check out the [guide](./doc/start/index.md) to get up and running. Also have a look at devos's [_flake.nix_](./examples/devos/flake.nix). If anything is not immediately discoverable via our [`mkFlake`][mk-flake], please file a bug report. # Examples + Make sure to check out all the [examples](./examples) to see the different ways to make use of the digga api. ## In the Wild -You can also see digga being actually used: -* @Pacman99: [Personal](https://gitlab.com/coffeetables/lower), [Server](https://gitlab.com/coffeetables/myrdd) -* [@danielphan2003](https://github.com/danielphan2003/flk) and make sure to also check out [devos-ext-lib](https://github.com/divnix/devos-ext-lib) -* [PubSolarOS](https://git.sr.ht/~b12f/pub-solar-os) -* @montchr: [Dotfield](https://github.com/montchr/dotfield) – including darwin configurations -* [@sweenu](https://github.com/sweenu/nixfiles): pc, server and RaspberryPi deployment in one repo +You can also see digga being actually used: + +- @Pacman99: [Personal](https://gitlab.com/coffeetables/lower), [Server](https://gitlab.com/coffeetables/myrdd) +- [@danielphan2003](https://github.com/danielphan2003/flk) and make sure to also check out [devos-ext-lib](https://github.com/divnix/devos-ext-lib) +- [PubSolarOS](https://git.sr.ht/~b12f/pub-solar-os) +- @montchr: [Dotfield](https://github.com/montchr/dotfield) – including darwin configurations +- [@sweenu](https://github.com/sweenu/nixfiles): pc, server and RaspberryPi deployment in one repo # Philosophy @@ -54,17 +57,19 @@ interface comprising four API containers that allow you to: your projects. ## Modules, Profiles & Suites + For NixOS- & home-manager-modules, _Digga_ allows you to distinguish between _modules_, _profiles_ and _suites_. - **Modules** are abstract configurations that, while holding the implementation, do not -set any system state. + set any system state. - **Profiles** are concrete configurations that set system state within the profile domain. - **Suites** are a composable, clean and discoverable mechanism for profile aggregation. ## Internal Art vs External Art + Overlays and modules can be defined internally coming from your repo or externally coming from an upstream flake. This distinction serves the library to only export your own work as the public flake output. @@ -73,6 +78,7 @@ Downstream consumers of your flake can now more easily tell your art apart from other upstream art. # Contributing + We encourage contributions of any kind. The simplest way to get involved is to join the [chat][] or report problems and ideas on the [issue thread][issues]. @@ -81,19 +87,23 @@ To craft well thought out APIs we need all the thoughts regarding new ideas. Pull Requests are just as amazing. # Why _flakes_? -Flakes are a part of an explicit push to improve [Nix's UX](https://github.com/NixOS/nix/blob/master/doc/manual/src/contributing/cli-guideline.md), and have become an integral part of that effort. + +Flakes are a part of an explicit push to improve [Nix's UX](https://github.com/NixOS/nix/blob/master/doc/manual/src/contributing/cli-guideline.md), and have become an integral part of that effort. They also make [Nix expressions](https://nixos.org/manual/nix/unstable/expressions/expression-syntax.html) easier to distribute and reuse with convient [flake references](https://github.com/NixOS/nix/blob/master/src/nix/flake.md#flake-references) for building or using packages, modules, and whole systems. # Shoulders + This work does not reinvent the wheel. It stands on the [shoulders of the following giants][giants]: ## :onion: — like the layers of an onion + - [`gytis-ivaskevicius/flake-utils-plus`](https://github.com/gytis-ivaskevicius/flake-utils-plus) - [`numtide/flake-utils`](https://github.com/numtide/flake-utils/) ## :family: — like family + - [`numtide/devshell`](https://github.com/numtide/devshell) - [`serokell/deploy-rs`](https://github.com/serokell/deploy-rs) - [`berberman/nvfetcher`](https://github.com/berberman/nvfetcher) @@ -102,6 +112,7 @@ following giants][giants]: :heart: ### Inspiration & Art + - [hlissner/dotfiles](https://github.com/hlissner/dotfiles) - [nix-user-chroot](https://github.com/nix-community/nix-user-chroot) - [Nickel](https://github.com/tweag/nickel) @@ -109,6 +120,7 @@ following giants][giants]: - [devshell](https://github.com/numtide/devshell) # Divnix + The divnix org is an open space that spontaneously formed out of "the Nix". It is really just a place where otherwise unrelated people work together and get stuff done. @@ -121,6 +133,7 @@ It might eventually become a non-profit if that's not too complicated or, if tho goals are sufficiently upstreamed into "the Nix", dissolved. # License + Digga is licensed under the [MIT License][mit]. [mk-flake]: ./src/mkFlake @@ -136,4 +149,3 @@ Digga is licensed under the [MIT License][mit]. [nix]: https://nixos.org/manual/nix/stable [nixpkgs]: https://github.com/nixos/nixpkgs [template]: ./examples/devos - diff --git a/checks/default.nix b/checks/default.nix index e2a2216..7facb08 100644 --- a/checks/default.nix +++ b/checks/default.nix @@ -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 + ''; } diff --git a/checks/lib/default.nix b/checks/lib/default.nix index 305818d..e492fad 100644 --- a/checks/lib/default.nix +++ b/checks/lib/default.nix @@ -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; + }; }; - }; -} + } diff --git a/checks/lib/profiles/f.nix b/checks/lib/profiles/f.nix index ffcd441..0967ef4 100644 --- a/checks/lib/profiles/f.nix +++ b/checks/lib/profiles/f.nix @@ -1 +1 @@ -{ } +{} diff --git a/checks/lib/profiles/t/bar.nix b/checks/lib/profiles/t/bar.nix index ffcd441..0967ef4 100644 --- a/checks/lib/profiles/t/bar.nix +++ b/checks/lib/profiles/t/bar.nix @@ -1 +1 @@ -{ } +{} diff --git a/default.nix b/default.nix index 664f25f..bb33a04 100644 --- a/default.nix +++ b/default.nix @@ -1,17 +1,22 @@ let - inherit (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 = ./.; }) defaultNix; + inherit + (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 = ./.;}) + defaultNix + ; in -# Pass this flake as inputs.digga -defaultNix // { - inputs = defaultNix.inputs // { digga = defaultNix; }; - shell = import ./devShell.nix { }; -} - + # Pass this flake as inputs.digga + defaultNix + // { + inputs = defaultNix.inputs // {digga = defaultNix;}; + shell = import ./devShell.nix {}; + } diff --git a/deprecated.nix b/deprecated.nix index 8b3e070..e5059a8 100644 --- a/deprecated.nix +++ b/deprecated.nix @@ -1,16 +1,17 @@ -{ lib, importers }: +{ + lib, + importers, +}: 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; } diff --git a/devShell.nix b/devShell.nix index 924d0cd..62223f9 100644 --- a/devShell.nix +++ b/devShell.nix @@ -1,13 +1,13 @@ -{ system ? builtins.currentSystem -, inputs ? (import ./.).inputs -}: -let +{ + system ? builtins.currentSystem, + inputs ? (import ./.).inputs, +}: let pkgs = inputs.nixpkgs.legacyPackages.${system}; unstablePkgs = inputs.nixpkgs-unstable.legacyPackages.${system}; - devshell = import inputs.devshell { inherit system; }; + devshell = import inputs.devshell {inherit system;}; nixBin = "${unstablePkgs.nix}/bin/nix"; - withCategory = category: attrset: attrset // { inherit category; }; + withCategory = category: attrset: attrset // {inherit category;}; utils = withCategory "utils"; docs = withCategory "docs"; @@ -31,84 +31,81 @@ 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 - tempdigga=path:$PRJ_ROOT + tempdigga=path:$PRJ_ROOT - trap_err() { - local ret=$? - echo -e \ - "\033[1m\033[31m""exit $ret: \033[0m\033[1m""command [$BASH_COMMAND] failed""\033[0m" - } + trap_err() { + local ret=$? + echo -e \ + "\033[1m\033[31m""exit $ret: \033[0m\033[1m""command [$BASH_COMMAND] failed""\033[0m" + } - is () { [ "$1" -eq "0" ]; } + is () { [ "$1" -eq "0" ]; } - trap 'trap_err' ERR + trap 'trap_err' ERR - # -------------------------------------------------------------------------------- + # -------------------------------------------------------------------------------- - cd $PRJ_ROOT/${type}/${name} - - ${nixBin} flake show "$@" --override-input digga $tempdigga - ${nixBin} flake check "$@" --override-input digga $tempdigga - ''; - }; + cd $PRJ_ROOT/${type}/${name} + ${nixBin} flake show "$@" --override-input digga $tempdigga + ${nixBin} flake check "$@" --override-input digga $tempdigga + ''; + }; in -devshell.mkShell { - name = "digga"; - packages = with pkgs; [ - fd - treefmt - alejandra - nodePackages.prettier - shellcheck - shfmt - # Use the latest stable version of nix - unstablePkgs.nix - ]; + devshell.mkShell { + name = "digga"; + packages = with pkgs; [ + fd + treefmt + alejandra + nodePackages.prettier + shellcheck + shfmt + # Use the latest stable version of nix + unstablePkgs.nix + ]; - 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=''; + } + ]; - 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 formatting"; - command = "treefmt \${@} $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 formatting"; + command = "treefmt \${@} $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) + ]; + } diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index 1297506..c49667c 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -1,14 +1,15 @@ # TL;DR; + - **Target Branch**: `main` - **Merge Policy**: green check: merge away. yellow circle: have patience. red x: try again. - **Docs**: every change set is expected to contain doc updates -- **Commit Msg**: be a poet! Comprehensive and explanatory commit messages +- **Commit Msg**: be a poet! Comprehensive and explanatory commit messages should cover the motivation and use case in an easily understandable manner even when read after a few months. - **Test Driven Development**: please default to test driven development you can - make use of the `./examples` & `./e2e` and wire test up in the devshell. + make use of the `./examples` & `./e2e` and wire test up in the devshell. ### Within the Devshell (`nix develop`) + - **Hooks**: please `git commit` within the devshell - **Fail Early**: please run `check-all` from within the devshell on your local machine - diff --git a/doc/api-reference-channels.md b/doc/api-reference-channels.md index 533e6e9..2ac2530 100755 --- a/doc/api-reference-channels.md +++ b/doc/api-reference-channels.md @@ -1,91 +1,76 @@ # Channels API Container + Configure your channels that you can use throughout your configurations. > #### ⚠ Gotcha ⚠ +> > Devshell & (non-host-specific) Home-Manager `pkgs` instances are rendered off the > `nixos.hostDefaults.channelName` (default) channel. - ## channels + nixpkgs channels to create - -*_Type_*: +_*Type*_: attribute set of submodules or path convertible to it +_*Default*_ -*_Default_* ``` {} ``` - - - ## channels.\.config + nixpkgs config for this channel - -*_Type_*: +_*Type*_: attribute set or path convertible to it +_*Default*_ -*_Default_* ``` {} ``` - - - ## channels.\.input + nixpkgs flake input to use for this channel - -*_Type_*: +_*Type*_: nix flake +_*Default*_ -*_Default_* ``` "self.inputs." ``` - - - ## channels.\.overlays + overlays to apply to this channel these will get exported under the 'overlays' flake output as \/\ and any overlay pulled from \ will be filtered out - -*_Type_*: +_*Type*_: list of valid Nixpkgs overlay or path convertible to its or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## channels.\.patches + patches to apply to this channel - -*_Type_*: +_*Type*_: list of paths +_*Default*_ -*_Default_* ``` [] ``` - - - - diff --git a/doc/api-reference-devshell.md b/doc/api-reference-devshell.md index 28f1808..64ad74f 100755 --- a/doc/api-reference-devshell.md +++ b/doc/api-reference-devshell.md @@ -1,72 +1,59 @@ # Devshell API Container + Configure your devshell module collections of your environment. - ## devshell + Modules to include in your DevOS shell. the `modules` argument will be exported under the `devshellModules` output - -*_Type_*: +_*Type*_: submodule or path convertible to it +_*Default*_ -*_Default_* ``` {} ``` - - - ## devshell.exportedModules + modules to include in all hosts and export to devshellModules output - -*_Type_*: +_*Type*_: list of valid module or path convertible to its or anything convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## devshell.externalModules + 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. - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## devshell.modules + modules to include that won't be exported meant importing modules from external flakes - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - - diff --git a/doc/api-reference-home.md b/doc/api-reference-home.md index 0ab62f3..c2bd002 100755 --- a/doc/api-reference-home.md +++ b/doc/api-reference-home.md @@ -1,119 +1,97 @@ # Home-Manager API Container + Configure your home manager modules, profiles & suites. - ## home + hosts, modules, suites, and profiles for home-manager - -*_Type_*: +_*Type*_: submodule or path convertible to it +_*Default*_ -*_Default_* ``` {} ``` - - - ## home.exportedModules + modules to include in all hosts and export to homeModules output - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## home.externalModules + 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. - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## home.importables + Packages of paths to be passed to modules as `specialArgs`. - -*_Type_*: +_*Type*_: attribute set +_*Default*_ -*_Default_* ``` {} ``` - - - ## home.importables.suites + collections of profiles - -*_Type_*: +_*Type*_: null or attribute set of list of paths or anything convertible to its or path convertible to it +_*Default*_ -*_Default_* ``` null ``` - - - ## home.modules + modules to include that won't be exported meant importing modules from external flakes - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## home.users + HM users that can be deployed portably without a host. - -*_Type_*: +_*Type*_: attribute set of HM user configs +_*Default*_ -*_Default_* ``` {} ``` - - - - diff --git a/doc/api-reference-nixos.md b/doc/api-reference-nixos.md index 7428b16..d5a780c 100755 --- a/doc/api-reference-nixos.md +++ b/doc/api-reference-nixos.md @@ -1,234 +1,191 @@ # NixOS API Container + Configure your nixos modules, profiles & suites. - ## nixos + hosts, modules, suites, and profiles for NixOS - -*_Type_*: +_*Type*_: submodule or path convertible to it +_*Default*_ -*_Default_* ``` {} ``` - - - ## nixos.hostDefaults + Defaults for all hosts. the modules passed under hostDefaults will be exported to the 'nixosModules' flake output. They will also be added to all hosts. - -*_Type_*: +_*Type*_: submodule +_*Default*_ -*_Default_* ``` {} ``` - - - ## nixos.hostDefaults.channelName + Channel this host should follow - -*_Type_*: +_*Type*_: channel defined in `channels` - - - - - ## nixos.hostDefaults.exportedModules + modules to include in all hosts and export to nixosModules output - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## nixos.hostDefaults.externalModules + 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. - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## nixos.hostDefaults.modules + modules to include that won't be exported meant importing modules from external flakes - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## nixos.hostDefaults.system + system for this host - -*_Type_*: +_*Type*_: null or system defined in `supportedSystems` +_*Default*_ -*_Default_* ``` null ``` - - - ## nixos.hosts + configurations to include in the nixosConfigurations output - -*_Type_*: +_*Type*_: attribute set of submodules +_*Default*_ -*_Default_* ``` {} ``` - - - ## nixos.hosts.\.channelName + Channel this host should follow - -*_Type_*: +_*Type*_: null or channel defined in `channels` +_*Default*_ -*_Default_* ``` null ``` - - - ## nixos.hosts.\.modules + modules to include - -*_Type_*: +_*Type*_: list of valid modules or anything convertible to it or path convertible to it +_*Default*_ -*_Default_* ``` [] ``` - - - ## nixos.hosts.\.system + system for this host - -*_Type_*: +_*Type*_: null or system defined in `supportedSystems` +_*Default*_ -*_Default_* ``` null ``` - - - ## nixos.hosts.\.tests + tests to run - -*_Type_*: +_*Type*_: list of valid NixOS test or path convertible to its or anything convertible to it +_*Default*_ -*_Default_* ``` [] ``` +_*Example*_ -*_Example_* ``` {"_type":"literalExpression","text":"[\n {\n name = \"testname1\";\n machine = { ... };\n testScript = ''\n # ...\n '';\n }\n ({ corutils, writers, ... }: {\n name = \"testname2\";\n machine = { ... };\n testScript = ''\n # ...\n '';\n })\n ./path/to/test.nix\n];\n"} ``` - ## nixos.importables + Packages of paths to be passed to modules as `specialArgs`. - -*_Type_*: +_*Type*_: attribute set +_*Default*_ -*_Default_* ``` {} ``` - - - ## nixos.importables.suites + collections of profiles - -*_Type_*: +_*Type*_: null or attribute set of list of paths or anything convertible to its or path convertible to it +_*Default*_ -*_Default_* ``` null ``` - - - - diff --git a/doc/api-reference.md b/doc/api-reference.md index 47eb128..ee2cb9e 100755 --- a/doc/api-reference.md +++ b/doc/api-reference.md @@ -1,4 +1,5 @@ # Top Level API + `digga`'s top level API. API Containers are documented in their respective sub-chapter: - [Channels](./api-reference-channels.md) @@ -8,73 +9,55 @@ - [Darwin](./api-reference-darwin.md) ## channelsConfig + nixpkgs config for all channels - -*_Type_*: +_*Type*_: attribute set or path convertible to it +_*Default*_ -*_Default_* ``` {} ``` - - - ## inputs + The flake's inputs -*_Type_*: +_*Type*_: attribute set of nix flakes - - - - - ## outputsBuilder + builder for flake system-spaced outputs The builder gets passed an attrset of all channels - -*_Type_*: +_*Type*_: function that evaluates to a(n) attribute set or path convertible to it +_*Default*_ -*_Default_* ``` "channels: { }" ``` - - - ## self + The flake to create the DevOS outputs for -*_Type_*: +_*Type*_: nix flake - - - - - ## supportedSystems + The systems supported by this flake - -*_Type_*: +_*Type*_: list of strings +_*Default*_ -*_Default_* ``` ["aarch64-linux","aarch64-darwin","i686-linux","x86_64-darwin","x86_64-linux"] ``` - - - - diff --git a/doc/concepts/hosts.md b/doc/concepts/hosts.md index 1c3c3fa..028f587 100644 --- a/doc/concepts/hosts.md +++ b/doc/concepts/hosts.md @@ -28,10 +28,10 @@ is best saved for [profile modules](./profiles.md). This is a good place to import sets of profiles, called [suites](./suites.md), that you intend to use on your machine. - ## Example flake.nix: + ```nix { nixos = { @@ -47,6 +47,7 @@ flake.nix: ``` hosts/librem.nix: + ```nix { suites, ... }: { diff --git a/doc/concepts/overrides.md b/doc/concepts/overrides.md index 610fde0..46ef653 100644 --- a/doc/concepts/overrides.md +++ b/doc/concepts/overrides.md @@ -1,8 +1,10 @@ # Overrides + Each NixOS host follows one channel. But many times it is useful to get packages or modules from different channels. ## Packages + You can make use of `overlays/overrides.nix` to override specific packages in the default channel to be pulled from other channels. That file is simply an example of how any overlay can get `channels` as their first argument. @@ -10,6 +12,7 @@ of how any overlay can get `channels` as their first argument. You can add overlays to any channel to override packages from other channels. Pulling the manix package from the `latest` channel: + ```nix channels: final: prev: { __dontExport = true; @@ -23,11 +26,12 @@ overrides and the property is already set for you. ## Modules -You can also pull modules from other channels. All modules have access to the +You can also pull modules from other channels. All modules have access to the `modulesPath` for each channel as `ModulesPath`. And you can use `disabledModules` to remove modules from the current channel. To pull zsh module from the `latest` channel this code can be placed in any module, whether its your host file, a profile, or a module in ./modules etc: + ```nix { latestModulesPath }: { @@ -37,6 +41,7 @@ To pull zsh module from the `latest` channel this code can be placed in any modu ``` > ##### _Note:_ +> > Sometimes a modules name will change from one branch to another. [nixpkgs-modules]: https://github.com/NixOS/nixpkgs/tree/master/nixos/modules diff --git a/doc/concepts/profiles.md b/doc/concepts/profiles.md index 7e592cc..a940495 100644 --- a/doc/concepts/profiles.md +++ b/doc/concepts/profiles.md @@ -6,20 +6,23 @@ built into the NixOS module system for a reason: to elegantly provide a clear separation of concerns. ## Creation + Profiles are created with the `rakeLeaves` function which recursively collects -`.nix` files from within a folder. The recursion stops at folders with a `default.nix` +`.nix` files from within a folder. The recursion stops at folders with a `default.nix` in them. You end up with an attribute set with leaves(paths to profiles) or nodes(attrsets leading to more nodes or leaves). A profile is used for quick modularization of [interelated bits](./profiles.md#subprofiles). > ##### _Notes:_ -> * For _declaring_ module options, there's the [modules](../outputs/modules.md) directory. -> * This directory takes inspiration from +> +> - For _declaring_ module options, there's the [modules](../outputs/modules.md) directory. +> - This directory takes inspiration from > [upstream](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/profiles) > . ### Nested profiles + Profiles can be nested in attribute sets due to the recursive nature of `rakeLeaves`. This can be useful to have a set of profiles created for a specific purpose. It is sometimes useful to have a `common` profile that has high level concerns related @@ -28,6 +31,7 @@ to all its sister profiles. ### Example profiles/develop/common.nix: + ```nix { imports = [ ./zsh ]; @@ -36,6 +40,7 @@ profiles/develop/common.nix: ``` profiles/develop/zsh.nix: + ```nix { ... }: { @@ -45,6 +50,7 @@ profiles/develop/zsh.nix: ``` The examples above will end up with a profiles set like this: + ```nix { develop = { @@ -55,6 +61,7 @@ The examples above will end up with a profiles set like this: ``` ## Conclusion + Profiles are the most important concept in DevOS. They allow us to keep our Nix expressions self contained and modular. This way we can maximize reuse across hosts while minimizing boilerplate. Remember, anything machine diff --git a/doc/concepts/suites.md b/doc/concepts/suites.md index e9eef34..45d7ec4 100644 --- a/doc/concepts/suites.md +++ b/doc/concepts/suites.md @@ -1,4 +1,5 @@ # Suites + Suites provide a mechanism for users to easily combine and name collections of profiles. @@ -8,6 +9,7 @@ argument (one that can be use in an `imports` line) to your hosts. All lists def in `suites` are flattened and type-checked as paths. ## Definition + ```nix rec { workstation = [ profiles.develop profiles.graphical users.nixos ]; @@ -16,7 +18,9 @@ rec { ``` ## Usage + `hosts/my-laptop.nix`: + ```nix { suites, ... }: { diff --git a/doc/concepts/users.md b/doc/concepts/users.md index 8d94c64..85e2f07 100644 --- a/doc/concepts/users.md +++ b/doc/concepts/users.md @@ -1,5 +1,6 @@ > ##### _Note:_ -> This section and its semantics need a conceptiual rework. +> +> This section and its semantics need a conceptiual rework. > Since recently [portable home configurations][portableuser] > that are not bound to any specific host are a thing. @@ -11,7 +12,9 @@ home manager is wired in by default so all you have to worry about is declaring your users. ## Basic Usage + `users/myuser/default.nix`: + ```nix { ... }: { @@ -27,6 +30,7 @@ your users. ``` ## Home Manager + Home Manager support follows the same principles as regular nixos configurations, it even gets its own namespace in your `flake.nix` as `home`. @@ -36,7 +40,9 @@ User profiles can be collected in a similar fashion as system ones into a `suite argument that gets passed to your home-manager users. ### Example + `flake.nix` + ```nix { home.users.nixos = { suites, ... }: { @@ -45,10 +51,10 @@ argument that gets passed to your home-manager users. } ``` - ## External Usage + You can easily use the defined home-manager configurations outside of NixOS -using the `homeConfigurations` flake output. +using the `homeConfigurations` flake output. This is great for keeping your environment consistent across Unix-like systems, including macOS. diff --git a/doc/integrations/cachix.md b/doc/integrations/cachix.md index b025459..1b609f1 100644 --- a/doc/integrations/cachix.md +++ b/doc/integrations/cachix.md @@ -1,4 +1,5 @@ # Cachix + The system will automatically pull a cachix.nix at the root if one exists. This is usually created automatically by a `sudo cachix use`. If you're more inclined to keep the root clean, you can drop any generated files in the diff --git a/doc/integrations/deploy.md b/doc/integrations/deploy.md index 2282eb7..5c5e167 100644 --- a/doc/integrations/deploy.md +++ b/doc/integrations/deploy.md @@ -1,4 +1,5 @@ # deploy-rs + [Deploy-rs][d-rs] is a tool for managing NixOS remote machines. It was chosen for devos after the author experienced some frustrations with the stateful nature of nixops' db. It was also designed from scratch to support @@ -11,6 +12,7 @@ the command line. ## Usage Just add your ssh key to the host: + ```nix { ... }: { @@ -21,6 +23,7 @@ Just add your ssh key to the host: ``` And the private key to your user: + ```nix { ... }: { @@ -39,16 +42,20 @@ And the private key to your user: ``` And run the deployment: + ```sh deploy '.#hostName' --hostname host.example.com ``` > ##### _Note:_ +> > Your user will need **passwordless** sudo access + ### Home Manager Digga's `lib.mkDeployNodes` provides only `system` profile. In order to deploy your `home-manager` configuration you should provide additional profile(s) to deploy-rs config: + ```nix # Initially, this line looks like this: deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations { }; deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations @@ -67,10 +74,9 @@ deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations }; ``` -Substitute ``, `` and `` placeholders (omitting the `<>`). +Substitute ``, `` and `` placeholders (omitting the `<>`). `` is there to illustrate deploying multiple `home-manager` configurations. Either substitute those as well, or remove them altogether. Don't forget the `profileOrder` variable. - [d-rs]: https://github.com/serokell/deploy-rs diff --git a/doc/integrations/hercules.md b/doc/integrations/hercules.md index aa0185e..aeb1daa 100644 --- a/doc/integrations/hercules.md +++ b/doc/integrations/hercules.md @@ -1,4 +1,5 @@ # Hercules CI + If you start adding your own packages and configurations, you'll probably have at least a few binary artifacts. With hercules we can build every package in our configuration automatically, on every commit. Additionally, we can have it @@ -8,6 +9,7 @@ This will work whether your copy is a fork, or a bare template, as long as your repo is hosted on GitHub. ## Setup + Just head over to [hercules-ci.com](https://hercules-ci.com) to make an account. Then follow the docs to set up an [agent][agent], if you want to deploy to a @@ -15,6 +17,7 @@ binary cache (and of course you do), be sure _not_ to skip the [binary-caches.json][cache]. ## Ready to Use + The repo is already set up with the proper _default.nix_ file, building all declared packages, checks, profiles and shells. So you can see if something breaks, and never build the same package twice! @@ -23,6 +26,7 @@ If you want to get fancy, you could even have hercules [deploy your configuration](https://docs.hercules-ci.com/hercules-ci-effects/guide/deploy-a-nixos-machine/)! > ##### _Note:_ +> > Hercules doesn't have access to anything encrypted in the > [secrets folder](../../secrets), so none of your secrets will accidentally get > pushed to a cache by mistake. diff --git a/doc/integrations/index.md b/doc/integrations/index.md index 5ea739e..ce9f3f1 100644 --- a/doc/integrations/index.md +++ b/doc/integrations/index.md @@ -1,4 +1,5 @@ # Integrations + This section explores some of the optional tools included with devos to provide a solution to common concerns such as ci and remote deployment. An effort is made to choose tools that treat nix, and where possible flakes, as first class diff --git a/doc/integrations/nvfetcher.md b/doc/integrations/nvfetcher.md index c26c5fb..75a0fd2 100644 --- a/doc/integrations/nvfetcher.md +++ b/doc/integrations/nvfetcher.md @@ -1,4 +1,5 @@ # nvfetcher + [NvFetcher][nvf] is a workflow companion for updating nix sources. You can specify an origin source and an update configuration, and @@ -15,6 +16,7 @@ and commit the results. ## Usage Statically fetching (not tracking) a particular tag from a github repo: + ```toml [manix] src.manual = "v0.6.3" @@ -22,6 +24,7 @@ fetch.github = "mlvzk/manix" ``` Tracking the latest github _release_ from a github repo: + ```toml [manix] src.github = "mlvzk/manix" # responsible for tracking @@ -29,6 +32,7 @@ fetch.github = "mlvzk/manix" # responsible for fetching ``` Tracking the latest commit of a git repository and fetch from a git repo: + ```toml [manix] src.git = "https://github.com/mlvzk/manix.git" # responsible for tracking @@ -36,6 +40,7 @@ fetch.git = "https://github.com/mlvzk/manix.git" # responsible for fetching ``` > ##### _Note:_ +> > Please refer to the [NvFetcher Readme][nvf-readme] for more options. [nvf]: https://github.com/berberman/nvfetcher diff --git a/doc/outputs/index.md b/doc/outputs/index.md index 3620718..34f8e66 100644 --- a/doc/outputs/index.md +++ b/doc/outputs/index.md @@ -1,3 +1,4 @@ # Layout + Each of the following sections is a directory whose contents are output to the outside world via the flake's outputs. Check each chapter for details. diff --git a/doc/outputs/modules.md b/doc/outputs/modules.md index f698e9f..208c910 100644 --- a/doc/outputs/modules.md +++ b/doc/outputs/modules.md @@ -1,4 +1,5 @@ # Modules + The modules directory is a replica of nixpkg's NixOS [modules][nixpkgs-modules] , and follows the same semantics. This allows for trivial upstreaming into nixpkgs proper once your module is sufficiently stable. @@ -6,18 +7,21 @@ nixpkgs proper once your module is sufficiently stable. All modules linked in _module-list.nix_ are automatically exported via `nixosModules.`, and imported into all [hosts](../concepts/hosts.md). - > ##### _Note:_ +> > This is reserved for declaring brand new module options. If you just want to > declare a coherent configuration of already existing and related NixOS options > , use [profiles](../concepts/profiles.md) instead. ## Semantics + In case you've never written a module for nixpkgs before, here is a brief outline of the process. ### Declaration + modules/services/service-category/my-service.nix: + ```nix { config, lib, ... }: let @@ -37,7 +41,9 @@ in ``` ### Import + modules/module-list.nix: + ```nix [ ./services/service-category/my-service.nix @@ -47,7 +53,9 @@ modules/module-list.nix: ## Usage ### Internal + profiles/profile-category/my-profile.nix: + ```nix { ... }: { @@ -56,7 +64,9 @@ profiles/profile-category/my-profile.nix: ``` ### External + flake.nix: + ```nix { # inputs omitted diff --git a/doc/outputs/overlays.md b/doc/outputs/overlays.md index f463d1a..607d751 100644 --- a/doc/outputs/overlays.md +++ b/doc/outputs/overlays.md @@ -1,4 +1,5 @@ # Overlays + Writing overlays is a common occurence when using a NixOS system. Therefore, we want to keep the process as simple and straightforward as possible. @@ -9,7 +10,9 @@ exported via `overlays./` _as well as_ write it. ## Example + overlays/kakoune.nix: + ```nix final: prev: { kakoune = prev.kakoune.override { diff --git a/doc/outputs/pkgs.md b/doc/outputs/pkgs.md index 4de93a8..5b73372 100644 --- a/doc/outputs/pkgs.md +++ b/doc/outputs/pkgs.md @@ -1,4 +1,5 @@ # Packages + Similar to [modules](./modules.md), the pkgs directory mirrors the upstream [nixpkgs/pkgs][pkgs], and for the same reason; if you ever want to upstream your package, it's as simple as dropping it into the nixpkgs/pkgs directory. @@ -13,26 +14,30 @@ the supported systems listed in the package's `meta.platforms` attribute. And, as usual, every package in the overlay is also available to any NixOS [host](../concepts/hosts.md). -Another convenient difference is that it is possible to use -[nvfetcher](https://github.com/berberman/nvfetcher) to keep packages up to +Another convenient difference is that it is possible to use +[nvfetcher](https://github.com/berberman/nvfetcher) to keep packages up to date. This is best understood by the simple example below. ## Example -It is possible to specify sources separately to keep them up to date semi + +It is possible to specify sources separately to keep them up to date semi automatically. The basic rules are specified in pkgs/sources.toml: + ```toml # nvfetcher.toml [libinih] src.github = "benhoyt/inih" fetch.github = "benhoyt/inih" ``` -After changes to this file as well as to update the packages specified in there run + +After changes to this file as well as to update the packages specified in there run nvfetcher (for more details see [nvfetcher](https://github.com/berberman/nvfetcher)). The pkgs overlay is managed in pkgs/default.nix: + ```nix final: prev: { # keep sources first, this makes sources available to the pkgs @@ -45,6 +50,7 @@ final: prev: { Lastly the example package is in pkgs/development/libraries/libinih/default.nix: + ```nix { stdenv, meson, ninja, lib, sources, ... }: stdenv.mkDerivation { @@ -59,16 +65,17 @@ stdenv.mkDerivation { } ``` - ## Migration from flake based approach + Previous to nvfetcher it was possible to manage sources via a pkgs/flake.nix, the main changes from there are that sources where in the attribute "srcs" (now "sources") and the contents of the sources where slightly different. In order to switch to the new system, rewrite pkgs/flake.nix to a pkgs/sources.toml file using the documentation of nvfetcher, -add the line that calls the sources at the beginning of pkgs/default.nix, and +add the line that calls the sources at the beginning of pkgs/default.nix, and accomodate the small changes in the packages as can be seen from the example. The example package looked like: pkgs/flake.nix: + ```nix { description = "Package sources"; @@ -81,6 +88,7 @@ pkgs/flake.nix: ``` pkgs/default.nix: + ```nix final: prev: { # then, call packages with `final.callPackage` @@ -89,6 +97,7 @@ final: prev: { ``` pkgs/development/libraries/libinih/default.nix: + ```nix { stdenv, meson, ninja, lib, srcs, ... }: let inherit (srcs) libinih; in diff --git a/doc/secrets.md b/doc/secrets.md index 8794925..1ae1eb4 100644 --- a/doc/secrets.md +++ b/doc/secrets.md @@ -1,9 +1,11 @@ # Secrets + Secrets are managed using [agenix][agenix] so you can keep your flake in a public repository like GitHub without exposing your password or other sensitive data. ## Agenix + Currently, there is [no mechanism][secrets-issue] in nix itself to deploy secrets within the nix store because it is world-readable. @@ -17,6 +19,7 @@ matching ssh private key can read the data. The [age module][age module] will ad encrypted files to the nix store and decrypt them on activation to `/run/agenix`. ### Setup + All hosts must have openssh enabled, this is done by default in the core profile. You need to populate your `secrets/secrets.nix` with the proper ssh public keys. @@ -24,6 +27,7 @@ Be extra careful to make sure you only add public keys, you should never share a private key!! secrets/secrets.nix: + ```nix let system = ""; @@ -37,22 +41,25 @@ this file doesn't exist you likely need to enable openssh and rebuild your syste Your users ssh public key is probably stored in `~/.ssh/id_ed25519.pub` or `~/.ssh/id_rsa.pub`. If you haven't generated a ssh key yet, be sure do so: + ```sh ssh-keygen -t ed25519 ``` > ##### _Note:_ +> > The underlying tool used by agenix, rage, doesn't work well with password protected > ssh keys. So if you have lots of secrets you might have to type in your password many > times. - ### Secrets + You will need the `agenix` command to create secrets. DevOS conveniently provides that in the devShell, so just run `nix develop` whenever you want to edit secrets. Make sure to always run `agenix` while in the `secrets/` folder, so it can pick up your `secrets.nix`. To create secrets, simply add lines to your `secrets/secrets.nix`: + ``` let ... @@ -62,21 +69,26 @@ in "secret.age".publicKeys = allKeys; } ``` + That would tell agenix to create a `secret.age` file that is encrypted with the `system` and `user` ssh public key. Then go into the `secrets` folder and run: + ```sh agenix -e secret.age ``` + This will create the `secret.age`, if it doesn't already exist, and allow you to edit it. If you ever change the `publicKeys` entry of any secret make sure to rekey the secrets: + ```sh agenix --rekey ``` ### Usage + Once you have your secret file encrypted and ready to use, you can utilize the [age module][age module] to ensure that your secrets end up in `/run/secrets`. @@ -89,15 +101,14 @@ In any profile that uses a NixOS module that requires a secret you can enable a } ``` - Then you can just pass the path `/run/agenix/mysecret` to the module. You can make use of the many options provided by the age module to customize where and how secrets get decrypted. You can learn about them by looking at the [age module][age module]. - > ##### _Note:_ +> > You can take a look at the [agenix repository][agenix] for more information > about the tool. diff --git a/doc/start/index.md b/doc/start/index.md index 9650ba0..06e4129 100644 --- a/doc/start/index.md +++ b/doc/start/index.md @@ -1,18 +1,24 @@ # Quick Start + The only dependency is nix, so make sure you have it [installed][install-nix]. ## Get the Template + If you currently don't have flakes setup, you can utilize the digga shell to pull the template: + ```sh nix-shell "https://github.com/divnix/digga/archive/main.tar.gz" \ --run "nix flake init -t github:divnix/digga" ``` + If you already have flakes support, you can directly pull the template: + ```sh nix flake init -t github:divnix/digga ``` Then make sure to create the git repository: + ```sh git init git add . @@ -20,11 +26,14 @@ git commit -m init ``` To drop into a nix-shell, if you don't have flakes setup, use the digga shell to create a `flake.lock`: + ```sh nix-shell "https://github.com/divnix/digga/archive/main.tar.gz" \ --run "nix flake lock" ``` + Or if you do have flakes support, just run: + ```sh nix flake lock ``` @@ -35,6 +44,7 @@ version required. You can run `menu` to confirm that you are using digga (expect In addition, the [binary cache](../integrations/cachix.md) is added for faster deployment. > ##### _Notes:_ +> > - Flakes ignore files that have not been added to git, so be sure to stage new > files before building the system. > - You can choose to simply clone the repo with git if you want to follow @@ -46,5 +56,4 @@ In addition, the [binary cache](../integrations/cachix.md) is added for faster d - [Make installable ISO](./iso.md) - [install-nix]: https://nixos.org/manual/nix/stable/#sect-multi-user-installation diff --git a/doc/start/iso.md b/doc/start/iso.md index b8fa665..8ce3098 100644 --- a/doc/start/iso.md +++ b/doc/start/iso.md @@ -31,6 +31,6 @@ custom-made for your target host will maximise those local cache hits. For hosts that don't differ too much, a single USB stick might be ok, whereas when there are bigger differences, a custom-made USB stick will be considerably faster. -[nixos-generators]: https://github.com/nix-community/nixos-generators +[nixos-generators]: https://github.com/nix-community/nixos-generators [burn]: https://nixos.org/manual/nixos/stable/index.html#sec-booting-from-usb [formats]: https://github.com/nix-community/nixos-generators/tree/master/formats diff --git a/doc/tests.md b/doc/tests.md index 9c47a57..24dead0 100644 --- a/doc/tests.md +++ b/doc/tests.md @@ -6,12 +6,14 @@ configuration, and, optionally, run them in [CI](./integrations/hercules.md). ## Unit Tests + Unit tests can be created from regular derivations, and they can do almost anything you can imagine. By convention, it is best to test your packages during their [check phase][check]. All packages and their tests will be built during CI. ## Integration Tests + All your profiles defined in suites can be tested against an individual host. Simply use digga's pre-baked `digga.lib.allProfilesTest` like so: diff --git a/examples/devos/README.md b/examples/devos/README.md index 2ba6eae..e8160b3 100644 --- a/examples/devos/README.md +++ b/examples/devos/README.md @@ -1,9 +1,10 @@ # Nix Configuration + This repository is home to the nix code that builds my systems. ## Why Nix? -Nix allows for easy to manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works forever. If someone else shares their configuration, anyone can make use of it. +Nix allows for easy to manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works forever. If someone else shares their configuration, anyone can make use of it. This flake is configured with the use of [digga][digga]. diff --git a/examples/devos/default.nix b/examples/devos/default.nix index 0e6bdee..0468b22 100644 --- a/examples/devos/default.nix +++ b/examples/devos/default.nix @@ -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;} diff --git a/examples/devos/flake.nix b/examples/devos/flake.nix index 632917d..3dba105 100644 --- a/examples/devos/flake.nix +++ b/examples/devos/flake.nix @@ -5,205 +5,212 @@ 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 = - { - flake-compat = { - url = "github:edolstra/flake-compat"; - flake = false; - }; - - # Track channels with commits tested and built by hydra - nixos.url = "github:nixos/nixpkgs/nixos-22.05"; - latest.url = "github:nixos/nixpkgs/nixos-unstable"; - # For darwin hosts: it can be helpful to track this darwin-specific stable - # channel equivalent to the `nixos-*` channels for NixOS. For one, these - # channels are more likely to provide cached binaries for darwin systems. - # But, perhaps even more usefully, it provides a place for adding - # darwin-specific overlays and packages which could otherwise cause build - # failures on Linux systems. - nixpkgs-darwin-stable.url = "github:NixOS/nixpkgs/nixpkgs-22.05-darwin"; - - 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"; - - home.url = "github:nix-community/home-manager/release-22.05"; - home.inputs.nixpkgs.follows = "nixos"; - - darwin.url = "github:LnL7/nix-darwin"; - darwin.inputs.nixpkgs.follows = "nixpkgs-darwin-stable"; - - deploy.url = "github:serokell/deploy-rs"; - deploy.inputs.nixpkgs.follows = "nixos"; - - agenix.url = "github:ryantm/agenix"; - agenix.inputs.nixpkgs.follows = "nixos"; - - nvfetcher.url = "github:berberman/nvfetcher"; - nvfetcher.inputs.nixpkgs.follows = "nixos"; - - naersk.url = "github:nmattia/naersk"; - naersk.inputs.nixpkgs.follows = "nixos"; - - nixos-hardware.url = "github:nixos/nixos-hardware"; - - nixos-generators.url = "github:nix-community/nixos-generators"; + inputs = { + flake-compat = { + url = "github:edolstra/flake-compat"; + flake = false; }; - outputs = - { self - , digga - , nixos - , home - , nixos-hardware - , nur - , agenix - , nvfetcher - , deploy - , nixpkgs - , ... - } @ inputs: + # Track channels with commits tested and built by hydra + nixos.url = "github:nixos/nixpkgs/nixos-22.05"; + latest.url = "github:nixos/nixpkgs/nixos-unstable"; + # For darwin hosts: it can be helpful to track this darwin-specific stable + # channel equivalent to the `nixos-*` channels for NixOS. For one, these + # channels are more likely to provide cached binaries for darwin systems. + # But, perhaps even more usefully, it provides a place for adding + # darwin-specific overlays and packages which could otherwise cause build + # failures on Linux systems. + nixpkgs-darwin-stable.url = "github:NixOS/nixpkgs/nixpkgs-22.05-darwin"; + + 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"; + + home.url = "github:nix-community/home-manager/release-22.05"; + home.inputs.nixpkgs.follows = "nixos"; + + darwin.url = "github:LnL7/nix-darwin"; + darwin.inputs.nixpkgs.follows = "nixpkgs-darwin-stable"; + + deploy.url = "github:serokell/deploy-rs"; + deploy.inputs.nixpkgs.follows = "nixos"; + + agenix.url = "github:ryantm/agenix"; + agenix.inputs.nixpkgs.follows = "nixos"; + + nvfetcher.url = "github:berberman/nvfetcher"; + nvfetcher.inputs.nixpkgs.follows = "nixos"; + + naersk.url = "github:nmattia/naersk"; + naersk.inputs.nixpkgs.follows = "nixos"; + + nixos-hardware.url = "github:nixos/nixos-hardware"; + + nixos-generators.url = "github:nix-community/nixos-generators"; + }; + + outputs = { + self, + digga, + nixos, + home, + nixos-hardware, + nur, + agenix, + nvfetcher, + deploy, + nixpkgs, + ... + } @ inputs: digga.lib.mkFlake - { - inherit self inputs; + { + inherit self inputs; - channelsConfig = { allowUnfree = true; }; - - channels = { - nixos = { - imports = [ (digga.lib.importOverlays ./overlays) ]; - overlays = [ ]; - }; - nixpkgs-darwin-stable = { - imports = [ (digga.lib.importOverlays ./overlays) ]; - overlays = [ - # TODO: restructure overlays directory for per-channel overrides - # `importOverlays` will import everything under the path given - (channels: final: prev: { - inherit (channels.latest) mas; - } // prev.lib.optionalAttrs true { }) - ]; - }; - latest = { }; - }; - - lib = import ./lib { lib = digga.lib // nixos.lib; }; - - sharedOverlays = [ - (final: prev: { - __dontExport = true; - lib = prev.lib.extend (lfinal: lprev: { - our = self.lib; - }); - }) - - nur.overlay - agenix.overlay - nvfetcher.overlay - - (import ./pkgs) - ]; + channelsConfig = {allowUnfree = true;}; + channels = { 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 - ]; - }; + imports = [(digga.lib.importOverlays ./overlays)]; + overlays = []; + }; + nixpkgs-darwin-stable = { + imports = [(digga.lib.importOverlays ./overlays)]; + overlays = [ + # TODO: restructure overlays directory for per-channel overrides + # `importOverlays` will import everything under the path given + (channels: final: prev: + { + inherit (channels.latest) mas; + } + // prev.lib.optionalAttrs true {}) + ]; + }; + latest = {}; + }; - imports = [ (digga.lib.importHosts ./hosts/nixos) ]; - hosts = { - /* set host-specific properties here */ - NixOS = { }; - }; - importables = rec { - profiles = digga.lib.rakeLeaves ./profiles // { + lib = import ./lib {lib = digga.lib // nixos.lib;}; + + sharedOverlays = [ + (final: prev: { + __dontExport = true; + lib = prev.lib.extend (lfinal: lprev: { + our = self.lib; + }); + }) + + nur.overlay + agenix.overlay + nvfetcher.overlay + + (import ./pkgs) + ]; + + 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 + ]; + }; + + imports = [(digga.lib.importHosts ./hosts/nixos)]; + 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.nixos users.nixos users.root ]; - }; + suites = with profiles; rec { + base = [core.nixos users.nixos users.root]; }; }; + }; - darwin = { - hostDefaults = { - system = "x86_64-darwin"; - channelName = "nixpkgs-darwin-stable"; - imports = [ (digga.lib.importExportableModules ./modules) ]; - modules = [ - { lib.our = self.lib; } - digga.darwinModules.nixConfig - home.darwinModules.home-manager - agenix.nixosModules.age - ]; - }; + darwin = { + hostDefaults = { + system = "x86_64-darwin"; + channelName = "nixpkgs-darwin-stable"; + imports = [(digga.lib.importExportableModules ./modules)]; + modules = [ + {lib.our = self.lib;} + digga.darwinModules.nixConfig + home.darwinModules.home-manager + agenix.nixosModules.age + ]; + }; - imports = [ (digga.lib.importHosts ./hosts/darwin) ]; - hosts = { - /* set host-specific properties here */ - Mac = { }; - }; - importables = rec { - profiles = digga.lib.rakeLeaves ./profiles // { + imports = [(digga.lib.importHosts ./hosts/darwin)]; + hosts = { + /* + set host-specific properties here + */ + Mac = {}; + }; + importables = rec { + profiles = + digga.lib.rakeLeaves ./profiles + // { users = digga.lib.rakeLeaves ./users; }; - suites = with profiles; rec { - base = [ core.darwin users.darwin ]; - }; + suites = with profiles; rec { + base = [core.darwin users.darwin]; }; }; + }; - 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 = { - # TODO: does this naming convention still make sense with darwin support? - # - # - it doesn't make sense to make a 'nixos' user available on - # darwin, and vice versa - # - # - the 'nixos' user might have special significance as the default - # user for fresh systems - # - # - perhaps a system-agnostic home-manager user is more appropriate? - # something like 'primaryuser'? - # - # all that said, these only exist within the `hmUsers` attrset, so - # it could just be left to the developer to determine what's - # appropriate. after all, configuring these hm users is one of the - # first steps in customizing the template. - nixos = { suites, ... }: { imports = suites.base; }; - darwin = { suites, ... }: { imports = suites.base; }; - }; # digga.lib.importers.rakeLeaves ./users/hm; }; + users = { + # TODO: does this naming convention still make sense with darwin support? + # + # - it doesn't make sense to make a 'nixos' user available on + # darwin, and vice versa + # + # - the 'nixos' user might have special significance as the default + # user for fresh systems + # + # - perhaps a system-agnostic home-manager user is more appropriate? + # something like 'primaryuser'? + # + # all that said, these only exist within the `hmUsers` attrset, so + # it could just be left to the developer to determine what's + # appropriate. after all, configuring these hm users is one of the + # first steps in customizing the template. + nixos = {suites, ...}: {imports = suites.base;}; + darwin = {suites, ...}: {imports = suites.base;}; + }; # digga.lib.importers.rakeLeaves ./users/hm; + }; - devshell = ./shell; + devshell = ./shell; - # TODO: similar to the above note: does it make sense to make all of - # these users available on all systems? - homeConfigurations = digga.lib.mergeAny - (digga.lib.mkHomeConfigurations self.darwinConfigurations) - (digga.lib.mkHomeConfigurations self.nixosConfigurations) - ; + # TODO: similar to the above note: does it make sense to make all of + # these users available on all systems? + homeConfigurations = + digga.lib.mergeAny + (digga.lib.mkHomeConfigurations self.darwinConfigurations) + (digga.lib.mkHomeConfigurations self.nixosConfigurations); - deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations { }; - - } - ; + deploy.nodes = digga.lib.mkDeployNodes self.nixosConfigurations {}; + }; } diff --git a/examples/devos/hosts/darwin/Mac.nix b/examples/devos/hosts/darwin/Mac.nix index 80fb079..73aee0b 100644 --- a/examples/devos/hosts/darwin/Mac.nix +++ b/examples/devos/hosts/darwin/Mac.nix @@ -1,8 +1,10 @@ -{ config, pkgs, suites, ... }: - { - imports = with suites; - base; + config, + pkgs, + suites, + ... +}: { + imports = with suites; base; # The `mas` package is included here as a test for platform-specific package # support in Digga. Feel free to remove it in your config. diff --git a/examples/devos/hosts/nixos/NixOS.nix b/examples/devos/hosts/nixos/NixOS.nix index 3b08411..7c1fc35 100644 --- a/examples/devos/hosts/nixos/NixOS.nix +++ b/examples/devos/hosts/nixos/NixOS.nix @@ -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";}; } diff --git a/examples/devos/hosts/nixos/bootstrap.nix b/examples/devos/hosts/nixos/bootstrap.nix index 1f89337..f6b8e34 100644 --- a/examples/devos/hosts/nixos/bootstrap.nix +++ b/examples/devos/hosts/nixos/bootstrap.nix @@ -1,5 +1,4 @@ -{ profiles, ... }: -{ +{profiles, ...}: { imports = [ # profiles.networking profiles.core.nixos @@ -10,5 +9,5 @@ boot.loader.systemd-boot.enable = true; # Required, but will be overridden in the resulting installer ISO. - fileSystems."/" = { device = "/dev/disk/by-label/nixos"; }; + fileSystems."/" = {device = "/dev/disk/by-label/nixos";}; } diff --git a/examples/devos/lib/compat/default.nix b/examples/devos/lib/compat/default.nix index ae3b442..fc1bc0c 100644 --- a/examples/devos/lib/compat/default.nix +++ b/examples/devos/lib/compat/default.nix @@ -1,6 +1,10 @@ let - lock = builtins.fromJSON (builtins.readFile builtins.path { path = ../../flake.lock; name = "lockPath"; }); - flake = (import + lock = builtins.fromJSON (builtins.readFile builtins.path { + path = ../../flake.lock; + name = "lockPath"; + }); + flake = + import ( fetchTarball { url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; @@ -8,7 +12,10 @@ let } ) { - src = builtins.path { path = ../../.; name = "projectRoot"; }; - }); + src = builtins.path { + path = ../../.; + name = "projectRoot"; + }; + }; in -flake + flake diff --git a/examples/devos/lib/compat/nixos/default.nix b/examples/devos/lib/compat/nixos/default.nix index e4e0e68..c7040a6 100644 --- a/examples/devos/lib/compat/nixos/default.nix +++ b/examples/devos/lib/compat/nixos/default.nix @@ -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 diff --git a/examples/devos/lib/default.nix b/examples/devos/lib/default.nix index 2356e1f..9bc86f1 100644 --- a/examples/devos/lib/default.nix +++ b/examples/devos/lib/default.nix @@ -1,2 +1,2 @@ -{ lib }: -lib.makeExtensible (self: { }) +{lib}: +lib.makeExtensible (self: {}) diff --git a/examples/devos/modules/hm-system-defaults.nix b/examples/devos/modules/hm-system-defaults.nix index 09afddc..86a9e9c 100644 --- a/examples/devos/modules/hm-system-defaults.nix +++ b/examples/devos/modules/hm-system-defaults.nix @@ -1,11 +1,15 @@ -{ config, pkgs, ... }: { +{ + config, + pkgs, + ... +}: { home-manager.sharedModules = [ { home.sessionVariables = { # environment.sessionVariables is not currently available in nix-darwin - NIX_PATH = config.environment.sessionVariables.NIX_PATH - or config.environment.variables.NIX_PATH - ; + NIX_PATH = + config.environment.sessionVariables.NIX_PATH + or config.environment.variables.NIX_PATH; }; xdg.configFile."nix/registry.json".text = config.environment.etc."nix/registry.json".text; diff --git a/examples/devos/modules/nix-path.nix b/examples/devos/modules/nix-path.nix index 273f67a..5967fd2 100644 --- a/examples/devos/modules/nix-path.nix +++ b/examples/devos/modules/nix-path.nix @@ -1,4 +1,8 @@ -{ channel, inputs, ... }: { +{ + channel, + inputs, + ... +}: { nix.nixPath = [ "nixpkgs=${channel.input}" "nixos-config=${../lib/compat/nixos}" diff --git a/examples/devos/overlays/manix.nix b/examples/devos/overlays/manix.nix index d39baa7..c98724b 100644 --- a/examples/devos/overlays/manix.nix +++ b/examples/devos/overlays/manix.nix @@ -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; }); } diff --git a/examples/devos/overlays/overrides.nix b/examples/devos/overlays/overrides.nix index 77d55ee..f6ae5a3 100644 --- a/examples/devos/overlays/overrides.nix +++ b/examples/devos/overlays/overrides.nix @@ -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 + ; + }); }); } diff --git a/examples/devos/pkgs/_sources/generated.nix b/examples/devos/pkgs/_sources/generated.nix index 71be396..9c81f22 100644 --- a/examples/devos/pkgs/_sources/generated.nix +++ b/examples/devos/pkgs/_sources/generated.nix @@ -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"; diff --git a/examples/devos/pkgs/default.nix b/examples/devos/pkgs/default.nix index 924a230..1addf90 100644 --- a/examples/devos/pkgs/default.nix +++ b/examples/devos/pkgs/default.nix @@ -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` } diff --git a/examples/devos/profiles/cachix/default.nix b/examples/devos/profiles/cachix/default.nix index d88a3f7..636d357 100644 --- a/examples/devos/profiles/cachix/default.nix +++ b/examples/devos/profiles/cachix/default.nix @@ -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/"]; } diff --git a/examples/devos/profiles/core/common.nix b/examples/devos/profiles/core/common.nix index 9cfca96..c5b4357 100644 --- a/examples/devos/profiles/core/common.nix +++ b/examples/devos/profiles/core/common.nix @@ -1,16 +1,17 @@ -{ self, config, lib, pkgs, ... }: - -let +{ + self, + config, + lib, + pkgs, + ... +}: let inherit (lib) fileContents; inherit (pkgs.stdenv.hostPlatform) isDarwin; -in - -{ +in { # Sets nrdxp.cachix.org binary cache which just speeds up some builds - imports = [ ../cachix ]; + imports = [../cachix]; environment = { - # Selection of sysadmin tools that can come in handy systemPackages = with pkgs; [ alejandra @@ -42,57 +43,53 @@ in } ''; - shellAliases = - let - # The `security.sudo.enable` option does not exist on darwin because - # sudo is always available. - ifSudo = lib.mkIf (isDarwin || config.security.sudo.enable); - in - { - # quick cd - ".." = "cd .."; - "..." = "cd ../.."; - "...." = "cd ../../.."; - "....." = "cd ../../../.."; + shellAliases = let + # The `security.sudo.enable` option does not exist on darwin because + # sudo is always available. + ifSudo = lib.mkIf (isDarwin || 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 - # TODO: explain this hard-coded IP address - myip = "dig +short myip.opendns.com @208.67.222.222 2>&1"; + # internet ip + # TODO: explain this hard-coded IP address + 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 ''"; - srch = "ns nixos"; - orch = "ns override"; - mn = '' - manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | sk --preview="manix '{}'" | xargs manix - ''; - top = "btm"; + # 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 ''"; + srch = "ns nixos"; + orch = "ns override"; + mn = '' + manix "" | grep '^# ' | sed 's/^# \(.*\) (.*/\1/;s/ (.*//;s/^# //' | sk --preview="manix '{}'" | xargs manix + ''; + top = "btm"; - # sudo - s = ifSudo "sudo -E "; - si = ifSudo "sudo -i"; - se = ifSudo "sudoedit"; - - }; + # sudo + s = ifSudo "sudo -E "; + si = ifSudo "sudo -i"; + se = ifSudo "sudoedit"; + }; }; - fonts.fonts = with pkgs; [ powerline-fonts dejavu_fonts ]; + fonts.fonts = with pkgs; [powerline-fonts dejavu_fonts]; nix = { - # Improve nix store disk usage gc.automatic = true; @@ -100,7 +97,7 @@ in useSandbox = true; # Give root user and wheel group special Nix privileges. - trustedUsers = [ "root" "@wheel" ]; + trustedUsers = ["root" "@wheel"]; # Generally useful nix option defaults extraOptions = '' @@ -109,7 +106,5 @@ in keep-derivations = true fallback = true ''; - }; - } diff --git a/examples/devos/profiles/core/darwin.nix b/examples/devos/profiles/core/darwin.nix index 88123eb..f8a55ab 100644 --- a/examples/devos/profiles/core/darwin.nix +++ b/examples/devos/profiles/core/darwin.nix @@ -1,6 +1,10 @@ -{ self, config, lib, pkgs, ... }: - { + self, + config, + lib, + pkgs, + ... +}: { imports = [ ./common.nix ]; @@ -12,7 +16,6 @@ users.nix.configureBuildUsers = true; environment = { - systemPackages = with pkgs; [ m-cli terminal-notifier @@ -23,11 +26,9 @@ shellAliases = { nrb = "sudo darwin-rebuild switch --flake"; }; - }; nix = { - nixPath = [ # TODO: This entry should be added automatically via FUP's # `nix.linkInputs` and `nix.generateNixPathFromInputs` options, but @@ -42,8 +43,7 @@ ]; # Administrative users on Darwin are part of this group. - trustedUsers = [ "@admin" ]; - + trustedUsers = ["@admin"]; }; programs.bash = { @@ -57,5 +57,4 @@ eval "$(${pkgs.direnv}/bin/direnv hook bash)" ''; }; - } diff --git a/examples/devos/profiles/core/nixos.nix b/examples/devos/profiles/core/nixos.nix index 8fac9f9..2a69ad9 100644 --- a/examples/devos/profiles/core/nixos.nix +++ b/examples/devos/profiles/core/nixos.nix @@ -1,15 +1,18 @@ -{ config, lib, pkgs, self, ... }: - { + config, + lib, + pkgs, + self, + ... +}: { imports = [ ./common.nix ]; # 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; [ dosfstools @@ -19,37 +22,37 @@ utillinux ]; - shellAliases = - let ifSudo = lib.mkIf config.security.sudo.enable; in - { - # nix - nrb = ifSudo "sudo nixos-rebuild"; + shellAliases = let + ifSudo = lib.mkIf config.security.sudo.enable; + in { + # nix + nrb = ifSudo "sudo nixos-rebuild"; - # fix nixos-option for flake compat - nixos-option = "nixos-option -I nixpkgs=${self}/lib/compat"; + # fix nixos-option for flake compat + nixos-option = "nixos-option -I nixpkgs=${self}/lib/compat"; - # 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.fontconfig.defaultFonts = { - monospace = [ "DejaVu Sans Mono for Powerline" ]; - sansSerif = [ "DejaVu Sans" ]; + monospace = ["DejaVu Sans Mono for Powerline"]; + sansSerif = ["DejaVu Sans"]; }; nix = { # Improve nix store disk usage autoOptimiseStore = true; optimise.automatic = true; - allowedUsers = [ "@wheel" ]; + allowedUsers = ["@wheel"]; }; programs.bash = { @@ -71,5 +74,4 @@ # Service that makes Out of Memory Killer more effective services.earlyoom.enable = true; - } diff --git a/examples/devos/secrets/secrets.nix b/examples/devos/secrets/secrets.nix index bac30e0..641ef20 100644 --- a/examples/devos/secrets/secrets.nix +++ b/examples/devos/secrets/secrets.nix @@ -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; } diff --git a/examples/devos/shell/default.nix b/examples/devos/shell/default.nix index 5a9ce56..3b1fadc 100644 --- a/examples/devos/shell/default.nix +++ b/examples/devos/shell/default.nix @@ -1,8 +1,10 @@ -{ self, inputs, ... }: { + self, + inputs, + ... +}: { modules = with inputs; []; exportedModules = [ ./devos.nix ]; } - diff --git a/examples/devos/shell/devos.nix b/examples/devos/shell/devos.nix index b202012..39fd5ed 100644 --- a/examples/devos/shell/devos.nix +++ b/examples/devos/shell/devos.nix @@ -1,7 +1,12 @@ -{ pkgs, extraModulesPath, inputs, lib, ... }: -let - - inherit (pkgs) +{ + pkgs, + extraModulesPath, + inputs, + lib, + ... +}: let + inherit + (pkgs) agenix cachix editorconfig-checker @@ -13,39 +18,37 @@ let hooks = import ./hooks; - pkgWithCategory = category: package: { inherit package category; }; + pkgWithCategory = category: package: {inherit package category;}; devos = pkgWithCategory "devos"; linter = pkgWithCategory "linter"; docs = pkgWithCategory "docs"; - -in -{ +in { _file = toString ./.; - imports = [ "${extraModulesPath}/git/hooks.nix" ]; - git = { inherit hooks; }; + imports = ["${extraModulesPath}/git/hooks.nix"]; + git = {inherit hooks;}; - commands = [ - (devos nixUnstable) - (devos agenix) + commands = + [ + (devos nixUnstable) + (devos agenix) - { - category = "devos"; - name = nvfetcher-bin.pname; - help = nvfetcher-bin.meta.description; - command = "cd $PRJ_ROOT/pkgs; ${nvfetcher-bin}/bin/nvfetcher -c ./sources.toml $@"; - } - (linter treefmt) - (linter editorconfig-checker) + { + category = "devos"; + name = nvfetcher-bin.pname; + help = nvfetcher-bin.meta.description; + command = "cd $PRJ_ROOT/pkgs; ${nvfetcher-bin}/bin/nvfetcher -c ./sources.toml $@"; + } + (linter treefmt) + (linter editorconfig-checker) - (docs mdbook) - ] - ++ lib.optionals (!pkgs.stdenv.buildPlatform.isi686) [ - (devos cachix) - ] - ++ lib.optionals (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin) [ - (devos inputs.nixos-generators.defaultPackage.${pkgs.system}) - (devos inputs.deploy.packages.${pkgs.system}.deploy-rs) - ] - ; + (docs mdbook) + ] + ++ lib.optionals (!pkgs.stdenv.buildPlatform.isi686) [ + (devos cachix) + ] + ++ lib.optionals (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin) [ + (devos inputs.nixos-generators.defaultPackage.${pkgs.system}) + (devos inputs.deploy.packages.${pkgs.system}.deploy-rs) + ]; } diff --git a/examples/devos/users/darwin/default.nix b/examples/devos/users/darwin/default.nix index a268b8a..45d18c9 100644 --- a/examples/devos/users/darwin/default.nix +++ b/examples/devos/users/darwin/default.nix @@ -1,6 +1,5 @@ -{ hmUsers, ... }: -{ - home-manager.users = { inherit (hmUsers) darwin; }; +{hmUsers, ...}: { + home-manager.users = {inherit (hmUsers) darwin;}; users.users.darwin = { description = "default"; diff --git a/examples/devos/users/nixos/default.nix b/examples/devos/users/nixos/default.nix index 077a52e..2b13833 100644 --- a/examples/devos/users/nixos/default.nix +++ b/examples/devos/users/nixos/default.nix @@ -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"]; }; } diff --git a/examples/devos/users/profiles/git/default.nix b/examples/devos/users/profiles/git/default.nix index 4c9637e..f827f5b 100644 --- a/examples/devos/users/profiles/git/default.nix +++ b/examples/devos/users/profiles/git/default.nix @@ -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 diff --git a/examples/devos/users/root/default.nix b/examples/devos/users/root/default.nix index f38c739..c9f1ef7 100644 --- a/examples/devos/users/root/default.nix +++ b/examples/devos/users/root/default.nix @@ -1,4 +1,4 @@ -{ ... }: +{...}: # recommend using `hashedPassword` { users.users.root.password = ""; diff --git a/examples/groupByConfig/darwin/Darwinia.nix b/examples/groupByConfig/darwin/Darwinia.nix index a1d9a82..ecdcee5 100644 --- a/examples/groupByConfig/darwin/Darwinia.nix +++ b/examples/groupByConfig/darwin/Darwinia.nix @@ -1,11 +1,16 @@ -{ lib, pkgs, config, suites, ... }: { +{ + lib, + pkgs, + config, + suites, + ... +}: { # TODO: remove manually-imported suites and profiles once custom test support # is added for darwin - imports = with suites; - base; + imports = with suites; base; # On Darwin, admins are added to the `admin` group. - nix.trustedUsers = [ "@admin" "sosumi" ]; + nix.trustedUsers = ["@admin" "sosumi"]; # https://daiderd.com/nix-darwin/manual/index.html#opt-system.stateVersion system.stateVersion = 4; diff --git a/examples/groupByConfig/darwin/default.nix b/examples/groupByConfig/darwin/default.nix index d748ac0..31a5eee 100644 --- a/examples/groupByConfig/darwin/default.nix +++ b/examples/groupByConfig/darwin/default.nix @@ -1,27 +1,27 @@ -{ self, inputs, ... }: - -let - inherit (inputs.digga.lib) allProfilesTest; -in - { + self, + inputs, + ... +}: let + inherit (inputs.digga.lib) allProfilesTest; +in { hostDefaults = { channelName = "nixpkgs-darwin-stable"; }; hosts = { Darwinia = { - modules = [ ./Darwinia.nix ]; + modules = [./Darwinia.nix]; # TODO: add custom test support for darwin hosts # tests = [ allProfilesTest ]; - tests = [ ]; + tests = []; }; }; importables = rec { suites = rec { - base = [ ]; + base = []; }; }; } diff --git a/examples/groupByConfig/devshell/default.nix b/examples/groupByConfig/devshell/default.nix index 40c2d35..be68d4a 100644 --- a/examples/groupByConfig/devshell/default.nix +++ b/examples/groupByConfig/devshell/default.nix @@ -1,4 +1,3 @@ -{ self, ... }: -{ - exportedModules = [ ./python.toml ]; +{self, ...}: { + exportedModules = [./python.toml]; } diff --git a/examples/groupByConfig/flake.nix b/examples/groupByConfig/flake.nix index aba49a7..af08e20 100644 --- a/examples/groupByConfig/flake.nix +++ b/examples/groupByConfig/flake.nix @@ -23,29 +23,27 @@ home.inputs.nixpkgs.follows = "nixos"; }; - outputs = - inputs @ { self - , nixos - , nixpkgs - , nixpkgs-darwin-stable - , darwin - , digga - , home - , ... - }: + outputs = inputs @ { + self, + nixos, + nixpkgs, + nixpkgs-darwin-stable, + darwin, + digga, + home, + ... + }: digga.lib.mkFlake { - inherit self inputs; channels = { - nixos = { }; - nixpkgs-darwin-stable = { }; + nixos = {}; + nixpkgs-darwin-stable = {}; }; nixos = ./nixos; darwin = ./darwin; home = ./home; devshell = ./devshell; - }; } diff --git a/examples/groupByConfig/home/default.nix b/examples/groupByConfig/home/default.nix index 1b4c3c9..03d2403 100644 --- a/examples/groupByConfig/home/default.nix +++ b/examples/groupByConfig/home/default.nix @@ -1,7 +1,5 @@ -{ self, ... }: -let +{self, ...}: let lib = self.inputs.digga.lib; -in -{ - imports = [ (lib.importExportableModules ./modules) ]; +in { + imports = [(lib.importExportableModules ./modules)]; } diff --git a/examples/groupByConfig/home/modules/my-home.nix b/examples/groupByConfig/home/modules/my-home.nix index 4c9637e..f827f5b 100644 --- a/examples/groupByConfig/home/modules/my-home.nix +++ b/examples/groupByConfig/home/modules/my-home.nix @@ -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 diff --git a/examples/groupByConfig/nixos/Morty.nix b/examples/groupByConfig/nixos/Morty.nix index f20cd47..e2da9d9 100644 --- a/examples/groupByConfig/nixos/Morty.nix +++ b/examples/groupByConfig/nixos/Morty.nix @@ -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 = ""; } diff --git a/examples/groupByConfig/nixos/default.nix b/examples/groupByConfig/nixos/default.nix index eed4a9e..1ab77a5 100644 --- a/examples/groupByConfig/nixos/default.nix +++ b/examples/groupByConfig/nixos/default.nix @@ -1,24 +1,24 @@ -{ 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 ]; - tests = [ allProfilesTest ]; + modules = [./Morty.nix]; + tests = [allProfilesTest]; }; }; importables = rec { suites = rec { - base = [ ]; + base = []; }; }; } diff --git a/examples/hmOnly/flake.nix b/examples/hmOnly/flake.nix index 0e30d3e..3334fb2 100644 --- a/examples/hmOnly/flake.nix +++ b/examples/hmOnly/flake.nix @@ -10,16 +10,19 @@ 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; - }; } diff --git a/examples/hmOnly/home/default.nix b/examples/hmOnly/home/default.nix index dca6c35..94ee8cd 100644 --- a/examples/hmOnly/home/default.nix +++ b/examples/hmOnly/home/default.nix @@ -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; diff --git a/examples/hmOnly/home/users/testuser.nix b/examples/hmOnly/home/users/testuser.nix index 34e42c0..5d10687 100644 --- a/examples/hmOnly/home/users/testuser.nix +++ b/examples/hmOnly/home/users/testuser.nix @@ -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; }; } - diff --git a/flake.nix b/flake.nix index 93e6130..9257004 100644 --- a/flake.nix +++ b/flake.nix @@ -5,151 +5,149 @@ 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-22.05"; - nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; + inputs = { + # Track channels with commits tested and built by hydra + nixpkgs.url = "github:nixos/nixpkgs/nixos-22.05"; + nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable"; - nixlib.url = "github:nix-community/nixpkgs.lib"; + nixlib.url = "github:nix-community/nixpkgs.lib"; - 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-22.05"; - home-manager.inputs.nixpkgs.follows = "nixlib"; + home-manager.url = "github:nix-community/home-manager/release-22.05"; + home-manager.inputs.nixpkgs.follows = "nixlib"; - darwin.url = "github:LnL7/nix-darwin"; - darwin.inputs.nixpkgs.follows = "nixpkgs"; + darwin.url = "github:LnL7/nix-darwin"; + darwin.inputs.nixpkgs.follows = "nixpkgs"; - devshell.url = "github:numtide/devshell"; - devshell.inputs.nixpkgs.follows = "nixpkgs"; + devshell.url = "github:numtide/devshell"; + devshell.inputs.nixpkgs.follows = "nixpkgs"; - flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/?ref=refs/pull/120/head"; + flake-utils-plus.url = "github:gytis-ivaskevicius/flake-utils-plus/?ref=refs/pull/120/head"; - 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, + darwin, + 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 - , darwin - , home-manager - , ... - }@inputs: - let + importers = import ./src/importers.nix { + inherit (nixlib) lib; + }; - tests = import ./src/tests.nix { inherit (nixlib) lib; }; + collectors = import ./src/collectors.nix { + inherit (nixlib) lib; + }; - internal-modules = import ./src/modules.nix { + generators = import ./src/generators.nix { + inherit (nixlib) lib; + inherit deploy; + }; + + mkFlake = let + mkFlake' = import ./src/mkFlake { inherit (nixlib) lib; + inherit (flake-utils-plus.inputs) flake-utils; + inherit + collectors + darwin + 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# - collectors = import ./src/collectors.nix { - inherit (nixlib) lib; - }; + # Super Stupid Flakes (ssf) / System As an Input - Style: + supportedSystems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin"]; - generators = import ./src/generators.nix { - inherit (nixlib) lib; - inherit deploy; - }; - - mkFlake = - let - mkFlake' = import ./src/mkFlake { - inherit (nixlib) lib; - inherit (flake-utils-plus.inputs) flake-utils; - inherit - collectors - darwin - 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 importers; - }; + # DEPRECATED - will be removed timely + deprecated = import ./deprecated.nix { + inherit (nixlib) lib; + inherit 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 mergeAny; + inherit mkFlake; + inherit (tests) mkTest allProfilesTest; + inherit (importers) flattenTree rakeLeaves importOverlays importExportableModules importHosts; + inherit (generators) mkDeployNodes mkHomeConfigurations; + inherit + (collectors) + collectHosts + collectHostsOnSystem + ; - 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 mergeAny; - inherit mkFlake; - inherit (tests) mkTest allProfilesTest; - inherit (importers) flattenTree rakeLeaves importOverlays importExportableModules importHosts; - inherit (generators) mkDeployNodes mkHomeConfigurations; - inherit (collectors) - collectHosts - collectHostsOnSystem - ; - - # 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/nixos-modules.nix; - darwinModules = import ./modules/darwin-modules.nix; - - 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 - ## This doesn't appear to be used? - formatter = nixlib.lib.genAttrs supportedSystems (s: nixpkgs.legacyPackages.${s}.treefmt); - # 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/nixos-modules.nix; + darwinModules = import ./modules/darwin-modules.nix; + + 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 + ## This doesn't appear to be used? + formatter = nixlib.lib.genAttrs supportedSystems (s: nixpkgs.legacyPackages.${s}.treefmt); + # system-space and pass sytem and input to each file + jobs = polyfillOutput ./jobs; + checks = polyfillOutput ./checks; + devShell = polyfillOutput ./devShell.nix; + }; } diff --git a/jobs/default.nix b/jobs/default.nix index 03662a7..6d7f774 100644 --- a/jobs/default.nix +++ b/jobs/default.nix @@ -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: @@ -32,17 +32,19 @@ in - [NixOS](./api-reference-nixos.md) - [Darwin](./api-reference-darwin.md) - ${( pkgs.nixosOptionsDoc { + ${(pkgs.nixosOptionsDoc { options = { - inherit (evaledOptions) + inherit + (evaledOptions) channelsConfig self inputs outputsBuilder supportedSystems - ; + ; }; - }).optionsMDDoc} + }) + .optionsMDDoc} ''; mkApiReferenceChannels = mkDocPartMd "channels" "Channels API Container" '' @@ -64,5 +66,4 @@ in mkApiReferenceDarwin = mkDocPartMd "darwin" "Darwin API Container" '' Configure your darwin/macOS modules, profiles & suites. ''; - } diff --git a/modules/bootstrap-iso.nix b/modules/bootstrap-iso.nix index 72fcb6f..3749557 100644 --- a/modules/bootstrap-iso.nix +++ b/modules/bootstrap-iso.nix @@ -1,29 +1,39 @@ let - getFqdn = config: - let - net = config.networking; - fqdn = - if (net ? domain) && (net.domain != null) - then "${net.hostName}.${net.domain}" - else net.hostName; - in + getFqdn = config: let + net = config.networking; + fqdn = + if (net ? domain) && (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; + }; + } diff --git a/modules/nix-config.nix b/modules/nix-config.nix index 8ce0429..7d7d2c0 100644 --- a/modules/nix-config.nix +++ b/modules/nix-config.nix @@ -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} ''; } diff --git a/overlays/default.nix b/overlays/default.nix index 7f0c7a0..3d56e48 100644 --- a/overlays/default.nix +++ b/overlays/default.nix @@ -1 +1 @@ -{ inputs }: { } +{inputs}: {} diff --git a/shell.nix b/shell.nix index 20950e0..b2a8bc1 100644 --- a/shell.nix +++ b/shell.nix @@ -1 +1 @@ -import ./devShell.nix { } +import ./devShell.nix {} diff --git a/src/collectors.nix b/src/collectors.nix index 37c428a..d9c9422 100644 --- a/src/collectors.nix +++ b/src/collectors.nix @@ -1,34 +1,38 @@ -{ lib }: -let +{lib}: let collectHosts = nixosConfigurations: darwinConfigurations: - /** - Synopsis: collectHosts _nixosConfigurations_ _darwinConfigurations_ - - Collect all hosts across NixOS and Darwin configurations, validating for - unique hostnames to prevent collisions. - **/ - (nixosConfigurations // lib.mapAttrs - (name: value: + /* + * + Synopsis: collectHosts _nixosConfigurations_ _darwinConfigurations_ + + Collect all hosts across NixOS and Darwin configurations, validating for + unique hostnames to prevent collisions. + * + */ + (nixosConfigurations + // lib.mapAttrs + ( + name: value: if builtins.hasAttr name nixosConfigurations then throw '' Hostnames must be unique across all platforms! Found a duplicate host config for '${name}'. '' else value - ) - darwinConfigurations); -in -{ + ) + darwinConfigurations); +in { inherit collectHosts; collectHostsOnSystem = hostConfigurations: system: - /** - Synopsis: collectHostsOnSystem _hostConfigurations_ _system_ - - Filter a set of host configurations to those matching a given system. - **/ - let - systemSieve = _: host: host.config.nixpkgs.system == system; - in + /* + * + Synopsis: collectHostsOnSystem _hostConfigurations_ _system_ + + Filter a set of host configurations to those matching a given system. + * + */ + let + systemSieve = _: host: host.config.nixpkgs.system == system; + in lib.filterAttrs systemSieve hostConfigurations; } diff --git a/src/generators.nix b/src/generators.nix index 0011002..60e841b 100644 --- a/src/generators.nix +++ b/src/generators.nix @@ -1,82 +1,83 @@ -{ lib, deploy }: -let - getFqdn = c: - let - net = c.config.networking; - fqdn = - if (net ? domain) && (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) && (net.domain != null) + then "${net.hostName}.${net.domain}" + else net.hostName; + in + fqdn; +in { mkHomeConfigurations = systemConfigurations: - /** - Synopsis: mkHomeConfigurations _systemConfigurations_ - - Generate the `homeConfigurations` attribute expected by `home-manager` cli - from _nixosConfigurations_ or _darwinConfigurations_ 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 _systemConfigurations_ + + Generate the `homeConfigurations` attribute expected by `home-manager` cli + from _nixosConfigurations_ or _darwinConfigurations_ 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 systemConfigurations); mkDeployNodes = systemConfigurations: extraConfig: - /** - Synopsis: mkNodes _systemConfigurations_ _extraConfig_ - - Generate the `nodes` attribute expected by deploy-rs - where _systemConfigurations_ are `nodes`. - - _systemConfigurations_ should take the form of a flake's - _nixosConfigurations_. Note that deploy-rs does not currently support - deploying to darwin hosts. - - _extraConfig_, if specified, will be merged into each of the - nodes' configurations. - - Example _systemConfigurations_ input: - - ``` - { - hostname-1 = { - fastConnection = true; - sshOpts = [ "-p" "25" ]; - }; - hostname-2 = { - sshOpts = [ "-p" "19999" ]; - sshUser = "root"; - }; - } - ``` - **/ + /* + * + Synopsis: mkNodes _systemConfigurations_ _extraConfig_ + + Generate the `nodes` attribute expected by deploy-rs + where _systemConfigurations_ are `nodes`. + + _systemConfigurations_ should take the form of a flake's + _nixosConfigurations_. Note that deploy-rs does not currently support + deploying to darwin hosts. + + _extraConfig_, if specified, will be merged into each of the + nodes' configurations. + + Example _systemConfigurations_ 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; - }; - } - ) - systemConfigurations) - extraConfig; + (lib.mapAttrs + ( + _: c: { + hostname = getFqdn c; + profiles.system = { + user = "root"; + path = deploy.lib.${c.config.nixpkgs.system}.activate.nixos c; + }; + } + ) + systemConfigurations) + extraConfig; } diff --git a/src/importers.nix b/src/importers.nix index 039ec9f..5a055bc 100644 --- a/src/importers.nix +++ b/src/importers.nix @@ -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 = ; - }; - }; - } - ``` - - Example output: - ``` - { - "a.b.c" = ; - } - ``` - **/ - 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 = ; + }; + }; + } + ``` + + Example output: + ``` + { + "a.b.c" = ; + } + ``` + * + */ + 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)); + }; } - diff --git a/src/mkFlake/default.nix b/src/mkFlake/default.nix index 8645b94..dbe4179 100644 --- a/src/mkFlake/default.nix +++ b/src/mkFlake/default.nix @@ -1,38 +1,36 @@ -{ lib -, collectors -, darwin -, deploy -, devshell -, home-manager -, flake-utils-plus -, flake-utils -, internal-modules -, tests -} @ injectedDeps: - -{ self, inputs, ... } @ args: -let +{ + lib, + collectors, + darwin, + 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'; - } diff --git a/src/mkFlake/fup-adapter.nix b/src/mkFlake/fup-adapter.nix index cf57e32..0c7042b 100644 --- a/src/mkFlake/fup-adapter.nix +++ b/src/mkFlake/fup-adapter.nix @@ -1,17 +1,21 @@ # constructor dependencies -{ lib, self, inputs, darwin, flake-utils-plus, collectors, internal-modules, ... }: - { + lib, + self, + inputs, + darwin, + flake-utils-plus, + collectors, + 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,102 +28,122 @@ 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: - let - getChannel = inputs."${channelName}".legacyPackages.x86_64-linux; - channelName = builtins.elemAt (builtins.attrNames channels) 0; - in - map (o: if builtins.isFunction (o getChannel getChannel) then o channels else o); + unifyOverlays = channels: let + getChannel = inputs."${channelName}".legacyPackages.x86_64-linux; + channelName = builtins.elemAt (builtins.attrNames channels) 0; + in + map (o: + if builtins.isFunction (o getChannel getChannel) + 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 stripNull = args: (lib.filterAttrs (_: arg: arg != null) args); - stripHost = args: removeAttrs (stripNull args) [ - # arguments in our hosts/hostDefaults api that shouldn't be passed to fup - "externalModules" # TODO: remove deprecated option - "exportedModules" - "tests" - ]; + stripHost = args: + removeAttrs (stripNull args) [ + # arguments in our hosts/hostDefaults api that shouldn't be passed to fup + "externalModules" # TODO: remove deprecated option + "exportedModules" + "tests" + ]; - nixosHostDefaults = flake-utils-plus.lib.mergeAny + nixosHostDefaults = + flake-utils-plus.lib.mergeAny { system = "x86_64-linux"; output = "nixosConfigurations"; # add `self` & `inputs` as specialArgs so their libs can be used in imports - specialArgs = config.nixos.importables // { inherit (config) self inputs; }; + specialArgs = config.nixos.importables // {inherit (config) self inputs;}; - modules = config.nixos.hostDefaults.exportedModules ++ defaultHostModules ++ [ - internal-modules.nixosDefaults - ]; + modules = + config.nixos.hostDefaults.exportedModules + ++ defaultHostModules + ++ [ + internal-modules.nixosDefaults + ]; } (stripNull config.nixos.hostDefaults); - nixosHosts = lib.mapAttrs + nixosHosts = + lib.mapAttrs ( _: hostConfig: flake-utils-plus.lib.mergeAny - nixosHostDefaults - (stripNull hostConfig) + nixosHostDefaults + (stripNull hostConfig) ) config.nixos.hosts; - darwinHostDefaults = flake-utils-plus.lib.mergeAny + darwinHostDefaults = + flake-utils-plus.lib.mergeAny { system = "x86_64-darwin"; output = "darwinConfigurations"; builder = darwin.lib.darwinSystem; # add `self` & `inputs` as specialArgs so their libs can be used in imports - specialArgs = config.darwin.importables // { inherit (config) self inputs; }; + specialArgs = config.darwin.importables // {inherit (config) self inputs;}; modules = config.darwin.hostDefaults.exportedModules ++ defaultHostModules; } (stripNull config.darwin.hostDefaults); - darwinHosts = lib.mapAttrs + darwinHosts = + lib.mapAttrs ( - _: hostConfig: flake-utils-plus.lib.mergeAny + _: hostConfig: + flake-utils-plus.lib.mergeAny darwinHostDefaults (stripNull hostConfig) ) config.darwin.hosts; diggaFupArgs = { - inherit (config) + inherit + (config) channelsConfig - supportedSystems; + supportedSystems + ; inherit self inputs sharedOverlays; - hosts = builtins.mapAttrs (_: stripHost) + hosts = + builtins.mapAttrs (_: stripHost) (collectors.collectHosts nixosHosts darwinHosts); - 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; @@ -141,13 +165,12 @@ let outputsBuilder = channels: flake-utils-plus.lib.mergeAny - (defaultOutputsBuilder channels) - (config.outputsBuilder channels); + (defaultOutputsBuilder channels) + (config.outputsBuilder channels); }; - in -flake-utils-plus.lib.mkFlake ( - flake-utils-plus.lib.mergeAny + flake-utils-plus.lib.mkFlake ( + flake-utils-plus.lib.mergeAny diggaFupArgs extraArgs # for overlays list order -) + ) diff --git a/src/mkFlake/options.nix b/src/mkFlake/options.nix index 69e3482..b75aa1d 100644 --- a/src/mkFlake/options.nix +++ b/src/mkFlake/options.nix @@ -1,466 +1,500 @@ # constructor dependencies -{ lib, devshell, flake-utils, self, inputs, ... }: - -with lib; - -{ config, ... }: -let - cfg = config; - - # ############# - # Resolver - # ############# - - /** - Synopsis: maybeImport - - 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 - - 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 resolver: types maybeImport's . - - Use in type declarations. - **/ - pathToOr = elemType: with types; coercedTo path maybeImport elemType; - - /** - Synopsis: coercedListOf - - Type resolver & list flattner: flattens a (evtl. arbitrarily nested) list of 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."; - 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 / and any overlay pulled from - 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; } - ]; - }; - - darwinType = with types; submoduleWith { - specialArgs = { inherit self inputs; }; - modules = [ - { options = (hostsOpt "darwin") // (hostDefaultsOpt "darwin") // 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 + + 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 + + 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 resolver: types maybeImport's . + + Use in type declarations. + * + */ + pathToOr = elemType: with types; coercedTo path maybeImport elemType; + + /* + * + Synopsis: coercedListOf + + Type resolver & list flattner: flattens a (evtl. arbitrarily nested) list of 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. + ''; + }; }; - darwin = mkOption { - type = pathToOr darwinType; - default = { }; - description = '' - hosts, modules, suites, and profiles for darwin - ''; + + hostsOpt = name: { + hosts = mkOption { + type = with types; hostType; + default = {}; + description = '' + configurations to include in the ${name}Configurations output + ''; + }; }; - home = mkOption { - type = pathToOr homeType; - default = { }; - description = '' - hosts, modules, suites, and profiles for home-manager - ''; + + inputOpt = name: { + input = mkOption { + type = flakeType; + default = self.inputs.${name}; + defaultText = "self.inputs."; + description = '' + nixpkgs flake input to use for this channel + ''; + }; }; - devshell = mkOption { - type = pathToOr devshellType; - default = { }; - description = '' - Modules to include in your DevOS shell. the `modules` argument - will be exported under the `devshellModules` output - ''; + + 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 / and any overlay pulled from + 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;} + ]; + }; + + darwinType = with types; + submoduleWith { + specialArgs = {inherit self inputs;}; + modules = [ + {options = (hostsOpt "darwin") // (hostDefaultsOpt "darwin") // 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 + ''; + }; + darwin = mkOption { + type = pathToOr darwinType; + default = {}; + description = '' + hosts, modules, suites, and profiles for darwin + ''; + }; + 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 + ''; + }; + }; + } diff --git a/src/mkFlake/outputs-builder.nix b/src/mkFlake/outputs-builder.nix index ed7a9da..ef1c260 100644 --- a/src/mkFlake/outputs-builder.nix +++ b/src/mkFlake/outputs-builder.nix @@ -1,144 +1,156 @@ # constructor dependencies -{ lib, self, inputs, collectors, deploy, devshell, home-manager, flake-utils-plus, tests, ... }: -config: channels: -let - +{ + lib, + self, + inputs, + collectors, + 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 && !pkgs.stdenv.buildPlatform.isDarwin) - then { targets.genericLinux.enable = true; } - else { } - ); + configuration = + { + imports = [configuration]; + } + // ( + if (pkgs.stdenv.hostPlatform.isLinux && !pkgs.stdenv.buildPlatform.isDarwin) + then {targets.genericLinux.enable = true;} + else {} + ); }; homeConfigurationsPortable = builtins.mapAttrs - (n: v: mkPortableHomeManagerConfiguration { + (n: v: + mkPortableHomeManagerConfiguration { inherit pkgs system; username = n; configuration = v; }) - 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 # N.B. portable home configurations for Linux/NixOS hosts cannot be built on Darwin! lib.mapAttrs' collectActivationPackages homeConfigurationsPortable - else { } + else {} ) - // - ( + // ( # for self.deploy - if ( - (builtins.hasAttr "deploy" self) && - (self.deploy != { }) && - (!pkgs.stdenv.buildPlatform.isDarwin) - ) 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 != {}) + && (!pkgs.stdenv.buildPlatform.isDarwin) + ) + 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 != { }) && - (!pkgs.stdenv.buildPlatform.isDarwin) - ) then - let - hostConfigsOnThisSystem = collectors.collectHostsOnSystem self.nixosConfigurations system; + if + ( + (builtins.hasAttr "nixosConfigurations" self) + && (self.nixosConfigurations != {}) + && (!pkgs.stdenv.buildPlatform.isDarwin) + ) + then let + hostConfigsOnThisSystem = collectors.collectHostsOnSystem self.nixosConfigurations system; - createCustomTestOp = n: host: test: - lib.warnIf (!(test ? name)) '' - '${n}' has a test without a name. To distinguish tests in the flake output - all 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 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 {} + ); } diff --git a/src/modules.nix b/src/modules.nix index 28c17b0..83fcd6f 100644 --- a/src/modules.nix +++ b/src/modules.nix @@ -1,40 +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, ... }: { - # 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. - ''; - }; + globalDefaults = {hmUsers}: { + config, + pkgs, + self, + ... + }: { + # digga lib can be accessed in modules directly as config.lib.digga + lib = { + inherit (pkgs.lib) digga; }; - nixosDefaults = { self, ... }: { + _module.args = { + inherit hmUsers; + hosts = throw '' + The `hosts` module argument has been removed, you should instead use + `self.nixosConfigurations`, with the `self` module argument. + ''; + }; + }; + + nixosDefaults = {self, ...}: { users.mutableUsers = lib.mkDefault false; hardware.enableRedistributableFirmware = lib.mkDefault true; system.configurationRevision = lib.mkIf (self ? rev) self.rev; }; - } diff --git a/src/tests.nix b/src/tests.nix index 60eec47..fb5087c 100644 --- a/src/tests.nix +++ b/src/tests.nix @@ -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"; - nodes.machine = { suites ? null, ... }: { - imports = - let - allProfiles = lib.foldl - (lhs: rhs: lhs ++ rhs) [ ] - (builtins.attrValues suites); - in + nodes.machine = {suites ? null, ...}: { + imports = let + allProfiles = + lib.foldl + (lhs: rhs: lhs ++ rhs) [] + (builtins.attrValues suites); + in allProfiles; }; @@ -44,5 +37,4 @@ let machine.systemctl("is-system-running --wait") ''; }; -in -{ inherit mkTest allProfilesTest; } +in {inherit mkTest allProfilesTest;}