style: fmt

This commit is contained in:
anntnzrb
2025-10-08 21:56:09 -05:00
parent 592bb5148d
commit 9bd2ffc288
21 changed files with 1509 additions and 1308 deletions

View File

@@ -1,6 +1,4 @@
( (import (
import
(
let let
lock = builtins.fromJSON (builtins.readFile ./flake.lock); lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in in
@@ -8,7 +6,4 @@
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz"; url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash; sha256 = lock.nodes.flake-compat.locked.narHash;
} }
) ) { src = ./.; }).defaultNix
{src = ./.;}
)
.defaultNix

View File

@@ -11,13 +11,13 @@
}; };
}; };
outputs = { outputs =
{
self, self,
... ...
} @ inputs: let }@inputs:
core-inputs = let
inputs core-inputs = inputs // {
// {
src = self; src = self;
}; };
@@ -31,19 +31,25 @@
# A convenience wrapper to create the library and then call `lib.mkFlake`. # A convenience wrapper to create the library and then call `lib.mkFlake`.
# Usage: mkFlake { inherit inputs; src = ./.; ... } # Usage: mkFlake { inherit inputs; src = ./.; ... }
# result: <flake-outputs> # result: <flake-outputs>
mkFlake = flake-and-lib-options @ { mkFlake =
flake-and-lib-options@{
inputs, inputs,
src, src,
snowfall ? { }, snowfall ? { },
... ...
}: let }:
let
lib = mkLib { lib = mkLib {
inherit inputs src snowfall; inherit inputs src snowfall;
}; };
flake-options = builtins.removeAttrs flake-and-lib-options ["inputs" "src"]; flake-options = builtins.removeAttrs flake-and-lib-options [
"inputs"
"src"
];
in in
lib.mkFlake flake-options; lib.mkFlake flake-options;
in { in
{
inherit mkLib mkFlake; inherit mkLib mkFlake;
nixosModules = { nixosModules = {
@@ -80,20 +86,17 @@
}; };
}; };
internal-lib = let internal-lib =
let
lib = mkLib { lib = mkLib {
src = self; src = self;
inputs = inputs = inputs // {
inputs
// {
self = { }; self = { };
}; };
}; };
in in
builtins.removeAttrs builtins.removeAttrs lib.snowfall [ "internal" ];
lib.snowfall
["internal"];
}; };
}; };
} }

View File

@@ -5,9 +5,9 @@
config, config,
inputs, inputs,
... ...
}: let }:
inherit let
(lib) inherit (lib)
types types
mkOption mkOption
mkDefault mkDefault
@@ -20,7 +20,9 @@
user-names = builtins.attrNames cfg.users; user-names = builtins.attrNames cfg.users;
create-system-users = system-users: name: let create-system-users =
system-users: name:
let
user = cfg.users.${name}; user = cfg.users.${name};
in in
system-users system-users
@@ -30,7 +32,8 @@
isHidden = mkDefault false; isHidden = mkDefault false;
}; };
}); });
in { in
{
imports = [ imports = [
(mkRenamedOptionModule [ "snowfallorg" "user" ] [ "snowfallorg" "users" ]) (mkRenamedOptionModule [ "snowfallorg" "user" ] [ "snowfallorg" "users" ])
]; ];
@@ -39,7 +42,10 @@ in {
users = mkOption { users = mkOption {
description = "User configuration."; description = "User configuration.";
default = { }; default = { };
type = types.attrsOf (types.submodule ({name, ...}: { type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = { options = {
create = mkOption { create = mkOption {
description = "Whether to create the user automatically."; description = "Whether to create the user automatically.";
@@ -62,19 +68,19 @@ in {
# HM-compatible options taken from: # HM-compatible options taken from:
# https://github.com/nix-community/home-manager/blob/0ee5ab611dc1fbb5180bd7d88d2aeb7841a4d179/nixos/common.nix#L14 # https://github.com/nix-community/home-manager/blob/0ee5ab611dc1fbb5180bd7d88d2aeb7841a4d179/nixos/common.nix#L14
type = types.submoduleWith { type = types.submoduleWith {
specialArgs = specialArgs = {
{
osConfig = config; osConfig = config;
modulesPath = "${inputs.home-manager}/modules"; modulesPath = "${inputs.home-manager}/modules";
} }
// config.home-manager.extraSpecialArgs; // config.home-manager.extraSpecialArgs;
modules = modules = [
[ (
({ {
lib, lib,
modulesPath, modulesPath,
... ...
}: { }:
{
imports = import "${modulesPath}/modules.nix" { imports = import "${modulesPath}/modules.nix" {
inherit pkgs lib; inherit pkgs lib;
useNixpkgsModule = !config.home-manager.useGlobalPkgs; useNixpkgsModule = !config.home-manager.useGlobalPkgs;
@@ -89,14 +95,17 @@ in {
nix.package = config.nix.package; nix.package = config.nix.package;
}; };
}) }
)
] ]
++ config.home-manager.sharedModules; ++ config.home-manager.sharedModules;
}; };
}; };
}; };
}; };
})); }
)
);
}; };
}; };

View File

@@ -4,8 +4,14 @@ inputs @ {
options, options,
config, config,
... ...
}: let }:
inherit (lib) types mkOption mkIf mkDefault; let
inherit (lib)
types
mkOption
mkIf
mkDefault
;
cfg = config.snowfallorg; cfg = config.snowfallorg;
@@ -16,12 +22,14 @@ inputs @ {
has-user-name = (cfg.user.name or null) != null; has-user-name = (cfg.user.name or null) != null;
default-home-directory = default-home-directory =
if (os-user-home != null) if (os-user-home != null) then
then os-user-home os-user-home
else if pkgs.stdenv.isDarwin else if pkgs.stdenv.isDarwin then
then "/Users/${cfg.user.name}" "/Users/${cfg.user.name}"
else "/home/${cfg.user.name}"; else
in { "/home/${cfg.user.name}";
in
{
options.snowfallorg = { options.snowfallorg = {
user = { user = {
enable = mkOption { enable = mkOption {

View File

@@ -4,9 +4,9 @@ args @ {
options, options,
config, config,
... ...
}: let }:
inherit let
(lib) inherit (lib)
types types
mkOption mkOption
mkDefault mkDefault
@@ -22,7 +22,9 @@ args @ {
user-names = builtins.attrNames cfg.users; user-names = builtins.attrNames cfg.users;
create-system-users = system-users: name: let create-system-users =
system-users: name:
let
user = cfg.users.${name}; user = cfg.users.${name};
in in
system-users system-users
@@ -38,7 +40,8 @@ args @ {
extraGroups = optional user.admin "wheel"; extraGroups = optional user.admin "wheel";
}; };
}); });
in { in
{
imports = [ imports = [
(mkRenamedOptionModule [ "snowfallorg" "user" ] [ "snowfallorg" "users" ]) (mkRenamedOptionModule [ "snowfallorg" "user" ] [ "snowfallorg" "users" ])
]; ];
@@ -47,7 +50,10 @@ in {
users = mkOption { users = mkOption {
description = "User configuration."; description = "User configuration.";
default = { }; default = { };
type = types.attrsOf (types.submodule ({name, ...}: { type = types.attrsOf (
types.submodule (
{ name, ... }:
{
options = { options = {
create = mkOption { create = mkOption {
description = "Whether to create the user automatically."; description = "Whether to create the user automatically.";
@@ -78,21 +84,20 @@ in {
# NOTE: This has been adapted to support documentation generation without # NOTE: This has been adapted to support documentation generation without
# having home-manager options fully declared. # having home-manager options fully declared.
type = types.submoduleWith { type = types.submoduleWith {
specialArgs = specialArgs = {
{
osConfig = config; osConfig = config;
modulesPath = "${inputs.home-manager or "/"}/modules"; modulesPath = "${inputs.home-manager or "/"}/modules";
} }
// (config.home-manager.extraSpecialArgs or { }); // (config.home-manager.extraSpecialArgs or { });
modules = modules = [
[ (
({ {
lib, lib,
modulesPath, modulesPath,
... ...
}: }:
if inputs ? home-manager if inputs ? home-manager then
then { {
imports = import "${modulesPath}/modules.nix" { imports = import "${modulesPath}/modules.nix" {
inherit pkgs lib; inherit pkgs lib;
useNixpkgsModule = !(config.home-manager.useGlobalPkgs or false); useNixpkgsModule = !(config.home-manager.useGlobalPkgs or false);
@@ -108,14 +113,18 @@ in {
nix.package = config.nix.package; nix.package = config.nix.package;
}; };
} }
else {}) else
{ }
)
] ]
++ (config.home-manager.sharedModules or [ ]); ++ (config.home-manager.sharedModules or [ ]);
}; };
}; };
}; };
}; };
})); }
)
);
}; };
}; };

View File

@@ -3,9 +3,9 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
inherit let
(core-inputs.nixpkgs.lib) inherit (core-inputs.nixpkgs.lib)
assertMsg assertMsg
mapAttrsToList mapAttrsToList
mapAttrs mapAttrs
@@ -15,7 +15,8 @@
mergeAttrs mergeAttrs
isDerivation isDerivation
; ;
in { in
{
attrs = { attrs = {
## Map and flatten an attribute set into a list. ## Map and flatten an attribute set into a list.
## Example Usage: ## Example Usage:
@@ -27,8 +28,7 @@ in {
## [ "x" 1 "y" 2 ] ## [ "x" 1 "y" 2 ]
## ``` ## ```
#@ (a -> b -> [c]) -> Attrs -> [c] #@ (a -> b -> [c]) -> Attrs -> [c]
map-concat-attrs-to-list = f: attrs: map-concat-attrs-to-list = f: attrs: flatten (mapAttrsToList f attrs);
flatten (mapAttrsToList f attrs);
## Recursively merge a list of attribute sets. ## Recursively merge a list of attribute sets.
## Example Usage: ## Example Usage:
@@ -64,23 +64,20 @@ in {
## { vim = ...; some.value = false; } ## { vim = ...; some.value = false; }
## ``` ## ```
#@ [Attrs] -> Attrs #@ [Attrs] -> Attrs
merge-shallow-packages = items: merge-shallow-packages =
foldl items:
( foldl (
result: item: result: item:
result result
// (mapAttrs // (mapAttrs (
(
name: value: name: value:
if isDerivation value if isDerivation value then
then value value
else if builtins.isAttrs value else if builtins.isAttrs value then
then (result.${name} or {}) // value (result.${name} or { }) // value
else value else
) value
item) ) item)
) ) { } items;
{}
items;
}; };
} }

View File

@@ -3,12 +3,19 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (core-inputs.flake-utils-plus.lib) filterPackages; inherit (core-inputs.flake-utils-plus.lib) filterPackages;
inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs callPackageWith; inherit (core-inputs.nixpkgs.lib)
assertMsg
foldl
mapAttrs
callPackageWith
;
user-checks-root = snowfall-lib.fs.get-snowfall-file "checks"; user-checks-root = snowfall-lib.fs.get-snowfall-file "checks";
in { in
{
check = { check = {
## Create flake output packages. ## Create flake output packages.
## Example Usage: ## Example Usage:
@@ -20,29 +27,33 @@ in {
## { another-check = ...; my-check = ...; default = ...; } ## { another-check = ...; my-check = ...; default = ...; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-checks = { create-checks =
{
channels, channels,
src ? user-checks-root, src ? user-checks-root,
pkgs ? channels.nixpkgs, pkgs ? channels.nixpkgs,
overrides ? { }, overrides ? { },
alias ? { }, alias ? { },
}: let }:
let
user-checks = snowfall-lib.fs.get-default-nix-files-recursive src; user-checks = snowfall-lib.fs.get-default-nix-files-recursive src;
create-check-metadata = check: let create-check-metadata =
extra-inputs = check:
pkgs let
// { extra-inputs = pkgs // {
inherit channels; inherit channels;
lib = snowfall-lib.internal.system-lib; lib = snowfall-lib.internal.system-lib;
inputs = snowfall-lib.flake.without-src user-inputs; inputs = snowfall-lib.flake.without-src user-inputs;
namespace = snowfall-config.namespace; namespace = snowfall-config.namespace;
}; };
in { in
{
name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory check); name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory check);
drv = callPackageWith extra-inputs check { }; drv = callPackageWith extra-inputs check { };
}; };
checks-metadata = builtins.map create-check-metadata user-checks; checks-metadata = builtins.map create-check-metadata user-checks;
merge-checks = checks: metadata: merge-checks =
checks: metadata:
checks checks
// { // {
${metadata.name} = metadata.drv; ${metadata.name} = metadata.drv;

View File

@@ -2,11 +2,10 @@
# Snowfall library. There is some duplication shared between this # Snowfall library. There is some duplication shared between this
# file and the library itself due to the library needing to pass through # file and the library itself due to the library needing to pass through
# another extended library for its own applications. # another extended library for its own applications.
core-inputs: user-options: let core-inputs: user-options:
let
raw-snowfall-config = user-options.snowfall or { }; raw-snowfall-config = user-options.snowfall or { };
snowfall-config = snowfall-config = raw-snowfall-config // {
raw-snowfall-config
// {
src = user-options.src; src = user-options.src;
root = raw-snowfall-config.root or user-options.src; root = raw-snowfall-config.root or user-options.src;
namespace = raw-snowfall-config.namespace or "internal"; namespace = raw-snowfall-config.namespace or "internal";
@@ -16,9 +15,20 @@ core-inputs: user-options: let
}; };
}; };
user-inputs = user-options.inputs // {src = user-options.src;}; user-inputs = user-options.inputs // {
src = user-options.src;
};
inherit (core-inputs.nixpkgs.lib) assertMsg fix filterAttrs mergeAttrs fold recursiveUpdate callPackageWith isFunction; inherit (core-inputs.nixpkgs.lib)
assertMsg
fix
filterAttrs
mergeAttrs
fold
recursiveUpdate
callPackageWith
isFunction
;
# Recursively merge a list of attribute sets. # Recursively merge a list of attribute sets.
# Type: [Attrs] -> Attrs # Type: [Attrs] -> Attrs
@@ -38,14 +48,12 @@ core-inputs: user-options: let
# Type: Attrs -> Attrs # Type: Attrs -> Attrs
# Usage: get-lib { x = nixpkgs; y = {}; } # Usage: get-lib { x = nixpkgs; y = {}; }
# result: { x = nixpkgs.lib; } # result: { x = nixpkgs.lib; }
get-libs = attrs: let get-libs =
attrs:
let
# @PERF(jakehamilton): Replace filter+map with a fold. # @PERF(jakehamilton): Replace filter+map with a fold.
attrs-with-libs = attrs-with-libs = filterAttrs (name: value: builtins.isAttrs (value.lib or null)) attrs;
filterAttrs libs = builtins.mapAttrs (name: input: input.lib) attrs-with-libs;
(name: value: builtins.isAttrs (value.lib or null))
attrs;
libs =
builtins.mapAttrs (name: input: input.lib) attrs-with-libs;
in in
libs; libs;
@@ -61,7 +69,8 @@ core-inputs: user-options: let
# NOTE: This root is different to accommodate the creation # NOTE: This root is different to accommodate the creation
# of a fake user-lib in order to run documentation on this flake. # of a fake user-lib in order to run documentation on this flake.
snowfall-lib-root = "${core-inputs.src}/snowfall-lib"; snowfall-lib-root = "${core-inputs.src}/snowfall-lib";
snowfall-lib-dirs = let snowfall-lib-dirs =
let
files = builtins.readDir snowfall-lib-root; files = builtins.readDir snowfall-lib-root;
dirs = filterAttrs (name: kind: kind == "directory") files; dirs = filterAttrs (name: kind: kind == "directory") files;
names = builtins.attrNames dirs; names = builtins.attrNames dirs;
@@ -69,14 +78,17 @@ core-inputs: user-options: let
names; names;
snowfall-lib = fix ( snowfall-lib = fix (
snowfall-lib: let snowfall-lib:
let
attrs = { attrs = {
inherit snowfall-lib snowfall-config core-inputs user-inputs; inherit
snowfall-lib
snowfall-config
core-inputs
user-inputs
;
}; };
libs = libs = builtins.map (dir: import "${snowfall-lib-root}/${dir}" attrs) snowfall-lib-dirs;
builtins.map
(dir: import "${snowfall-lib-root}/${dir}" attrs)
snowfall-lib-dirs;
in in
merge-deep libs merge-deep libs
); );
@@ -95,25 +107,28 @@ core-inputs: user-options: let
user-lib-modules = snowfall-lib.fs.get-default-nix-files-recursive user-lib-root; user-lib-modules = snowfall-lib.fs.get-default-nix-files-recursive user-lib-root;
user-lib = fix ( user-lib = fix (
user-lib: let user-lib:
let
attrs = { attrs = {
inherit (user-options) inputs; inherit (user-options) inputs;
snowfall-inputs = core-inputs; snowfall-inputs = core-inputs;
namespace = snowfall-config.namespace; namespace = snowfall-config.namespace;
lib = merge-shallow [base-lib {${snowfall-config.namespace} = user-lib;}]; lib = merge-shallow [
base-lib
{ ${snowfall-config.namespace} = user-lib; }
];
}; };
libs = libs = builtins.map (
builtins.map path:
( let
path: let
imported-module = import path; imported-module = import path;
in in
if isFunction imported-module if isFunction imported-module then
then callPackageWith attrs path {} callPackageWith attrs path { }
# the only difference is that there is no `override` and `overrideDerivation` on returned value # the only difference is that there is no `override` and `overrideDerivation` on returned value
else imported-module else
) imported-module
user-lib-modules; ) user-lib-modules;
in in
merge-deep libs merge-deep libs
); );
@@ -127,4 +142,5 @@ core-inputs: user-options: let
user-inputs-has-src = builtins.elem "src" (builtins.attrNames user-inputs); user-inputs-has-src = builtins.elem "src" (builtins.attrNames user-inputs);
in in
assert (assertMsg user-inputs-has-self "Missing attribute `self` for mkLib."); assert (assertMsg user-inputs-has-self "Missing attribute `self` for mkLib.");
assert (assertMsg user-inputs-has-src "Missing attribute `src` for mkLib."); lib assert (assertMsg user-inputs-has-src "Missing attribute `src` for mkLib.");
lib

View File

@@ -3,9 +3,22 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
inherit (core-inputs.nixpkgs.lib) assertMsg foldl filterAttrs const mapAttrs mapAttrs' hasSuffix removeSuffix nameValuePair traceVal; let
in rec { inherit (core-inputs.nixpkgs.lib)
assertMsg
foldl
filterAttrs
const
mapAttrs
mapAttrs'
hasSuffix
removeSuffix
nameValuePair
traceVal
;
in
rec {
flake = rec { flake = rec {
## Remove the `self` attribute from an attribute set. ## Remove the `self` attribute from an attribute set.
## Example Usage: ## Example Usage:
@@ -53,10 +66,9 @@ in rec {
## { x = true; } ## { x = true; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
without-snowfall-options = flake-options: without-snowfall-options =
builtins.removeAttrs flake-options:
flake-options builtins.removeAttrs flake-options [
[
"systems" "systems"
"modules" "modules"
"overlays" "overlays"
@@ -83,19 +95,19 @@ in rec {
## { x = nixpkgs.lib; } ## { x = nixpkgs.lib; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
get-libs = attrs: let get-libs =
attrs:
let
# @PERF(jakehamilton): Replace filter+map with a fold. # @PERF(jakehamilton): Replace filter+map with a fold.
attrs-with-libs = attrs-with-libs = filterAttrs (name: value: builtins.isAttrs (value.lib or null)) attrs;
filterAttrs libs = builtins.mapAttrs (name: input: input.lib) attrs-with-libs;
(name: value: builtins.isAttrs (value.lib or null))
attrs;
libs =
builtins.mapAttrs (name: input: input.lib) attrs-with-libs;
in in
libs; libs;
}; };
mkFlake = full-flake-options: let mkFlake =
full-flake-options:
let
namespace = snowfall-config.namespace or "internal"; namespace = snowfall-config.namespace or "internal";
custom-flake-options = flake.without-snowfall-options full-flake-options; custom-flake-options = flake.without-snowfall-options full-flake-options;
alias = full-flake-options.alias or { }; alias = full-flake-options.alias or { };
@@ -104,7 +116,11 @@ in rec {
systems = full-flake-options.systems or { }; systems = full-flake-options.systems or { };
homes = full-flake-options.homes or { }; homes = full-flake-options.homes or { };
}; };
hosts = snowfall-lib.attrs.merge-shallow [(full-flake-options.systems.hosts or {}) systems homes]; hosts = snowfall-lib.attrs.merge-shallow [
(full-flake-options.systems.hosts or { })
systems
homes
];
templates = snowfall-lib.template.create-templates { templates = snowfall-lib.template.create-templates {
overrides = full-flake-options.templates or { }; overrides = full-flake-options.templates or { };
alias = alias.templates or { }; alias = alias.templates or { };
@@ -130,11 +146,11 @@ in rec {
}; };
channels = full-flake-options.channels or { }; channels = full-flake-options.channels or { };
outputs-builder = channels: let outputs-builder =
channels:
let
user-outputs-builder = user-outputs-builder =
full-flake-options.outputs-builder full-flake-options.outputs-builder or full-flake-options.outputsBuilder or (const { });
or full-flake-options.outputsBuilder
or (const {});
user-outputs = user-outputs-builder channels; user-outputs = user-outputs-builder channels;
packages = snowfall-lib.package.create-packages { packages = snowfall-lib.package.create-packages {
inherit channels namespace; inherit channels namespace;
@@ -158,11 +174,12 @@ in rec {
devShells = shells; devShells = shells;
}; };
in in
snowfall-lib.attrs.merge-deep [user-outputs outputs]; snowfall-lib.attrs.merge-deep [
user-outputs
outputs
];
flake-options = flake-options = custom-flake-options // {
custom-flake-options
// {
inherit hosts templates; inherit hosts templates;
inherit (user-inputs) self; inherit (user-inputs) self;
@@ -173,22 +190,18 @@ in rec {
darwinModules = darwin-modules; darwinModules = darwin-modules;
homeModules = home-modules; homeModules = home-modules;
channelsConfig = channelsConfig = full-flake-options.channels-config or full-flake-options.channelsConfig or { };
full-flake-options.channels-config
or full-flake-options.channelsConfig
or {};
channels = channels = mapAttrs (
mapAttrs channel: config:
(channel: config:
config config
// { // {
overlaysBuilder = snowfall-lib.overlay.create-overlays-builder { overlaysBuilder = snowfall-lib.overlay.create-overlays-builder {
inherit namespace; inherit namespace;
extra-overlays = full-flake-options.overlays or [ ]; extra-overlays = full-flake-options.overlays or [ ];
}; };
}) }
({nixpkgs = {};} // channels); ) ({ nixpkgs = { }; } // channels);
outputsBuilder = outputs-builder; outputsBuilder = outputs-builder;
@@ -199,12 +212,9 @@ in rec {
}; };
}; };
flake-utils-plus-outputs = flake-utils-plus-outputs = core-inputs.flake-utils-plus.lib.mkFlake flake-options;
core-inputs.flake-utils-plus.lib.mkFlake flake-options;
flake-outputs = flake-outputs = flake-utils-plus-outputs // {
flake-utils-plus-outputs
// {
inherit overlays; inherit overlays;
}; };
in in
@@ -215,20 +225,20 @@ in rec {
// (builtins.listToAttrs ( // (builtins.listToAttrs (
builtins.map (system: { builtins.map (system: {
name = system; name = system;
value = value = flake-outputs.packages.${system} // {
flake-outputs.packages.${system} homeConfigurations =
// { let
homeConfigurations = let
homeNames = filterAttrs (_: home: home.system == system) homes; homeNames = filterAttrs (_: home: home.system == system) homes;
homeConfigurations = mapAttrs (home-name: _: flake-outputs.homeConfigurations.${home-name}) homeNames; homeConfigurations = mapAttrs (
renamedHomeConfigurations = home-name: _: flake-outputs.homeConfigurations.${home-name}
mapAttrs' ( ) homeNames;
renamedHomeConfigurations = mapAttrs' (
name: value: name: value:
if hasSuffix "@${system}" name if hasSuffix "@${system}" name then
then nameValuePair (removeSuffix "@${system}" name) value nameValuePair (removeSuffix "@${system}" name) value
else nameValuePair name value else
) nameValuePair name value
homeConfigurations; ) homeConfigurations;
in in
renamedHomeConfigurations; renamedHomeConfigurations;
}; };

View File

@@ -3,10 +3,12 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (builtins) baseNameOf dirOf; inherit (builtins) baseNameOf dirOf;
inherit (core-inputs.nixpkgs.lib) id foldr flip; inherit (core-inputs.nixpkgs.lib) id foldr flip;
in { in
{
fp = rec { fp = rec {
## Compose two functions. ## Compose two functions.
## Example Usage: ## Example Usage:
@@ -18,7 +20,9 @@ in {
## (x: add-two (add-one x)) ## (x: add-two (add-one x))
## ``` ## ```
#@ (b -> c) -> (a -> b) -> a -> c #@ (b -> c) -> (a -> b) -> a -> c
compose = f: g: x: f (g x); compose =
f: g: x:
f (g x);
## Compose many functions. ## Compose many functions.
## Example Usage: ## Example Usage:

View File

@@ -3,13 +3,20 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (builtins) readDir pathExists; inherit (builtins) readDir pathExists;
inherit (core-inputs) flake-utils-plus; inherit (core-inputs) flake-utils-plus;
inherit (core-inputs.nixpkgs.lib) assertMsg filterAttrs mapAttrsToList flatten; inherit (core-inputs.nixpkgs.lib)
assertMsg
filterAttrs
mapAttrsToList
flatten
;
file-name-regex = "(.*)\\.(.*)$"; file-name-regex = "(.*)\\.(.*)$";
in { in
{
fs = rec { fs = rec {
## Matchers for file kinds. These are often used with `readDir`. ## Matchers for file kinds. These are often used with `readDir`.
## Example Usage: ## Example Usage:
@@ -72,10 +79,7 @@ in {
## { "my-file.txt" = "regular"; } ## { "my-file.txt" = "regular"; }
## ``` ## ```
#@ Path -> Attrs #@ Path -> Attrs
safe-read-directory = path: safe-read-directory = path: if pathExists path then readDir path else { };
if pathExists path
then readDir path
else {};
## Get directories at a given path. ## Get directories at a given path.
## Example Usage: ## Example Usage:
@@ -87,7 +91,9 @@ in {
## [ "./something/a-directory" ] ## [ "./something/a-directory" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-directories = path: let get-directories =
path:
let
entries = safe-read-directory path; entries = safe-read-directory path;
filtered-entries = filterAttrs (name: kind: is-directory-kind kind) entries; filtered-entries = filterAttrs (name: kind: is-directory-kind kind) entries;
in in
@@ -103,7 +109,9 @@ in {
## [ "./something/a-file" ] ## [ "./something/a-file" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-files = path: let get-files =
path:
let
entries = safe-read-directory path; entries = safe-read-directory path;
filtered-entries = filterAttrs (name: kind: is-file-kind kind) entries; filtered-entries = filterAttrs (name: kind: is-file-kind kind) entries;
in in
@@ -119,22 +127,20 @@ in {
## [ "./something/some-directory/a-file" ] ## [ "./something/some-directory/a-file" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-files-recursive = path: let get-files-recursive =
path:
let
entries = safe-read-directory path; entries = safe-read-directory path;
filtered-entries = filtered-entries = filterAttrs (
filterAttrs name: kind: (is-file-kind kind) || (is-directory-kind kind)
(name: kind: (is-file-kind kind) || (is-directory-kind kind)) ) entries;
entries; map-file =
map-file = name: kind: let name: kind:
let
path' = "${path}/${name}"; path' = "${path}/${name}";
in in
if is-directory-kind kind if is-directory-kind kind then get-files-recursive path' else path';
then get-files-recursive path' files = snowfall-lib.attrs.map-concat-attrs-to-list map-file filtered-entries;
else path';
files =
snowfall-lib.attrs.map-concat-attrs-to-list
map-file
filtered-entries;
in in
files; files;
@@ -148,10 +154,7 @@ in {
## [ "./something/a.nix" ] ## [ "./something/a.nix" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-nix-files = path: get-nix-files = path: builtins.filter (snowfall-lib.path.has-file-extension "nix") (get-files path);
builtins.filter
(snowfall-lib.path.has-file-extension "nix")
(get-files path);
## Get nix files at a given path, traversing any directories within. ## Get nix files at a given path, traversing any directories within.
## Example Usage: ## Example Usage:
@@ -163,10 +166,8 @@ in {
## [ "./something/a.nix" ] ## [ "./something/a.nix" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-nix-files-recursive = path: get-nix-files-recursive =
builtins.filter path: builtins.filter (snowfall-lib.path.has-file-extension "nix") (get-files-recursive path);
(snowfall-lib.path.has-file-extension "nix")
(get-files-recursive path);
## Get nix files at a given path named "default.nix". ## Get nix files at a given path named "default.nix".
## Example Usage: ## Example Usage:
@@ -178,10 +179,8 @@ in {
## [ "./something/default.nix" ] ## [ "./something/default.nix" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-default-nix-files = path: get-default-nix-files =
builtins.filter path: builtins.filter (name: builtins.baseNameOf name == "default.nix") (get-files path);
(name: builtins.baseNameOf name == "default.nix")
(get-files path);
## Get nix files at a given path named "default.nix", traversing any directories within. ## Get nix files at a given path named "default.nix", traversing any directories within.
## Example Usage: ## Example Usage:
@@ -193,10 +192,8 @@ in {
## [ "./something/some-directory/default.nix" ] ## [ "./something/some-directory/default.nix" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-default-nix-files-recursive = path: get-default-nix-files-recursive =
builtins.filter path: builtins.filter (name: builtins.baseNameOf name == "default.nix") (get-files-recursive path);
(name: builtins.baseNameOf name == "default.nix")
(get-files-recursive path);
## Get nix files at a given path not named "default.nix". ## Get nix files at a given path not named "default.nix".
## Example Usage: ## Example Usage:
@@ -208,14 +205,12 @@ in {
## [ "./something/a.nix" ] ## [ "./something/a.nix" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-non-default-nix-files = path: get-non-default-nix-files =
builtins.filter path:
( builtins.filter (
name: name:
(snowfall-lib.path.has-file-extension "nix" name) (snowfall-lib.path.has-file-extension "nix" name) && (builtins.baseNameOf name != "default.nix")
&& (builtins.baseNameOf name != "default.nix") ) (get-files path);
)
(get-files path);
## Get nix files at a given path not named "default.nix", traversing any directories within. ## Get nix files at a given path not named "default.nix", traversing any directories within.
## Example Usage: ## Example Usage:
@@ -227,13 +222,11 @@ in {
## [ "./something/some-directory/a.nix" ] ## [ "./something/some-directory/a.nix" ]
## ``` ## ```
#@ Path -> [Path] #@ Path -> [Path]
get-non-default-nix-files-recursive = path: get-non-default-nix-files-recursive =
builtins.filter path:
( builtins.filter (
name: name:
(snowfall-lib.path.has-file-extension "nix" name) (snowfall-lib.path.has-file-extension "nix" name) && (builtins.baseNameOf name != "default.nix")
&& (builtins.baseNameOf name != "default.nix") ) (get-files-recursive path);
)
(get-files-recursive path);
}; };
} }

View File

@@ -3,9 +3,9 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
inherit let
(core-inputs.nixpkgs.lib) inherit (core-inputs.nixpkgs.lib)
assertMsg assertMsg
foldl foldl
head head
@@ -30,24 +30,26 @@
user-homes-root = snowfall-lib.fs.get-snowfall-file "homes"; user-homes-root = snowfall-lib.fs.get-snowfall-file "homes";
user-modules-root = snowfall-lib.fs.get-snowfall-file "modules"; user-modules-root = snowfall-lib.fs.get-snowfall-file "modules";
in { in
{
home = rec { home = rec {
# Modules in home-manager expect `hm` to be available directly on `lib` itself. # Modules in home-manager expect `hm` to be available directly on `lib` itself.
home-lib = home-lib =
# NOTE: This prevents an error during evaluation if the input does # NOTE: This prevents an error during evaluation if the input does
# not exist. # not exist.
if user-inputs ? home-manager if user-inputs ? home-manager then
then snowfall-lib.internal.system-lib.extend (
snowfall-lib.internal.system-lib.extend final: prev:
(final: prev:
# NOTE: This order is important, this library's extend and other utilities must write # NOTE: This order is important, this library's extend and other utilities must write
# _over_ the original `system-lib`. # _over_ the original `system-lib`.
snowfall-lib.internal.system-lib snowfall-lib.internal.system-lib
// prev // prev
// { // {
hm = snowfall-lib.internal.system-lib.home-manager.hm; hm = snowfall-lib.internal.system-lib.home-manager.hm;
}) }
else {}; )
else
{ };
## Get the user and host from a combined string. ## Get the user and host from a combined string.
## Example Usage: ## Example Usage:
@@ -59,16 +61,16 @@ in {
## { user = "myuser"; host = "myhost"; } ## { user = "myuser"; host = "myhost"; }
## ``` ## ```
#@ String -> Attrs #@ String -> Attrs
split-user-and-host = target: let split-user-and-host =
target:
let
raw-name-parts = builtins.split "@" target; raw-name-parts = builtins.split "@" target;
name-parts = builtins.filter builtins.isString raw-name-parts; name-parts = builtins.filter builtins.isString raw-name-parts;
user = builtins.elemAt name-parts 0; user = builtins.elemAt name-parts 0;
host = host = if builtins.length name-parts > 1 then builtins.elemAt name-parts 1 else "";
if builtins.length name-parts > 1 in
then builtins.elemAt name-parts 1 {
else "";
in {
inherit user host; inherit user host;
}; };
@@ -82,32 +84,36 @@ in {
## <flake-utils-plus-home-configuration> ## <flake-utils-plus-home-configuration>
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-home = { create-home =
{
path, path,
name ? builtins.unsafeDiscardStringContext (snowfall-lib.system.get-inferred-system-name path), name ? builtins.unsafeDiscardStringContext (snowfall-lib.system.get-inferred-system-name path),
modules ? [ ], modules ? [ ],
specialArgs ? { }, specialArgs ? { },
channelName ? "nixpkgs", channelName ? "nixpkgs",
system ? "x86_64-linux", system ? "x86_64-linux",
}: let }:
let
user-metadata = split-user-and-host name; user-metadata = split-user-and-host name;
unique-name = unique-name = if user-metadata.host == "" then "${user-metadata.user}@${system}" else name;
if user-metadata.host == ""
then "${user-metadata.user}@${system}"
else name;
# NOTE: home-manager has trouble with `pkgs` recursion if it isn't passed in here. # NOTE: home-manager has trouble with `pkgs` recursion if it isn't passed in here.
pkgs = user-inputs.self.pkgs.${system}.${channelName} // {lib = home-lib;}; pkgs = user-inputs.self.pkgs.${system}.${channelName} // {
lib = home-lib;
};
lib = home-lib; lib = home-lib;
in in
assert assertMsg (user-inputs ? home-manager) "In order to create home-manager configurations, you must include `home-manager` as a flake input."; assert assertMsg (user-inputs ? home-manager)
assert assertMsg ((user-metadata.host != "") || !(hasInfix "@" name)) "Snowfall Lib homes must be named with the format: user@system"; { "In order to create home-manager configurations, you must include `home-manager` as a flake input.";
assert assertMsg (
(user-metadata.host != "") || !(hasInfix "@" name)
) "Snowfall Lib homes must be named with the format: user@system";
{
inherit channelName system; inherit channelName system;
output = "homeConfigurations"; output = "homeConfigurations";
modules = modules = [
[
path path
../../modules/home/user/default.nix ../../modules/home/user/default.nix
] ]
@@ -127,20 +133,26 @@ in {
inherit pkgs lib; inherit pkgs lib;
}; };
builder = args: builder =
user-inputs.home-manager.lib.homeManagerConfiguration args:
((builtins.removeAttrs args ["system" "specialArgs"]) user-inputs.home-manager.lib.homeManagerConfiguration (
(builtins.removeAttrs args [
"system"
"specialArgs"
])
// { // {
inherit pkgs lib; inherit pkgs lib;
modules = modules = args.modules ++ [
args.modules (
++ [ module-args:
(module-args: import ./nix-registry-module.nix (
import ./nix-registry-module.nix (module-args module-args
// { // {
inherit user-inputs core-inputs; inherit user-inputs core-inputs;
})) }
)
)
{ {
snowfallorg.user = { snowfallorg.user = {
name = mkDefault user-metadata.user; name = mkDefault user-metadata.user;
@@ -150,7 +162,8 @@ in {
]; ];
extraSpecialArgs = specialArgs // args.specialArgs; extraSpecialArgs = specialArgs // args.specialArgs;
}); }
);
}; };
## Get structured data about all homes for a given target. ## Get structured data about all homes for a given target.
@@ -163,10 +176,14 @@ in {
## [ { system = "x86_64-linux"; name = "my-home"; path = "/homes/x86_64-linux/my-home";} ] ## [ { system = "x86_64-linux"; name = "my-home"; path = "/homes/x86_64-linux/my-home";} ]
## ``` ## ```
#@ String -> [Attrs] #@ String -> [Attrs]
get-target-homes-metadata = target: let get-target-homes-metadata =
target:
let
homes = snowfall-lib.fs.get-directories target; homes = snowfall-lib.fs.get-directories target;
existing-homes = builtins.filter (home: builtins.pathExists "${home}/default.nix") homes; existing-homes = builtins.filter (home: builtins.pathExists "${home}/default.nix") homes;
create-home-metadata = path: let create-home-metadata =
path:
let
# We are building flake outputs based on file contents. Nix doesn't like this # We are building flake outputs based on file contents. Nix doesn't like this
# so we have to explicitly discard the string's path context to allow us to # so we have to explicitly discard the string's path context to allow us to
# use the name as a variable. # use the name as a variable.
@@ -175,11 +192,9 @@ in {
# so we have to explicitly discard the string's path context to allow us to # so we have to explicitly discard the string's path context to allow us to
# use the name as a variable. # use the name as a variable.
system = builtins.unsafeDiscardStringContext (builtins.baseNameOf target); system = builtins.unsafeDiscardStringContext (builtins.baseNameOf target);
name = name = if !(hasInfix "@" basename) then "${basename}@${system}" else basename;
if !(hasInfix "@" basename) in
then "${basename}@${system}" {
else basename;
in {
path = "${path}/default.nix"; path = "${path}/default.nix";
inherit name system; inherit name system;
}; };
@@ -197,7 +212,9 @@ in {
## { "my-user@my-system" = <flake-utils-plus-home-configuration>; } ## { "my-user@my-system" = <flake-utils-plus-home-configuration>; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-homes = homes: let create-homes =
homes:
let
targets = snowfall-lib.fs.get-directories user-homes-root; targets = snowfall-lib.fs.get-directories user-homes-root;
target-homes-metadata = concatMap get-target-homes-metadata targets; target-homes-metadata = concatMap get-target-homes-metadata targets;
@@ -205,27 +222,34 @@ in {
src = "${user-modules-root}/home"; src = "${user-modules-root}/home";
}; };
user-home-modules-list = user-home-modules-list = mapAttrsToList (
mapAttrsToList module-path: module:
(module-path: module: args @ {pkgs, ...}: args@{ pkgs, ... }:
(module args) (module args)
// { // {
_file = "${user-homes-root}/${module-path}/default.nix"; _file = "${user-homes-root}/${module-path}/default.nix";
}) }
user-home-modules; ) user-home-modules;
create-home' = home-metadata: let create-home' =
home-metadata:
let
inherit (home-metadata) name; inherit (home-metadata) name;
overrides = homes.users.${name} or { }; overrides = homes.users.${name} or { };
in { in
"${name}" = create-home (overrides {
"${name}" = create-home (
overrides
// home-metadata // home-metadata
// { // {
modules = user-home-modules-list ++ (homes.users.${name}.modules or [ ]) ++ (homes.modules or [ ]); modules = user-home-modules-list ++ (homes.users.${name}.modules or [ ]) ++ (homes.modules or [ ]);
}); }
);
}; };
created-homes = foldl (homes: home-metadata: homes // (create-home' home-metadata)) {} target-homes-metadata; created-homes = foldl (
homes: home-metadata: homes // (create-home' home-metadata)
) { } target-homes-metadata;
in in
created-homes; created-homes;
@@ -239,7 +263,9 @@ in {
## [Module] ## [Module]
## ``` ## ```
#@ Attrs -> [Module] #@ Attrs -> [Module]
create-home-system-modules = users: let create-home-system-modules =
users:
let
created-users = create-homes users; created-users = create-homes users;
user-home-modules = snowfall-lib.module.create-modules { user-home-modules = snowfall-lib.module.create-modules {
src = "${user-modules-root}/home"; src = "${user-modules-root}/home";
@@ -249,16 +275,13 @@ in {
config.home-manager.sharedModules = [ module ]; config.home-manager.sharedModules = [ module ];
}) (users.modules or [ ]); }) (users.modules or [ ]);
shared-user-modules = shared-user-modules = mapAttrsToList (module-path: module: {
mapAttrsToList
(module-path: module: {
_file = "${user-modules-root}/home/${module-path}/default.nix"; _file = "${user-modules-root}/home/${module-path}/default.nix";
config = { config = {
home-manager.sharedModules = [ module ]; home-manager.sharedModules = [ module ];
}; };
}) }) user-home-modules;
user-home-modules;
snowfall-user-home-module = { snowfall-user-home-module = {
_file = "virtual:snowfallorg/modules/home/user/default.nix"; _file = "virtual:snowfallorg/modules/home/user/default.nix";
@@ -270,7 +293,8 @@ in {
}; };
}; };
extra-special-args-module = args @ { extra-special-args-module =
args@{
config, config,
pkgs, pkgs,
system ? pkgs.stdenv.hostPlatform.system, system ? pkgs.stdenv.hostPlatform.system,
@@ -280,12 +304,20 @@ in {
virtual ? (snowfall-lib.system.is-virtual target), virtual ? (snowfall-lib.system.is-virtual target),
systems ? { }, systems ? { },
... ...
}: { }:
{
_file = "virtual:snowfallorg/home/extra-special-args"; _file = "virtual:snowfallorg/home/extra-special-args";
config = { config = {
home-manager.extraSpecialArgs = { home-manager.extraSpecialArgs = {
inherit system target format virtual systems host; inherit
system
target
format
virtual
systems
host
;
inherit (snowfall-config) namespace; inherit (snowfall-config) namespace;
lib = home-lib; lib = home-lib;
@@ -295,10 +327,9 @@ in {
}; };
}; };
system-modules = system-modules = builtins.map (
builtins.map name:
( let
name: let
created-user = created-users.${name}; created-user = created-users.${name};
user-module = head created-user.modules; user-module = head created-user.modules;
other-modules = users.users.${name}.modules or [ ]; other-modules = users.users.${name}.modules or [ ];
@@ -311,26 +342,21 @@ in {
host ? "", host ? "",
system ? pkgs.stdenv.hostPlatform.system, system ? pkgs.stdenv.hostPlatform.system,
... ...
}: let }:
host-matches = let
(name == "${user-name}@${host}") host-matches = (name == "${user-name}@${host}") || (name == "${user-name}@${system}");
|| (name == "${user-name}@${system}");
# NOTE: To conform to the config structure of home-manager, we have to # NOTE: To conform to the config structure of home-manager, we have to
# remap the options coming from `snowfallorg.user.<name>.home.config` since `mkAliasDefinitions` # remap the options coming from `snowfallorg.user.<name>.home.config` since `mkAliasDefinitions`
# does not let us target options within a submodule. # does not let us target options within a submodule.
wrap-user-options = user-option: wrap-user-options =
if (user-option ? "_type") && user-option._type == "merge" user-option:
then if (user-option ? "_type") && user-option._type == "merge" then
user-option user-option
// { // {
contents = contents = builtins.map (
builtins.map merge-entry: merge-entry.${user-name}.home.config or { }
( ) user-option.contents;
merge-entry:
merge-entry.${user-name}.home.config or {}
)
user-option.contents;
} }
else else
(builtins.trace '' (builtins.trace ''
@@ -345,7 +371,8 @@ in {
user-option; user-option;
home-config = mkAliasAndWrapDefinitions wrap-user-options options.snowfallorg.users; home-config = mkAliasAndWrapDefinitions wrap-user-options options.snowfallorg.users;
in { in
{
_file = "virtual:snowfallorg/home/user/${name}"; _file = "virtual:snowfallorg/home/user/${name}";
config = mkIf host-matches { config = mkIf host-matches {
@@ -358,18 +385,32 @@ in {
# NOTE: specialArgs are not propagated by Home-Manager without this. # NOTE: specialArgs are not propagated by Home-Manager without this.
# However, not all specialArgs values can be set when using `_module.args`. # However, not all specialArgs values can be set when using `_module.args`.
_module.args = builtins.removeAttrs ((users.users.${name}.specialArgs or {}) _module.args =
builtins.removeAttrs
(
(users.users.${name}.specialArgs or { })
// { // {
namespace = snowfall-config.namespace; namespace = snowfall-config.namespace;
}) }
["options" "config" "lib" "pkgs" "specialArgs" "host"]; )
[
"options"
"config"
"lib"
"pkgs"
"specialArgs"
"host"
];
}; };
home-manager = { home-manager = {
users.${user-name} = mkIf config.snowfallorg.users.${user-name}.home.enable ({pkgs, ...}: { users.${user-name} = mkIf config.snowfallorg.users.${user-name}.home.enable (
{ pkgs, ... }:
{
imports = (home-config.imports or [ ]) ++ other-modules ++ [ user-module ]; imports = (home-config.imports or [ ]) ++ other-modules ++ [ user-module ];
config = builtins.removeAttrs home-config [ "imports" ]; config = builtins.removeAttrs home-config [ "imports" ];
}); }
);
# NOTE: Without this home-manager will instead create its own package set which won't contain the same config and # NOTE: Without this home-manager will instead create its own package set which won't contain the same config and
# user-defined packages/overlays as the flake's nixpkgs channel. # user-defined packages/overlays as the flake's nixpkgs channel.
@@ -377,8 +418,7 @@ in {
}; };
}; };
} }
) ) (builtins.attrNames created-users);
(builtins.attrNames created-users);
in in
[ [
extra-special-args-module extra-special-args-module

View File

@@ -6,7 +6,8 @@
user-inputs, user-inputs,
core-inputs, core-inputs,
... ...
}: { }:
{
disabledModules = [ disabledModules = [
# The module from flake-utils-plus only works on NixOS and nix-darwin. For home-manager # The module from flake-utils-plus only works on NixOS and nix-darwin. For home-manager
# to build, this module needs to be disabled. # to build, this module needs to be disabled.

View File

@@ -3,8 +3,14 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
inherit (core-inputs.nixpkgs.lib) fix filterAttrs callPackageWith isFunction; let
inherit (core-inputs.nixpkgs.lib)
fix
filterAttrs
callPackageWith
isFunction
;
core-inputs-libs = snowfall-lib.flake.get-libs (snowfall-lib.flake.without-self core-inputs); core-inputs-libs = snowfall-lib.flake.get-libs (snowfall-lib.flake.without-self core-inputs);
user-inputs-libs = snowfall-lib.flake.get-libs (snowfall-lib.flake.without-self user-inputs); user-inputs-libs = snowfall-lib.flake.get-libs (snowfall-lib.flake.without-self user-inputs);
@@ -23,7 +29,8 @@
user-lib-modules = snowfall-lib.fs.get-default-nix-files-recursive user-lib-root; user-lib-modules = snowfall-lib.fs.get-default-nix-files-recursive user-lib-root;
user-lib = fix ( user-lib = fix (
user-lib: let user-lib:
let
attrs = { attrs = {
inputs = snowfall-lib.flake.without-snowfall-inputs user-inputs; inputs = snowfall-lib.flake.without-snowfall-inputs user-inputs;
snowfall-inputs = core-inputs; snowfall-inputs = core-inputs;
@@ -33,18 +40,17 @@
{ "${snowfall-config.namespace}" = user-lib; } { "${snowfall-config.namespace}" = user-lib; }
]; ];
}; };
libs = libs = builtins.map (
builtins.map path:
( let
path: let
imported-module = import path; imported-module = import path;
in in
if isFunction imported-module if isFunction imported-module then
then callPackageWith attrs path {} callPackageWith attrs path { }
# the only difference is that there is no `override` and `overrideDerivation` on returned value # the only difference is that there is no `override` and `overrideDerivation` on returned value
else imported-module else
) imported-module
user-lib-modules; ) user-lib-modules;
in in
snowfall-lib.attrs.merge-deep libs snowfall-lib.attrs.merge-deep libs
); );
@@ -53,7 +59,8 @@
base-lib base-lib
{ "${snowfall-config.namespace}" = user-lib; } { "${snowfall-config.namespace}" = user-lib; }
]; ];
in { in
{
internal = { internal = {
inherit system-lib user-lib; inherit system-lib user-lib;
}; };

View File

@@ -3,12 +3,22 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (builtins) baseNameOf; inherit (builtins) baseNameOf;
inherit (core-inputs.nixpkgs.lib) foldl mapAttrs hasPrefix hasSuffix isFunction splitString tail; inherit (core-inputs.nixpkgs.lib)
foldl
mapAttrs
hasPrefix
hasSuffix
isFunction
splitString
tail
;
user-modules-root = snowfall-lib.fs.get-snowfall-file "modules"; user-modules-root = snowfall-lib.fs.get-snowfall-file "modules";
in { in
{
module = { module = {
## Create flake output modules. ## Create flake output modules.
## Example Usage: ## Example Usage:
@@ -20,44 +30,53 @@ in {
## { another-module = ...; my-module = ...; default = ...; } ## { another-module = ...; my-module = ...; default = ...; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-modules = { create-modules =
{
src ? "${user-modules-root}/nixos", src ? "${user-modules-root}/nixos",
overrides ? { }, overrides ? { },
alias ? { }, alias ? { },
}: let }:
let
user-modules = snowfall-lib.fs.get-default-nix-files-recursive src; user-modules = snowfall-lib.fs.get-default-nix-files-recursive src;
create-module-metadata = module: { create-module-metadata = module: {
name = let name =
path-name = builtins.replaceStrings [(builtins.toString src) "/default.nix"] ["" ""] (builtins.unsafeDiscardStringContext module); let
path-name = builtins.replaceStrings [ (builtins.toString src) "/default.nix" ] [ "" "" ] (
builtins.unsafeDiscardStringContext module
);
in in
if hasPrefix "/" path-name if hasPrefix "/" path-name then
then builtins.substring 1 ((builtins.stringLength path-name) - 1) path-name builtins.substring 1 ((builtins.stringLength path-name) - 1) path-name
else path-name; else
path-name;
path = module; path = module;
}; };
modules-metadata = builtins.map create-module-metadata user-modules; modules-metadata = builtins.map create-module-metadata user-modules;
merge-modules = modules: metadata: merge-modules =
modules: metadata:
modules modules
// { // {
# NOTE: home-manager *requires* modules to specify named arguments or it will not # NOTE: home-manager *requires* modules to specify named arguments or it will not
# pass values in. For this reason we must specify things like `pkgs` as a named attribute. # pass values in. For this reason we must specify things like `pkgs` as a named attribute.
${metadata.name} = args @ {pkgs, ...}: let ${metadata.name} =
args@{ pkgs, ... }:
let
system = args.system or args.pkgs.stdenv.hostPlatform.system; system = args.system or args.pkgs.stdenv.hostPlatform.system;
target = args.target or system; target = args.target or system;
format = let format =
let
virtual-system-type = snowfall-lib.system.get-virtual-system-type target; virtual-system-type = snowfall-lib.system.get-virtual-system-type target;
in in
if virtual-system-type != "" if virtual-system-type != "" then
then virtual-system-type virtual-system-type
else if snowfall-lib.system.is-darwin target else if snowfall-lib.system.is-darwin target then
then "darwin" "darwin"
else "linux"; else
"linux";
# Replicates the specialArgs from Snowfall Lib's system builder. # Replicates the specialArgs from Snowfall Lib's system builder.
modified-args = modified-args = args // {
args
// {
inherit system target format; inherit system target format;
virtual = args.virtual or (snowfall-lib.system.get-virtual-system-type target != ""); virtual = args.virtual or (snowfall-lib.system.get-virtual-system-type target != "");
systems = args.systems or { }; systems = args.systems or { };
@@ -69,9 +88,10 @@ in {
}; };
imported-user-module = import metadata.path; imported-user-module = import metadata.path;
user-module = user-module =
if isFunction imported-user-module if isFunction imported-user-module then
then imported-user-module modified-args imported-user-module modified-args
else imported-user-module; else
imported-user-module;
in in
user-module // { _file = metadata.path; }; user-module // { _file = metadata.path; };
}; };

View File

@@ -3,12 +3,14 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (core-inputs.nixpkgs.lib) assertMsg foldl concatStringsSep; inherit (core-inputs.nixpkgs.lib) assertMsg foldl concatStringsSep;
user-overlays-root = snowfall-lib.fs.get-snowfall-file "overlays"; user-overlays-root = snowfall-lib.fs.get-snowfall-file "overlays";
user-packages-root = snowfall-lib.fs.get-snowfall-file "packages"; user-packages-root = snowfall-lib.fs.get-snowfall-file "packages";
in { in
{
overlay = { overlay = {
## Create a flake-utils-plus overlays builder. ## Create a flake-utils-plus overlays builder.
## Example Usage: ## Example Usage:
@@ -20,13 +22,17 @@ in {
## (channels: [ ... ]) ## (channels: [ ... ])
## ``` ## ```
#@ Attrs -> Attrs -> [(a -> b -> c)] #@ Attrs -> Attrs -> [(a -> b -> c)]
create-overlays-builder = { create-overlays-builder =
{
src ? user-overlays-root, src ? user-overlays-root,
namespace ? snowfall-config.namespace, namespace ? snowfall-config.namespace,
extra-overlays ? [ ], extra-overlays ? [ ],
}: channels: let }:
channels:
let
user-overlays = snowfall-lib.fs.get-default-nix-files-recursive src; user-overlays = snowfall-lib.fs.get-default-nix-files-recursive src;
create-overlay = overlay: create-overlay =
overlay:
import overlay ( import overlay (
# Deprecated: Use `inputs.*` instead of referencing the input name directly. # Deprecated: Use `inputs.*` instead of referencing the input name directly.
user-inputs user-inputs
@@ -37,18 +43,22 @@ in {
lib = snowfall-lib.internal.system-lib; lib = snowfall-lib.internal.system-lib;
} }
); );
user-packages-overlay = final: prev: let user-packages-overlay =
final: prev:
let
user-packages = snowfall-lib.package.create-packages { user-packages = snowfall-lib.package.create-packages {
pkgs = final; pkgs = final;
inherit channels namespace; inherit channels namespace;
}; };
in { in
${namespace} = {
(prev.${namespace} or {}) ${namespace} = (prev.${namespace} or { }) // user-packages;
// user-packages;
}; };
overlays = overlays = [
[user-packages-overlay] ++ extra-overlays ++ (builtins.map create-overlay user-overlays); user-packages-overlay
]
++ extra-overlays
++ (builtins.map create-overlay user-overlays);
in in
overlays; overlays;
@@ -63,12 +73,14 @@ in {
## { default = final: prev: ...; some-overlay = final: prev: ...; } ## { default = final: prev: ...; some-overlay = final: prev: ...; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-overlays = { create-overlays =
{
src ? user-overlays-root, src ? user-overlays-root,
packages-src ? user-packages-root, packages-src ? user-packages-root,
namespace ? snowfall-config.namespace, namespace ? snowfall-config.namespace,
extra-overlays ? { }, extra-overlays ? { },
}: let }:
let
fake-pkgs = { fake-pkgs = {
callPackage = x: x; callPackage = x: x;
isFakePkgs = true; isFakePkgs = true;
@@ -80,25 +92,29 @@ in {
channel-systems = user-inputs.self.pkgs; channel-systems = user-inputs.self.pkgs;
user-packages-overlay = final: prev: let user-packages-overlay =
final: prev:
let
user-packages = snowfall-lib.package.create-packages { user-packages = snowfall-lib.package.create-packages {
pkgs = final; pkgs = final;
channels = channel-systems.${prev.system}; channels = channel-systems.${prev.system};
inherit namespace; inherit namespace;
}; };
in in
if namespace == null if namespace == null then
then user-packages user-packages
else { else
${namespace} = {
(prev.${namespace} or {}) ${namespace} = (prev.${namespace} or { }) // user-packages;
// user-packages;
}; };
create-overlay = ( create-overlay = (
overlays: file: let overlays: file:
let
name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory file); name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory file);
overlay = final: prev: let overlay =
final: prev:
let
channels = channel-systems.${prev.system}; channels = channel-systems.${prev.system};
user-overlay = import file ( user-overlay = import file (
# Deprecated: Use `inputs.*` instead of referencing the input name directly. # Deprecated: Use `inputs.*` instead of referencing the input name directly.
@@ -111,29 +127,24 @@ in {
); );
packages = user-packages-overlay final prev; packages = user-packages-overlay final prev;
prev-with-packages = prev-with-packages =
if namespace == null if namespace == null then
then prev // packages prev // packages
else else
prev prev
// { // {
${namespace} = ${namespace} = (prev.${namespace} or { }) // packages.${namespace};
(prev.${namespace} or {})
// packages.${namespace};
}; };
user-overlay-packages = user-overlay-packages = user-overlay final prev-with-packages;
user-overlay outputs = user-overlay-packages;
final
prev-with-packages;
outputs =
user-overlay-packages;
in in
if user-overlay-packages.__dontExport or false == true if user-overlay-packages.__dontExport or false == true then
then outputs // {__dontExport = true;} outputs // { __dontExport = true; }
else outputs; else
outputs;
fake-overlay-result = overlay fake-pkgs fake-pkgs; fake-overlay-result = overlay fake-pkgs fake-pkgs;
in in
if fake-overlay-result.__dontExport or false == true if fake-overlay-result.__dontExport or false == true then
then overlays overlays
else else
overlays overlays
// { // {
@@ -141,29 +152,30 @@ in {
} }
); );
overlays = overlays = foldl create-overlay { } user-overlays;
foldl
create-overlay
{}
user-overlays;
user-packages = snowfall-lib.fs.get-default-nix-files-recursive packages-src; user-packages = snowfall-lib.fs.get-default-nix-files-recursive packages-src;
create-package-overlay = package-overlays: file: let create-package-overlay =
package-overlays: file:
let
name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory file); name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory file);
overlay = final: prev: let overlay =
final: prev:
let
channels = channel-systems.${prev.system}; channels = channel-systems.${prev.system};
packages = snowfall-lib.package.create-packages { packages = snowfall-lib.package.create-packages {
inherit namespace; inherit namespace;
channels = channel-systems.${prev.system}; channels = channel-systems.${prev.system};
}; };
in in
if namespace == null if namespace == null then
then {${name} = packages.${name};} { ${name} = packages.${name}; }
else { else
${namespace} = {
(prev.${namespace} or {}) ${namespace} = (prev.${namespace} or { }) // {
// {${name} = packages.${name};}; ${name} = packages.${name};
};
}; };
in in
package-overlays package-overlays
@@ -171,28 +183,23 @@ in {
"package/${name}" = overlay; "package/${name}" = overlay;
}; };
package-overlays = package-overlays = foldl create-package-overlay { } user-packages;
foldl
create-package-overlay
{}
user-packages;
default-overlay = final: prev: let default-overlay =
final: prev:
let
overlays-list = builtins.attrValues overlays; overlays-list = builtins.attrValues overlays;
package-overlays-list = builtins.attrValues package-overlays; package-overlays-list = builtins.attrValues package-overlays;
overlays-results = builtins.map (overlay: overlay final prev) overlays-list; overlays-results = builtins.map (overlay: overlay final prev) overlays-list;
package-overlays-results = builtins.map (overlay: overlay final prev) package-overlays-list; package-overlays-results = builtins.map (overlay: overlay final prev) package-overlays-list;
merged-results = merged-results = snowfall-lib.attrs.merge-shallow-packages (
snowfall-lib.attrs.merge-shallow-packages package-overlays-results ++ overlays-results
(package-overlays-results ++ overlays-results); );
in in
merged-results; merged-results;
in in
package-overlays package-overlays // overlays // { default = default-overlay; } // extra-overlays;
// overlays
// {default = default-overlay;}
// extra-overlays;
}; };
} }

View File

@@ -3,12 +3,20 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (core-inputs.flake-utils-plus.lib) filterPackages allSystems; inherit (core-inputs.flake-utils-plus.lib) filterPackages allSystems;
inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs filterAttrs callPackageWith; inherit (core-inputs.nixpkgs.lib)
assertMsg
foldl
mapAttrs
filterAttrs
callPackageWith
;
user-packages-root = snowfall-lib.fs.get-snowfall-file "packages"; user-packages-root = snowfall-lib.fs.get-snowfall-file "packages";
in { in
{
package = rec { package = rec {
## Create flake output packages. ## Create flake output packages.
## Example Usage: ## Example Usage:
@@ -20,16 +28,20 @@ in {
## { another-package = ...; my-package = ...; default = ...; } ## { another-package = ...; my-package = ...; default = ...; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-packages = { create-packages =
{
channels, channels,
src ? user-packages-root, src ? user-packages-root,
pkgs ? channels.nixpkgs, pkgs ? channels.nixpkgs,
overrides ? { }, overrides ? { },
alias ? { }, alias ? { },
namespace ? snowfall-config.namespace, namespace ? snowfall-config.namespace,
}: let }:
let
user-packages = snowfall-lib.fs.get-default-nix-files-recursive src; user-packages = snowfall-lib.fs.get-default-nix-files-recursive src;
create-package-metadata = package: let create-package-metadata =
package:
let
namespaced-packages = { namespaced-packages = {
${namespace} = packages-without-aliases; ${namespace} = packages-without-aliases;
}; };
@@ -42,16 +54,16 @@ in {
pkgs = pkgs // namespaced-packages; pkgs = pkgs // namespaced-packages;
inputs = user-inputs; inputs = user-inputs;
}; };
in { in
{
name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory package); name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory package);
drv = let drv =
let
pkg = callPackageWith extra-inputs package { }; pkg = callPackageWith extra-inputs package { };
in in
pkg pkg
// { // {
meta = meta = (pkg.meta or { }) // {
(pkg.meta or {})
// {
snowfall = { snowfall = {
path = package; path = package;
}; };
@@ -59,7 +71,8 @@ in {
}; };
}; };
packages-metadata = builtins.map create-package-metadata user-packages; packages-metadata = builtins.map create-package-metadata user-packages;
merge-packages = packages: metadata: merge-packages =
packages: metadata:
packages packages
// { // {
${metadata.name} = metadata.drv; ${metadata.name} = metadata.drv;

View File

@@ -3,12 +3,19 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
inherit (builtins) toString baseNameOf dirOf concatStringsSep; let
inherit (builtins)
toString
baseNameOf
dirOf
concatStringsSep
;
inherit (core-inputs.nixpkgs.lib) assertMsg last init; inherit (core-inputs.nixpkgs.lib) assertMsg last init;
file-name-regex = "(.*)\\.(.*)$"; file-name-regex = "(.*)\\.(.*)$";
in { in
{
path = rec { path = rec {
## Split a file name and its extension. ## Split a file name and its extension.
## Example Usage: ## Example Usage:
@@ -20,10 +27,15 @@ in {
## [ "my-file" "md" ] ## [ "my-file" "md" ]
## ``` ## ```
#@ String -> [String] #@ String -> [String]
split-file-extension = file: let split-file-extension =
file:
let
match = builtins.match file-name-regex file; match = builtins.match file-name-regex file;
in in
assert assertMsg (match != null) "lib.snowfall.split-file-extension: File must have an extension to split."; match; assert assertMsg (
match != null
) "lib.snowfall.split-file-extension: File must have an extension to split.";
match;
## Check if a file name has a file extension. ## Check if a file name has a file extension.
## Example Usage: ## Example Usage:
@@ -35,7 +47,9 @@ in {
## true ## true
## ``` ## ```
#@ String -> Bool #@ String -> Bool
has-any-file-extension = file: let has-any-file-extension =
file:
let
match = builtins.match file-name-regex (toString file); match = builtins.match file-name-regex (toString file);
in in
match != null; match != null;
@@ -50,13 +64,15 @@ in {
## "txt" ## "txt"
## ``` ## ```
#@ String -> String #@ String -> String
get-file-extension = file: get-file-extension =
if has-any-file-extension file file:
then let if has-any-file-extension file then
let
match = builtins.match file-name-regex (toString file); match = builtins.match file-name-regex (toString file);
in in
last match last match
else ""; else
"";
## Check if a file name has a specific file extension. ## Check if a file name has a specific file extension.
## Example Usage: ## Example Usage:
@@ -68,10 +84,9 @@ in {
## true ## true
## ``` ## ```
#@ String -> String -> Bool #@ String -> String -> Bool
has-file-extension = extension: file: has-file-extension =
if has-any-file-extension file extension: file:
then extension == get-file-extension file if has-any-file-extension file then extension == get-file-extension file else false;
else false;
## Get the parent directory for a given path. ## Get the parent directory for a given path.
## Example Usage: ## Example Usage:
@@ -95,11 +110,14 @@ in {
## "my-file" ## "my-file"
## ``` ## ```
#@ Path -> String #@ Path -> String
get-file-name-without-extension = path: let get-file-name-without-extension =
path:
let
file-name = baseNameOf path; file-name = baseNameOf path;
in in
if has-any-file-extension file-name if has-any-file-extension file-name then
then concatStringsSep "" (init (split-file-extension file-name)) concatStringsSep "" (init (split-file-extension file-name))
else file-name; else
file-name;
}; };
} }

View File

@@ -3,12 +3,19 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (core-inputs.flake-utils-plus.lib) filterPackages; inherit (core-inputs.flake-utils-plus.lib) filterPackages;
inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs callPackageWith; inherit (core-inputs.nixpkgs.lib)
assertMsg
foldl
mapAttrs
callPackageWith
;
user-shells-root = snowfall-lib.fs.get-snowfall-file "shells"; user-shells-root = snowfall-lib.fs.get-snowfall-file "shells";
in { in
{
shell = { shell = {
## Create flake output packages. ## Create flake output packages.
## Example Usage: ## Example Usage:
@@ -20,29 +27,33 @@ in {
## { another-shell = ...; my-shell = ...; default = ...; } ## { another-shell = ...; my-shell = ...; default = ...; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-shells = { create-shells =
{
channels, channels,
src ? user-shells-root, src ? user-shells-root,
pkgs ? channels.nixpkgs, pkgs ? channels.nixpkgs,
overrides ? { }, overrides ? { },
alias ? { }, alias ? { },
}: let }:
let
user-shells = snowfall-lib.fs.get-default-nix-files-recursive src; user-shells = snowfall-lib.fs.get-default-nix-files-recursive src;
create-shell-metadata = shell: let create-shell-metadata =
extra-inputs = shell:
pkgs let
// { extra-inputs = pkgs // {
inherit channels; inherit channels;
lib = snowfall-lib.internal.system-lib; lib = snowfall-lib.internal.system-lib;
inputs = snowfall-lib.flake.without-src user-inputs; inputs = snowfall-lib.flake.without-src user-inputs;
namespace = snowfall-config.namespace; namespace = snowfall-config.namespace;
}; };
in { in
{
name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory shell); name = builtins.unsafeDiscardStringContext (snowfall-lib.path.get-parent-directory shell);
drv = callPackageWith extra-inputs shell { }; drv = callPackageWith extra-inputs shell { };
}; };
shells-metadata = builtins.map create-shell-metadata user-shells; shells-metadata = builtins.map create-shell-metadata user-shells;
merge-shells = shells: metadata: merge-shells =
shells: metadata:
shells shells
// { // {
${metadata.name} = metadata.drv; ${metadata.name} = metadata.drv;

View File

@@ -3,15 +3,25 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (builtins) dirOf baseNameOf; inherit (builtins) dirOf baseNameOf;
inherit (core-inputs.nixpkgs.lib) assertMsg fix hasInfix concatMap foldl optionals singleton; inherit (core-inputs.nixpkgs.lib)
assertMsg
fix
hasInfix
concatMap
foldl
optionals
singleton
;
virtual-systems = import ./virtual-systems.nix; virtual-systems = import ./virtual-systems.nix;
user-systems-root = snowfall-lib.fs.get-snowfall-file "systems"; user-systems-root = snowfall-lib.fs.get-snowfall-file "systems";
user-modules-root = snowfall-lib.fs.get-snowfall-file "modules"; user-modules-root = snowfall-lib.fs.get-snowfall-file "modules";
in { in
{
system = rec { system = rec {
## Get the name of a system based on its file path. ## Get the name of a system based on its file path.
## Example Usage: ## Example Usage:
@@ -23,10 +33,12 @@ in {
## "my-system" ## "my-system"
## ``` ## ```
#@ Path -> String #@ Path -> String
get-inferred-system-name = path: get-inferred-system-name =
if snowfall-lib.path.has-file-extension "nix" path path:
then snowfall-lib.path.get-parent-directory path if snowfall-lib.path.has-file-extension "nix" path then
else baseNameOf path; snowfall-lib.path.get-parent-directory path
else
baseNameOf path;
## Check whether a named system is macOS. ## Check whether a named system is macOS.
## Example Usage: ## Example Usage:
@@ -62,8 +74,7 @@ in {
## true ## true
## ``` ## ```
#@ String -> Bool #@ String -> Bool
is-virtual = target: is-virtual = target: (get-virtual-system-type target) != "";
(get-virtual-system-type target) != "";
## Get the virtual system type of a system target. ## Get the virtual system type of a system target.
## Example Usage: ## Example Usage:
@@ -75,16 +86,12 @@ in {
## "iso" ## "iso"
## ``` ## ```
#@ String -> String #@ String -> String
get-virtual-system-type = target: get-virtual-system-type =
foldl target:
( foldl (
result: virtual-system: result: virtual-system:
if result == "" && hasInfix virtual-system target if result == "" && hasInfix virtual-system target then virtual-system else result
then virtual-system ) "" virtual-systems;
else result
)
""
virtual-systems;
## Get structured data about all systems for a given target. ## Get structured data about all systems for a given target.
## Example Usage: ## Example Usage:
@@ -96,7 +103,9 @@ in {
## [ { target = "x86_64-linux"; name = "my-machine"; path = "/systems/x86_64-linux/my-machine"; } ] ## [ { target = "x86_64-linux"; name = "my-machine"; path = "/systems/x86_64-linux/my-machine"; } ]
## ``` ## ```
#@ String -> [Attrs] #@ String -> [Attrs]
get-target-systems-metadata = target: let get-target-systems-metadata =
target:
let
systems = snowfall-lib.fs.get-directories target; systems = snowfall-lib.fs.get-directories target;
existing-systems = builtins.filter (system: builtins.pathExists "${system}/default.nix") systems; existing-systems = builtins.filter (system: builtins.pathExists "${system}/default.nix") systems;
create-system-metadata = path: { create-system-metadata = path: {
@@ -124,62 +133,66 @@ in {
## (args: <system>) ## (args: <system>)
## ``` ## ```
#@ String -> Function #@ String -> Function
get-system-builder = target: let get-system-builder =
target:
let
virtual-system-type = get-virtual-system-type target; virtual-system-type = get-virtual-system-type target;
virtual-system-builder = args: virtual-system-builder =
assert assertMsg (user-inputs ? nixos-generators) "In order to create virtual systems, you must include `nixos-generators` as a flake input."; args:
user-inputs.nixos-generators.nixosGenerate assert assertMsg (
(args user-inputs ? nixos-generators
) "In order to create virtual systems, you must include `nixos-generators` as a flake input.";
user-inputs.nixos-generators.nixosGenerate (
args
// { // {
format = virtual-system-type; format = virtual-system-type;
specialArgs = specialArgs = args.specialArgs // {
args.specialArgs
// {
format = virtual-system-type; format = virtual-system-type;
}; };
modules = modules = args.modules ++ [
args.modules
++ [
../../modules/nixos/user/default.nix ../../modules/nixos/user/default.nix
]; ];
}); }
darwin-system-builder = args: );
assert assertMsg (user-inputs ? darwin) "In order to create virtual systems, you must include `darwin` as a flake input."; darwin-system-builder =
user-inputs.darwin.lib.darwinSystem args:
((builtins.removeAttrs args ["system" "modules"]) assert assertMsg (
// { user-inputs ? darwin
specialArgs = ) "In order to create virtual systems, you must include `darwin` as a flake input.";
args.specialArgs user-inputs.darwin.lib.darwinSystem (
(builtins.removeAttrs args [
"system"
"modules"
])
// { // {
specialArgs = args.specialArgs // {
format = "darwin"; format = "darwin";
}; };
modules = modules = args.modules ++ [
args.modules
++ [
../../modules/darwin/user/default.nix ../../modules/darwin/user/default.nix
]; ];
}); }
linux-system-builder = args: );
core-inputs.nixpkgs.lib.nixosSystem linux-system-builder =
(args args:
// { core-inputs.nixpkgs.lib.nixosSystem (
specialArgs = args
args.specialArgs
// { // {
specialArgs = args.specialArgs // {
format = "linux"; format = "linux";
}; };
modules = modules = args.modules ++ [
args.modules
++ [
../../modules/nixos/user/default.nix ../../modules/nixos/user/default.nix
]; ];
}); }
);
in in
if virtual-system-type != "" if virtual-system-type != "" then
then virtual-system-builder virtual-system-builder
else if is-darwin target else if is-darwin target then
then darwin-system-builder darwin-system-builder
else linux-system-builder; else
linux-system-builder;
## Get the flake output attribute for a system target. ## Get the flake output attribute for a system target.
## Example Usage: ## Example Usage:
@@ -191,14 +204,17 @@ in {
## "darwinConfigurations" ## "darwinConfigurations"
## ``` ## ```
#@ String -> String #@ String -> String
get-system-output = target: let get-system-output =
target:
let
virtual-system-type = get-virtual-system-type target; virtual-system-type = get-virtual-system-type target;
in in
if virtual-system-type != "" if virtual-system-type != "" then
then "${virtual-system-type}Configurations" "${virtual-system-type}Configurations"
else if is-darwin target else if is-darwin target then
then "darwinConfigurations" "darwinConfigurations"
else "nixosConfigurations"; else
"nixosConfigurations";
## Get the resolved (non-virtual) system target. ## Get the resolved (non-virtual) system target.
## Example Usage: ## Example Usage:
@@ -210,12 +226,15 @@ in {
## "x86_64-linux" ## "x86_64-linux"
## ``` ## ```
#@ String -> String #@ String -> String
get-resolved-system-target = target: let get-resolved-system-target =
target:
let
virtual-system-type = get-virtual-system-type target; virtual-system-type = get-virtual-system-type target;
in in
if virtual-system-type != "" if virtual-system-type != "" then
then builtins.replaceStrings [virtual-system-type] ["linux"] target builtins.replaceStrings [ virtual-system-type ] [ "linux" ] target
else target; else
target;
## Create a system. ## Create a system.
## Example Usage: ## Example Usage:
@@ -227,7 +246,8 @@ in {
## <flake-utils-plus-system-configuration> ## <flake-utils-plus-system-configuration>
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-system = { create-system =
{
target ? "x86_64-linux", target ? "x86_64-linux",
system ? get-resolved-system-target target, system ? get-resolved-system-target target,
path, path,
@@ -239,23 +259,34 @@ in {
output ? get-system-output target, output ? get-system-output target,
systems ? { }, systems ? { },
homes ? { }, homes ? { },
}: let }:
let
lib = snowfall-lib.internal.system-lib; lib = snowfall-lib.internal.system-lib;
home-system-modules = snowfall-lib.home.create-home-system-modules homes; home-system-modules = snowfall-lib.home.create-home-system-modules homes;
home-manager-module = home-manager-module =
if is-darwin system if is-darwin system then
then user-inputs.home-manager.darwinModules.home-manager user-inputs.home-manager.darwinModules.home-manager
else user-inputs.home-manager.nixosModules.home-manager; else
user-inputs.home-manager.nixosModules.home-manager;
home-manager-modules = [ home-manager-module ] ++ home-system-modules; home-manager-modules = [ home-manager-module ] ++ home-system-modules;
in { in
inherit channelName system builder output; {
inherit
channelName
system
builder
output
;
modules = [ path ] ++ modules ++ (optionals (user-inputs ? home-manager) home-manager-modules); modules = [ path ] ++ modules ++ (optionals (user-inputs ? home-manager) home-manager-modules);
specialArgs = specialArgs = specialArgs // {
specialArgs inherit
// { target
inherit target system systems lib; system
systems
lib
;
host = name; host = name;
virtual = (get-virtual-system-type target) != ""; virtual = (get-virtual-system-type target) != "";
@@ -274,10 +305,12 @@ in {
## { my-host = <flake-utils-plus-system-configuration>; } ## { my-host = <flake-utils-plus-system-configuration>; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-systems = { create-systems =
{
systems ? { }, systems ? { },
homes ? { }, homes ? { },
}: let }:
let
targets = snowfall-lib.fs.get-directories user-systems-root; targets = snowfall-lib.fs.get-directories user-systems-root;
target-systems-metadata = concatMap get-target-systems-metadata targets; target-systems-metadata = concatMap get-target-systems-metadata targets;
user-nixos-modules = snowfall-lib.module.create-modules { user-nixos-modules = snowfall-lib.module.create-modules {
@@ -289,35 +322,30 @@ in {
nixos-modules = systems.modules.nixos or [ ]; nixos-modules = systems.modules.nixos or [ ];
darwin-modules = systems.modules.darwin or [ ]; darwin-modules = systems.modules.darwin or [ ];
create-system' = created-systems: system-metadata: let create-system' =
created-systems: system-metadata:
let
overrides = systems.hosts.${system-metadata.name} or { }; overrides = systems.hosts.${system-metadata.name} or { };
user-modules = user-modules = if is-darwin system-metadata.target then user-darwin-modules else user-nixos-modules;
if is-darwin system-metadata.target
then user-darwin-modules
else user-nixos-modules;
user-modules-list = builtins.attrValues user-modules; user-modules-list = builtins.attrValues user-modules;
system-modules = system-modules = if is-darwin system-metadata.target then darwin-modules else nixos-modules;
if is-darwin system-metadata.target in
then darwin-modules {
else nixos-modules; ${system-metadata.name} = create-system (
in { overrides
${system-metadata.name} = create-system (overrides
// system-metadata // system-metadata
// { // {
systems = created-systems; systems = created-systems;
modules = user-modules-list ++ (overrides.modules or [ ]) ++ system-modules; modules = user-modules-list ++ (overrides.modules or [ ]) ++ system-modules;
inherit homes; inherit homes;
}); }
);
}; };
created-systems = fix ( created-systems = fix (
created-systems: created-systems:
foldl foldl (
( systems: system-metadata: systems // (create-system' created-systems system-metadata)
systems: system-metadata: ) { } target-systems-metadata
systems // (create-system' created-systems system-metadata)
)
{}
target-systems-metadata
); );
in in
created-systems; created-systems;

View File

@@ -3,12 +3,14 @@
user-inputs, user-inputs,
snowfall-lib, snowfall-lib,
snowfall-config, snowfall-config,
}: let }:
let
inherit (builtins) baseNameOf; inherit (builtins) baseNameOf;
inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs; inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs;
user-templates-root = snowfall-lib.fs.get-snowfall-file "templates"; user-templates-root = snowfall-lib.fs.get-snowfall-file "templates";
in { in
{
template = { template = {
## Create flake templates. ## Create flake templates.
## ##
@@ -22,41 +24,40 @@ in {
## { another-template = ...; my-template = ...; default = ...; } ## { another-template = ...; my-template = ...; default = ...; }
## ``` ## ```
#@ Attrs -> Attrs #@ Attrs -> Attrs
create-templates = { create-templates =
{
src ? user-templates-root, src ? user-templates-root,
overrides ? { }, overrides ? { },
alias ? { }, alias ? { },
}: let }:
let
user-templates = snowfall-lib.fs.get-directories src; user-templates = snowfall-lib.fs.get-directories src;
create-template-metadata = template: let create-template-metadata =
template:
let
flake-file = template + "/flake.nix"; flake-file = template + "/flake.nix";
has-flake = builtins.pathExists flake-file; has-flake = builtins.pathExists flake-file;
flake-attrs = flake-attrs = if has-flake then import flake-file else { };
if has-flake
then import flake-file
else {};
description = flake-attrs.description or null; description = flake-attrs.description or null;
in in
{ {
name = builtins.unsafeDiscardStringContext (baseNameOf template); name = builtins.unsafeDiscardStringContext (baseNameOf template);
path = template; path = template;
} }
// ( // (if description != null then { inherit description; } else { });
if description != null
then {inherit description;}
else {}
);
templates-metadata = builtins.map create-template-metadata user-templates; templates-metadata = builtins.map create-template-metadata user-templates;
merge-templates = templates: metadata: merge-templates =
templates: metadata:
templates templates
// { // {
${metadata.name} = ${metadata.name} =
(overrides.${metadata.name} or {}) (overrides.${metadata.name} or { }) // (builtins.removeAttrs metadata [ "name" ]);
// (builtins.removeAttrs metadata ["name"]);
}; };
templates-without-aliases = foldl merge-templates { } templates-metadata; templates-without-aliases = foldl merge-templates { } templates-metadata;
aliased-templates = mapAttrs (name: value: templates-without-aliases.${value}) alias; aliased-templates = mapAttrs (name: value: templates-without-aliases.${value}) alias;
unused-overrides = builtins.removeAttrs overrides (builtins.map (metadata: metadata.name) templates-metadata); unused-overrides = builtins.removeAttrs overrides (
builtins.map (metadata: metadata.name) templates-metadata
);
templates = templates-without-aliases // aliased-templates // unused-overrides; templates = templates-without-aliases // aliased-templates // unused-overrides;
in in
templates; templates;