Skip to content

Commit

Permalink
Merge #61
Browse files Browse the repository at this point in the history
61: Add option for defining flake-parts modules for downstream flakes. r=roberth a=shlevy



Co-authored-by: Shea Levy <[email protected]>
  • Loading branch information
bors[bot] and shlevy authored Dec 27, 2022
2 parents f5bdec7 + 3c60ce7 commit 8bfe944
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
9 changes: 8 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 2022-12-25

- Added a new `flake.flakeModules` option so a flake can expose a module
to be used in a downstream flake's flake-parts usage. `.flakeModule` is
now an alias for `.flakeModules.default`.

Option only available if `flake-parts.flakeModules.flakeModules` is imported.

# 2022-12-17

Expand Down Expand Up @@ -30,7 +37,7 @@
- The `nixpkgs` input has been renamed to `nixpkgs-lib` to signify that the
only dependency is on the `lib` attribute, which can be provided by either
the `nixpkgs?dir=lib` subflake or by the `nixpkgs` flake itself.

- The templates now use the default, _fixed_ `nixpkgs?dir=lib` dependency instead
of a _following_ `nixpkgs` dependency.

Expand Down
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

outputs = { self, nixpkgs-lib, ... }: {
lib = import ./lib.nix { inherit (nixpkgs-lib) lib; };
flakeModules.flakeModules = ./modules/flakeModules.nix;
templates = {
default = {
path = ./template/default;
Expand Down
43 changes: 43 additions & 0 deletions lib.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,24 @@ let
throwIf
types
warnIf
getAttrFromPath
setAttrByPath
attrByPath
optionalAttrs
;
inherit (lib.modules)
mkAliasAndWrapDefsWithPriority;
inherit (lib.types)
path
submoduleWith
;

# Polyfill isFlake until Nix with https://github.com/NixOS/nix/pull/7207 is common
isFlake = maybeFlake:
if maybeFlake ? _type
then maybeFlake._type == "flake"
else maybeFlake ? inputs && maybeFlake ? outputs && maybeFlake ? sourceInfo;

# Polyfill functionTo to make sure it has type merging.
# Remove 2022-12
functionTo =
Expand Down Expand Up @@ -112,6 +124,17 @@ let
}
);

# Function to extract the default flakeModule from
# what may be a flake, returning the argument unmodified
# if it's not a flake.
#
# Useful to map over an 'imports' list to make it less
# verbose in the common case.
defaultModule = maybeFlake:
if isFlake maybeFlake
then maybeFlake.flakeModules.default or maybeFlake
else maybeFlake;

mkFlake = args: module:
let
loc =
Expand Down Expand Up @@ -173,6 +196,26 @@ let
transposition.${name} = { };
};
};

# Needed pending https://github.com/NixOS/nixpkgs/pull/198450
mkAliasOptionModule = from: to: { config, options, ... }:
let
fromOpt = getAttrFromPath from options;
toOf = attrByPath to
(abort "Renaming error: option `${showOption to}' does not exist.");
toType = let opt = attrByPath to { } options; in opt.type or (types.submodule { });
in
{
options = setAttrByPath from (mkOption
{
visible = true;
description = lib.mdDoc "Alias of {option}`${showOption to}`.";
apply = x: (toOf config);
} // optionalAttrs (toType != null) {
type = toType;
});
config = (mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt);
};
};

in
Expand Down
45 changes: 45 additions & 0 deletions modules/flakeModules.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{ config, self, lib, flake-parts-lib, ... }:
let
inherit (lib)
filterAttrs
mapAttrs
mkOption
optionalAttrs
types
;
inherit (flake-parts-lib)
mkAliasOptionModule
;

flakeModulesOption = mkOption {
type = types.lazyAttrsOf types.deferredModule;
default = { };
apply = mapAttrs (k: v: {
_file = "${toString self.outPath}/flake.nix#flakeModules.${k}";
imports = [ v ];
});
description = ''
flake-parts modules for use by other flakes.
If the flake defines only one module, it should be flakeModules.default.
You can not use this option in defining the flake's own `imports`. Instead, you can
put the module in question into its own file and reference it both in `imports` and
export it with this option.
'';
};
in
{
options = {
flake = mkOption {
type = types.submoduleWith {
modules = [
(mkAliasOptionModule [ "flakeModule" ] [ "flakeModules" "default" ])
{
options.flakeModules = flakeModulesOption;
}
];
};
};
};
}

0 comments on commit 8bfe944

Please sign in to comment.