1
0
Fork 0
mirror of https://github.com/hercules-ci/flake-parts.git synced 2024-12-14 11:47:31 +00:00
flake-parts/lib.nix

230 lines
6.7 KiB
Nix
Raw Normal View History

2023-05-31 14:31:11 +00:00
{ lib
# Optionally a string with extra version info to be included in the error message
# in case is lib is out of date. Empty or starts with space.
, revInfo ? ""
}:
2021-10-27 09:05:52 +00:00
let
inherit (lib)
mkOption
mkOptionType
defaultFunctor
isAttrs
isFunction
showOption
2022-12-17 17:36:15 +00:00
throwIf
2021-10-27 09:05:52 +00:00
types
2022-12-17 17:36:15 +00:00
warnIf
getAttrFromPath
setAttrByPath
attrByPath
optionalAttrs
2021-10-27 09:05:52 +00:00
;
inherit (lib.modules)
mkAliasAndWrapDefsWithPriority;
inherit (lib.types)
path
submoduleWith
;
2021-10-27 09:05:52 +00:00
# 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 https://github.com/NixOS/nixpkgs/pull/163617
deferredModuleWith = lib.deferredModuleWith or (
attrs@{ staticModules ? [ ] }: mkOptionType {
name = "deferredModule";
description = "module";
check = x: isAttrs x || isFunction x || path.check x;
merge = loc: defs: staticModules ++ map (def: lib.setDefaultModuleLocation "${def.file}, via option ${showOption loc}" def.value) defs;
inherit (submoduleWith { modules = staticModules; })
getSubOptions
getSubModules;
substSubModules = m: deferredModuleWith (attrs // {
staticModules = m;
});
functor = defaultFunctor "deferredModuleWith" // {
type = deferredModuleWith;
payload = {
inherit staticModules;
};
binOp = lhs: rhs: {
staticModules = lhs.staticModules ++ rhs.staticModules;
};
};
}
);
2022-12-17 17:36:15 +00:00
errorExample = ''
For example:
outputs = inputs@{ flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } { /* module */ };
To avoid an infinite recursion, *DO NOT* pass `self.inputs` and
*DO NOT* pass `inherit (self) inputs`, but pass the output function
arguments as `inputs` like above.
'';
2023-05-07 02:30:03 +00:00
flake-parts-lib = rec {
2021-10-27 09:05:52 +00:00
evalFlakeModule =
2022-12-17 17:36:15 +00:00
args@
{ inputs ? self.inputs
2021-10-27 09:05:52 +00:00
, specialArgs ? { }
2022-12-17 17:36:15 +00:00
# legacy
, self ? inputs.self or (throw ''
When invoking flake-parts, you must pass all the flake output arguments,
and not just `self.inputs`.
${errorExample}
'')
2021-10-27 09:05:52 +00:00
}:
2022-12-17 17:36:15 +00:00
throwIf
(!args?self && !args?inputs) ''
When invoking flake-parts, you must pass in the flake output arguments.
2021-10-27 09:05:52 +00:00
2022-12-17 17:36:15 +00:00
${errorExample}
''
warnIf
(!args?inputs) ''
When invoking flake-parts, it is recommended to pass all the flake output
arguments in the `inputs` parameter. If you only pass `self`, it's not
possible to use the `inputs` module argument in the module `imports`.
Please pass the output function arguments. ${errorExample}
''
(module:
lib.evalModules {
specialArgs = {
inherit self flake-parts-lib;
inputs = args.inputs or /* legacy, warned above */ self.inputs;
} // specialArgs;
modules = [ ./all-modules.nix module ];
}
);
2021-11-21 14:47:11 +00:00
# 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 =
if args?inputs.self.outPath
then args.inputs.self.outPath + "/flake.nix"
else "<mkFlake argument>";
mod = lib.setDefaultModuleLocation loc module;
eval = flake-parts-lib.evalFlakeModule args mod;
in
eval.config.flake;
2021-11-21 14:47:11 +00:00
# For extending options in an already declared submodule.
# Workaround for https://github.com/NixOS/nixpkgs/issues/146882
mkSubmoduleOptions =
options:
mkOption {
type = types.submoduleWith {
2022-05-17 08:28:03 +00:00
modules = [{ inherit options; }];
2021-11-21 14:47:11 +00:00
};
};
2022-05-17 08:28:03 +00:00
2023-05-07 20:42:48 +00:00
mkDeferredModuleType =
2022-05-13 08:14:10 +00:00
module:
deferredModuleWith {
staticModules = [ module ];
};
2023-05-07 02:30:03 +00:00
mkPerSystemType = mkDeferredModuleType;
2022-05-13 08:14:10 +00:00
2023-05-07 02:30:03 +00:00
mkDeferredModuleOption =
2022-05-13 08:14:10 +00:00
module:
mkOption {
2022-05-25 14:36:33 +00:00
type = flake-parts-lib.mkPerSystemType module;
2022-05-13 08:14:10 +00:00
};
2023-05-07 02:30:03 +00:00
mkPerSystemOption = mkDeferredModuleOption;
2022-05-13 08:14:10 +00:00
# Helper function for defining a per-system option that
# gets transposed by the usual flake system logic to a
# top-level flake attribute.
mkTransposedPerSystemModule = { name, option, file }: {
_file = file;
options = {
flake = flake-parts-lib.mkSubmoduleOptions {
${name} = mkOption {
type = types.lazyAttrsOf option.type;
default = { };
2022-11-11 06:39:25 +00:00
description = ''
See {option}`perSystem.${name}` for description and examples.
'';
};
};
perSystem = flake-parts-lib.mkPerSystemOption {
_file = file;
options.${name} = option;
};
};
config = {
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;
});
2023-05-29 17:52:03 +00:00
config = mkAliasAndWrapDefsWithPriority (setAttrByPath to) fromOpt;
};
2023-05-07 22:48:08 +00:00
# Helper function for importing while preserving module location. To be added
# in nixpkgs: https://github.com/NixOS/nixpkgs/pull/230588
# I expect these functions to remain identical. This one will stick around
# for a while to support older nixpkgs-lib.
importApply =
modulePath: staticArgs:
lib.setDefaultModuleLocation modulePath (import modulePath staticArgs);
2021-10-27 09:05:52 +00:00
};
2021-11-21 14:47:11 +00:00
2023-05-31 14:31:11 +00:00
# A best effort, lenient estimate. Please use a recent nixpkgs lib if you
# override it at all.
minVersion = "22.05";
2021-10-27 09:05:52 +00:00
in
2023-05-31 14:31:11 +00:00
if builtins.compareVersions lib.version minVersion <= 0
then
abort ''
The nixpkgs-lib dependency of flake-parts was overridden but is too old.
The minimum supported version of nixpkgs-lib is ${minVersion},
but the actual version is ${lib.version}${revInfo}.
''
else
flake-parts-lib