1557cfd0c6
* unifyModuleSyntax: handle all kind of module syntax to convert them into a module which has the following form: { imports = [ <paths> ]; options = <attribute set of options declarations>; config = <attribute set (with properties) of option definitions>; } This function assume that there is at most one imported attribute set which correspond to option declarations. * moduleClosure: handle a list of module's paths which are converted with the previous function to do the closure of the imports with the function lazyGenericClosure (which does the same as builtins.genericClosure except that it doesn't evaluate the content of modules). The "key" and "paths" attributes are left to be used as debug information in futur implementation(s). svn path=/nixpkgs/trunk/; revision=17108
91 lines
2.2 KiB
Nix
91 lines
2.2 KiB
Nix
# NixOS module handling.
|
|
|
|
let lib = import ./default.nix; in
|
|
|
|
with { inherit (builtins) head tail; };
|
|
with import ./trivial.nix;
|
|
with import ./lists.nix;
|
|
with import ./misc.nix;
|
|
with import ./attrsets.nix;
|
|
with import ./properties.nix;
|
|
|
|
rec {
|
|
|
|
# Unfortunately this can also be a string.
|
|
isPath = x: !(
|
|
builtins.isFunction x
|
|
|| builtins.isAttrs x
|
|
|| builtins.isInt x
|
|
|| builtins.isBool x
|
|
|| builtins.isList x
|
|
);
|
|
|
|
importIfPath = path:
|
|
if isPath path then
|
|
import path
|
|
else
|
|
path;
|
|
|
|
applyIfFunction = f: arg:
|
|
if builtins.isFunction f then
|
|
f arg
|
|
else
|
|
f;
|
|
|
|
# Convert module to a set which has imports / options and config
|
|
# attributes.
|
|
unifyModuleSyntax = m:
|
|
let
|
|
getImports = m:
|
|
if m ? config || m ? options then
|
|
attrByPath ["imports"] [] m
|
|
else
|
|
toList (rmProperties (attrByPath ["require"] [] (delayProperties m)));
|
|
|
|
getImportedPaths = m: filter isPath (getImports m);
|
|
getImportedSets = m: filter (x: !isPath x) (getImports m);
|
|
|
|
getConfig = m:
|
|
removeAttrs (delayProperties m) ["require"];
|
|
in
|
|
if m ? config || m ? options then
|
|
m
|
|
else
|
|
{
|
|
imports = getImportedPaths m;
|
|
config = getConfig m;
|
|
} // (
|
|
if getImportedSets m != [] then
|
|
assert tail (getImportedSets m) == [];
|
|
{ options = head (getImportedSets m); }
|
|
else
|
|
{}
|
|
);
|
|
|
|
moduleClosure = initModules: args:
|
|
let
|
|
moduleImport = m: lib.addErrorContext "Import module ${m}." (
|
|
(unifyModuleSyntax (applyIfFunction (import m) args)) // {
|
|
# used by generic closure to avoid duplicated imports.
|
|
key = m;
|
|
paths = [ m ];
|
|
}
|
|
);
|
|
|
|
getImports = m: attrByPath ["imports"] [] m;
|
|
in
|
|
lazyGenericClosure {
|
|
startSet = map moduleImport initModules;
|
|
operator = m: map moduleImport (getImports m);
|
|
};
|
|
|
|
selectDeclsAndDefs = modules:
|
|
lib.concatMap (m:
|
|
if m ? config || m ? options then
|
|
[ (attrByPath ["options"] {} m) ]
|
|
++ [ (attrByPath ["config"] {} m) ]
|
|
else
|
|
[ m ]
|
|
) modules;
|
|
|
|
} |