diff --git a/README.md b/README.md index 555c27a..7921c79 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,10 @@ library instance with `mkLib`. # your flake. inherit inputs; src = ./.; + + # You can optionally place your Snowfall-related files in another + # directory. + snowfall.root = ./nix; }; in # We'll cover what to do here next. @@ -100,6 +104,10 @@ let lib = inputs.snowfall-lib.mkLib { inherit inputs; src = ./.; + + # You can optionally place your Snowfall-related files in another + # directory. + snowfall.root = ./nix; }; in lib.mkFlake { } @@ -150,7 +158,10 @@ Snowfall Lib has opinions about how a flake's files are laid out. This lets the structure that `lib` expects to find at the root of your flake. ``` -flake-root/ +snowfall-root/ +│ The Snowfall root defaults to "src", but can be changed by setting "snowfall.root". +│ This is useful if you want to add a flake to a project, but don't want to clutter the +│ root of the repository with directories. │ │ Your Nix flake. ├─ flake.nix @@ -383,7 +394,7 @@ on `pkgs` and consumers of your flake can use the generated `.overla Snowfall Lib will create packages and shells based on your `packages/` and `shells` directories. However, it is common to additionally map one of those packages or shells -to be their respective default. This can be achieved by using `outputs-builder` and +to be their respective default. This can be achieved by setting an `alias` and mapping the `default` package or shell to the name of the one you want. ```nix @@ -411,16 +422,22 @@ mapping the `default` package or shell to the name of the one you want. }; in lib.mkFlake { - # You can also pass through external packages or dynamically create new ones - # in addition to the ones that `lib` will create from your `packages/` directory. - outputs-builder = channels: { + alias = { packages = { default = "my-package"; }; - devShells = { + shells = { default = "my-shell"; }; + + modules = { + default = "my-module"; + }; + + templates = { + default = "my-template"; + }; }; }; } @@ -742,6 +759,24 @@ Result: "/user-source/systems" ``` +#### `lib.snowfall.fs.get-snowfall-file` + +Get a file path relative to the user's snowfall directory. + +Type: `Path -> Path` + +Usage: + +```nix +get-snowfall-file "systems" +``` + +Result: + +```nix +"/user-source/snowfall-dir/systems" +``` + #### `lib.snowfall.fs.internal-get-file` Get a file relative to the Snowfall Lib flake. You probably shouldn't use this! @@ -940,6 +975,28 @@ Result: [ "./something/some-directory/a.nix" ] ``` +### `lib.snowfall.module` + +Utilities for working with NixOS modules. + +#### `lib.snowfall.module.create-modules` + +Create flake output modules. + +Type: `Attrs -> Attrs` + +Usage: + +```nix +create-modules { src = ./my-modules; overrides = { inherit another-module; }; alias = { default = "another-module" }; } +``` + +Result: + +```nix +{ another-module = ...; my-module = ...; default = ...; } +``` + ### `lib.snowfall.attrs` Utilities for working with attribute sets. @@ -1226,7 +1283,7 @@ Type: `Attrs -> Attrs` Usage: ```nix -create-packages { inherit channels; src = ./my-packages; overrides = { inherit another-package; default = "my-package"; }; } +create-packages { inherit channels; src = ./my-packages; overrides = { inherit another-package; }; alias = { default = "another-package"; }; } ``` Result: @@ -1248,7 +1305,7 @@ Type: `Attrs -> Attrs` Usage: ```nix -create-shells { inherit channels; src = ./my-shells; overrides = { inherit another-shell; default = "my-shell"; }; } +create-shells { inherit channels; src = ./my-shells; overrides = { inherit another-shell; }; alias = { default = "another-shell"; }; } ``` Result: @@ -1321,7 +1378,7 @@ Type: `Attrs -> Attrs` Usage: ```nix -create-templates { src = ./my-templates; overrides = { inherit another-template; default = "my-template"; }; } +create-templates { src = ./my-templates; overrides = { inherit another-template; }; alias = { default = "another-template"; }; } ``` Result: diff --git a/lib/flake/default.nix b/lib/flake/default.nix index 318739b..60f2dbe 100644 --- a/lib/flake/default.nix +++ b/lib/flake/default.nix @@ -46,6 +46,7 @@ rec { "channels-config" "templates" "overlay-package-namespace" + "alias" ]; # Transform an attribute set of inputs into an attribute set where @@ -70,13 +71,16 @@ rec { mkFlake = full-flake-options: let custom-flake-options = flake.without-snowfall-options full-flake-options; + alias = full-flake-options.alias or { }; systems = snowfall-lib.system.create-systems (full-flake-options.systems or { }); hosts = snowfall-lib.attrs.merge-shallow [ (full-flake-options.systems.hosts or { }) systems ]; templates = snowfall-lib.template.create-templates { overrides = (full-flake-options.templates or { }); + alias = alias.templates or { }; }; modules = snowfall-lib.module.create-modules { overrides = (full-flake-options.modules or { }); + alias = alias.modules or { }; }; overlays = snowfall-lib.overlay.create-overlays { overlay-package-namespace = full-flake-options.overlay-package-namespace or null; @@ -93,10 +97,12 @@ rec { packages = snowfall-lib.package.create-packages { inherit channels; overrides = (full-flake-options.packages or { }) // (user-outputs.packages or { }); + alias = alias.packages or { }; }; shells = snowfall-lib.shell.create-shells { inherit channels; overrides = (full-flake-options.shells or { }) // (user-outputs.devShells or { }); + alias = alias.shells or { }; }; outputs = { diff --git a/lib/fs/default.nix b/lib/fs/default.nix index 48910ad..3791a81 100644 --- a/lib/fs/default.nix +++ b/lib/fs/default.nix @@ -27,6 +27,12 @@ in # result: "/user-source/systems" get-file = path: "${user-inputs.src}/${path}"; + # Get a file path relative to the user's snowfall directory. + # Type: Path -> Path + # Usage: get-snowfall-file "systems" + # result: "/user-source/snowfall-dir/systems" + get-snowfall-file = path: "${user-inputs.snowfall.root or user-inputs.src}/${path}"; + # Get a file path relative to the this flake. # Type: Path -> Path # Usage: get-file "systems" @@ -41,7 +47,7 @@ in if pathExists path then readDir path else - {}; + { }; # Get directories at a given path. # Type: Path -> [Path] @@ -52,7 +58,7 @@ in entries = safe-read-directory path; filtered-entries = filterAttrs (name: kind: is-directory-kind kind) entries; in - mapAttrsToList (name: kind: "${path}/${name}") filtered-entries; + mapAttrsToList (name: kind: "${path}/${name}") filtered-entries; # Get files at a given path. # Type: Path -> [Path] @@ -63,7 +69,7 @@ in entries = safe-read-directory path; filtered-entries = filterAttrs (name: kind: is-file-kind kind) entries; in - mapAttrsToList (name: kind: "${path}/${name}") filtered-entries; + mapAttrsToList (name: kind: "${path}/${name}") filtered-entries; # Get files at a given path, traversing any directories within. # Type: Path -> [Path] @@ -79,7 +85,8 @@ in map-file = name: kind: let path' = "${path}/${name}"; - in if is-directory-kind kind then + in + if is-directory-kind kind then get-files-recursive path' else path'; @@ -122,8 +129,8 @@ in # result: [ "./something/some-directory/default.nix" ] get-default-nix-files-recursive = 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". # Type: Path -> [Path] @@ -144,10 +151,10 @@ in # result: [ "./something/some-directory/a.nix" ] get-non-default-nix-files-recursive = path: builtins.filter - (name: - (snowfall-lib.path.has-file-extension "nix" name) - && (builtins.baseNameOf name != "default.nix") - ) - (get-files-recursive path); + (name: + (snowfall-lib.path.has-file-extension "nix" name) + && (builtins.baseNameOf name != "default.nix") + ) + (get-files-recursive path); }; } diff --git a/lib/module/default.nix b/lib/module/default.nix index 5e9f874..9243d0d 100644 --- a/lib/module/default.nix +++ b/lib/module/default.nix @@ -5,19 +5,20 @@ let inherit (builtins) baseNameOf; - inherit (core-inputs.nixpkgs.lib) assertMsg foldl; + inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs; - user-modules-root = snowfall-lib.fs.get-file "modules"; + user-modules-root = snowfall-lib.fs.get-snowfall-file "modules"; in { module = { # Create flake output modules. # Type: Attrs -> Attrs - # Usage: create-modules { src = ./my-modules; overrides = { inherit another-module; default = "my-module"; }; } + # Usage: create-modules { src = ./my-modules; overrides = { inherit another-module; }; alias = { default = "another-module" }; } # result: { another-module = ...; my-module = ...; default = ...; } create-modules = { src ? user-modules-root , overrides ? { } + , alias ? { } }: let user-modules = snowfall-lib.fs.get-default-nix-files-recursive src; @@ -30,18 +31,9 @@ in modules // { ${metadata.name} = import metadata.path; }; - modules-without-default = foldl merge-modules { } modules-metadata; - default-module = - if overrides.default or null == null then - { } - else if builtins.isAttrs overrides.default then - { default = overrides.default; } - else if modules-without-default.${overrides.default} or null != null then - { default = modules-without-default.${overrides.default}; } - else - { }; - overrides-without-default = builtins.removeAttrs overrides [ "default" ]; - modules = modules-without-default // default-module // overrides-without-default; + modules-without-aliases = foldl merge-modules { } modules-metadata; + aliased-modules = mapAttrs (name: value: modules-without-aliases.${value}) alias; + modules = modules-without-aliases // aliased-modules // overrides; in modules; }; diff --git a/lib/overlay/default.nix b/lib/overlay/default.nix index bb2a26b..176e9d7 100644 --- a/lib/overlay/default.nix +++ b/lib/overlay/default.nix @@ -6,8 +6,8 @@ let inherit (core-inputs.nixpkgs.lib) assertMsg foldl concatStringsSep; - user-overlays-root = snowfall-lib.fs.get-file "overlays"; - user-packages-root = snowfall-lib.fs.get-file "packages"; + user-overlays-root = snowfall-lib.fs.get-snowfall-file "overlays"; + user-packages-root = snowfall-lib.fs.get-snowfall-file "packages"; in { overlay = { diff --git a/lib/package/default.nix b/lib/package/default.nix index 20339a7..a83fafe 100644 --- a/lib/package/default.nix +++ b/lib/package/default.nix @@ -5,21 +5,22 @@ let inherit (core-inputs.flake-utils-plus.lib) filterPackages; - inherit (core-inputs.nixpkgs.lib) assertMsg foldl; + inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs; - user-packages-root = snowfall-lib.fs.get-file "packages"; + user-packages-root = snowfall-lib.fs.get-snowfall-file "packages"; in { package = { # Create flake output packages. # Type: Attrs -> Attrs - # Usage: create-packages { inherit channels; src = ./my-packages; overrides = { inherit another-package; default = "my-package"; }; } + # Usage: create-packages { inherit channels; src = ./my-packages; overrides = { inherit another-package; }; alias.default = "another-package"; } # result: { another-package = ...; my-package = ...; default = ...; } create-packages = { channels , src ? user-packages-root , pkgs ? channels.nixpkgs , overrides ? { } + , alias ? { } }: let user-packages = snowfall-lib.fs.get-default-nix-files-recursive src; @@ -36,18 +37,9 @@ in packages // { ${metadata.name} = metadata.drv; }; - packages-without-default = foldl merge-packages { } packages-metadata; - default-package = - if overrides.default or null == null then - { } - else if builtins.isAttrs overrides.default then - { default = overrides.default; } - else if packages-without-default.${overrides.default} or null != null then - { default = packages-without-default.${overrides.default}; } - else - { }; - overrides-without-default = builtins.removeAttrs overrides [ "default" ]; - packages = packages-without-default // default-package // overrides-without-default; + packages-without-aliases = foldl merge-packages { } packages-metadata; + aliased-packages = mapAttrs (name: value: packages-without-aliases.${value}) alias; + packages = packages-without-aliases // aliased-packages // overrides; in filterPackages pkgs.system packages; }; diff --git a/lib/shell/default.nix b/lib/shell/default.nix index a99dac4..47161b6 100644 --- a/lib/shell/default.nix +++ b/lib/shell/default.nix @@ -4,20 +4,22 @@ }: let - inherit (core-inputs.nixpkgs.lib) assertMsg foldl; + inherit (core-inputs.flake-utils-plus.lib) filterPackages; + inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs; - user-shells-root = snowfall-lib.fs.get-file "shells"; + user-shells-root = snowfall-lib.fs.get-snowfall-file "shells"; in { shell = { # Create flake output packages. # Type: Attrs -> Attrs - # Usage: create-shells { inherit channels; src = ./my-shells; overrides = { inherit another-shell; default = "my-shell"; }; } + # Usage: create-shells { inherit channels; src = ./my-shells; overrides = { inherit another-shell; }; alias = { default = "another-shell"; }; } # result: { another-shell = ...; my-shell = ...; default = ...; } create-shells = { channels , src ? user-shells-root , overrides ? { } + , alias ? { } }: let user-shells = snowfall-lib.fs.get-default-nix-files-recursive src; @@ -35,19 +37,12 @@ in shells // { ${metadata.name} = metadata.drv; }; - shells-without-default = foldl merge-shells { } shells-metadata; - default-shell = - if overrides.default or null == null then - { } - else if builtins.isAttrs overrides.default then - { default = overrides.default; } - else if shells-without-default.${overrides.default} or null != null then - { default = shells-without-default.${overrides.default}; } - else - { }; - overrides-without-default = builtins.removeAttrs overrides [ "default" ]; - shells = shells-without-default // default-shell // overrides-without-default; + shells-without-aliases = foldl merge-shells { } shells-metadata; + aliased-shells = mapAttrs (name: value: shells-without-aliases.${value}) alias; + shells = shells-without-aliases // aliased-shells // overrides; in - shells; + filterPackages + channels.nixpkgs.system + shells; }; } diff --git a/lib/system/default.nix b/lib/system/default.nix index edb2f26..b2a5d1e 100644 --- a/lib/system/default.nix +++ b/lib/system/default.nix @@ -9,8 +9,8 @@ let virtual-systems = import ./virtual-systems.nix; - user-systems-root = snowfall-lib.fs.get-file "systems"; - user-modules-root = snowfall-lib.fs.get-file "modules"; + user-systems-root = snowfall-lib.fs.get-snowfall-file "systems"; + user-modules-root = snowfall-lib.fs.get-snowfall-file "modules"; get-inferred-system-name = path: if snowfall-lib.path.has-file-extension "nix" path then diff --git a/lib/template/default.nix b/lib/template/default.nix index 6f2a47b..3e04626 100644 --- a/lib/template/default.nix +++ b/lib/template/default.nix @@ -5,19 +5,20 @@ let inherit (builtins) baseNameOf; - inherit (core-inputs.nixpkgs.lib) assertMsg foldl; + inherit (core-inputs.nixpkgs.lib) assertMsg foldl mapAttrs; - user-templates-root = snowfall-lib.fs.get-file "templates"; + user-templates-root = snowfall-lib.fs.get-snowfall-file "templates"; in { template = { # Create flake templates. # Type: Attrs -> Attrs - # Usage: create-templates { src = ./my-templates; overrides = { inherit another-template; default = "my-template"; }; } + # Usage: create-templates { src = ./my-templates; overrides = { inherit another-template; }; alias = { default = "another-template"; }; } # result: { another-template = ...; my-template = ...; default = ...; } create-templates = { src ? user-templates-root , overrides ? { } + , alias ? { } }: let user-templates = snowfall-lib.fs.get-directories src; @@ -32,18 +33,9 @@ in inherit (metadata) path; }; }; - templates-without-default = foldl merge-templates { } templates-metadata; - default-template = - if overrides.default or null == null then - { } - else if builtins.isAttrs overrides.default then - { default = overrides.default; } - else if templates-without-default.${overrides.default} or null != null then - { default = templates-without-default.${overrides.default}; } - else - { }; - overrides-without-default = builtins.removeAttrs overrides [ "default" ]; - templates = templates-without-default // default-template // overrides-without-default; + templates-without-aliases = foldl merge-templates { } templates-metadata; + aliased-templates = mapAttrs (name: value: templates-without-aliases.${value}) alias; + templates = templates-without-aliases // aliased-templates // overrides; in templates; };