Substitute fixOptionSetsFun by multiple functions which are:
- well named, - capable to handle the proposal of Eelco Dolstra { imports= [..]; options = {}; config = {}; } in addition to the current { require = [..]; .. } syntax. svn path=/nixpkgs/trunk/; revision=16192
This commit is contained in:
parent
a89f3bca50
commit
c49dddb1ab
|
@ -208,20 +208,24 @@ rec {
|
||||||
(filter (__hasAttr name) sets));
|
(filter (__hasAttr name) sets));
|
||||||
}) (concatMap builtins.attrNames sets));
|
}) (concatMap builtins.attrNames sets));
|
||||||
|
|
||||||
# flatten a list of elements by following the properties of the elements.
|
|
||||||
# next : return the list of following elements.
|
lazyGenericClosure = {startSet, operator}:
|
||||||
# seen : lists of elements already visited.
|
let
|
||||||
# default: result if 'x' is empty.
|
work = list: doneKeys: result:
|
||||||
# x : list of values that have to be processed.
|
if list == [] then
|
||||||
uniqFlatten = next: seen: default: x:
|
result
|
||||||
if x == []
|
else
|
||||||
then default
|
let x = head list; key = x.key; in
|
||||||
else
|
if elem key doneKeys then
|
||||||
let h = head x; t = tail x; n = next h; in
|
work (tail list) doneKeys result
|
||||||
if elem h seen
|
else
|
||||||
then uniqFlatten next seen default t
|
work (tail list ++ operator x) ([key] ++ doneKeys) ([x] ++ result);
|
||||||
else uniqFlatten next (seen ++ [h]) (default ++ [h]) (n ++ t)
|
in
|
||||||
;
|
work startSet [] [];
|
||||||
|
|
||||||
|
genericClosure =
|
||||||
|
if builtins ? genericClosure then builtins.genericClosure
|
||||||
|
else lazyGenericClosure;
|
||||||
|
|
||||||
innerModifySumArgs = f: x: a: b: if b == null then (f a b) // x else
|
innerModifySumArgs = f: x: a: b: if b == null then (f a b) // x else
|
||||||
innerModifySumArgs f x (a // b);
|
innerModifySumArgs f x (a // b);
|
||||||
|
|
|
@ -78,7 +78,7 @@ rec {
|
||||||
merge = list:
|
merge = list:
|
||||||
decl.type.iter
|
decl.type.iter
|
||||||
(path: opts:
|
(path: opts:
|
||||||
fixMergeFun (recurseInto path) (optionConfig opts)
|
lib.fix (fixableMergeFun (recurseInto path) (optionConfig opts))
|
||||||
)
|
)
|
||||||
opt.name
|
opt.name
|
||||||
(opt.merge list);
|
(opt.merge list);
|
||||||
|
@ -262,6 +262,12 @@ rec {
|
||||||
|| builtins.isList x
|
|| builtins.isList x
|
||||||
);
|
);
|
||||||
|
|
||||||
|
importIfPath = path:
|
||||||
|
if isPath path then
|
||||||
|
import path
|
||||||
|
else
|
||||||
|
path;
|
||||||
|
|
||||||
applyIfFunction = f: arg:
|
applyIfFunction = f: arg:
|
||||||
if builtins.isFunction f then
|
if builtins.isFunction f then
|
||||||
f arg
|
f arg
|
||||||
|
@ -270,106 +276,87 @@ rec {
|
||||||
|
|
||||||
moduleClosure = initModules: args:
|
moduleClosure = initModules: args:
|
||||||
let
|
let
|
||||||
moduleImport = path:
|
moduleImport = m:
|
||||||
(applyIfFunction (import path) args) // {
|
(applyIfFunction (importIfPath m) args) // {
|
||||||
# used by generic closure to avoid duplicated imports.
|
# used by generic closure to avoid duplicated imports.
|
||||||
key = path;
|
key = m;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
removeKeys = list: map (m: removeAttrs m ["key"]) list;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
inlineImportedSets = list:
|
||||||
|
lib.concatMap (m:[m] ++ map moduleImport (getImportedSets m)) list;
|
||||||
in
|
in
|
||||||
builtins.genericClosure {
|
inlineImportedSets (removeKeys (lazyGenericClosure {
|
||||||
startSet = map moduleImport initModules;
|
startSet = map moduleImport initModules;
|
||||||
operator = m:
|
operator = m: map moduleImport (getImportedPaths m);
|
||||||
map moduleImport (attrByPath ["imports"] [] m);
|
}));
|
||||||
};
|
|
||||||
|
|
||||||
selectDeclsAndDefs = modules:
|
selectDeclsAndDefs = modules:
|
||||||
lib.concatMap (m:
|
lib.concatMap (m:
|
||||||
attrByPath ["options"] [] m
|
if m ? config || m ? options then
|
||||||
++ attrByPath ["config"] [] m
|
attrByPath ["options"] [] m
|
||||||
|
++ attrByPath ["config"] [] m
|
||||||
|
else
|
||||||
|
[ m ]
|
||||||
) modules;
|
) modules;
|
||||||
|
|
||||||
fixMergeFun = merge: optFun:
|
|
||||||
lib.fix (config:
|
fixableMergeFun = merge: f: config:
|
||||||
merge (
|
merge (
|
||||||
|
# remove require because this is not an option.
|
||||||
|
map (m: removeAttrs m ["require"]) (
|
||||||
# Delay top-level properties like mkIf
|
# Delay top-level properties like mkIf
|
||||||
map delayProperties (
|
map delayProperties (
|
||||||
# generate the list of option sets.
|
# generate the list of option sets.
|
||||||
optFun config
|
f config
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
fixMergeModules = merge: initModules: {...}@args:
|
fixableMergeModules = merge: initModules: {...}@args: config:
|
||||||
fixMergeFun (config:
|
fixableMergeFun merge (config:
|
||||||
|
# filter the list of option sets.
|
||||||
selectDeclsAndDefs (
|
selectDeclsAndDefs (
|
||||||
|
# generate the list of modules from a closure of imports/require
|
||||||
|
# attribtues.
|
||||||
moduleClosure initModules (args // { inherit config; })
|
moduleClosure initModules (args // { inherit config; })
|
||||||
)
|
)
|
||||||
);
|
) config;
|
||||||
|
|
||||||
fixModulesConfig = initModules: {...}@args:
|
|
||||||
fixMergeModules (mergeOptionSets "") initModules args;
|
|
||||||
|
|
||||||
fixOptionsConfig = initModules: {...}@args:
|
|
||||||
fixMergeModules (filterOptionSets "") initModules args;
|
|
||||||
|
|
||||||
|
|
||||||
# Evaluate a list of option sets that would be merged with the
|
fixableDefinitionsOf = initModules: {...}@args:
|
||||||
# function "merge" which expects two arguments. The attribute named
|
fixableMergeModules (mergeOptionSets "") initModules args;
|
||||||
# "require" is used to imports option declarations and bindings.
|
|
||||||
#
|
|
||||||
# * cfg[0-9]: configuration
|
|
||||||
# * cfgSet[0-9]: configuration set
|
|
||||||
#
|
|
||||||
# merge: the function used to merge options sets.
|
|
||||||
# args: is the set of packages available. (nixpkgs)
|
|
||||||
# opts: list of option sets or option set functions.
|
|
||||||
# config: result of this evaluation.
|
|
||||||
fixOptionSetsFun = merge: args: opts: config:
|
|
||||||
let
|
|
||||||
# remove possible mkIf to access the require attribute.
|
|
||||||
noImportConditions = cfgSet0:
|
|
||||||
let cfgSet1 = delayProperties cfgSet0; in
|
|
||||||
if cfgSet1 ? require then
|
|
||||||
cfgSet1 // { require = rmProperties cfgSet1.require; }
|
|
||||||
else
|
|
||||||
cfgSet1;
|
|
||||||
|
|
||||||
filenameHandler = cfg:
|
fixableDeclarationsOf = initModules: {...}@args:
|
||||||
if isPath cfg then import cfg else cfg;
|
fixableMergeModules (filterOptionSets "") initModules args;
|
||||||
|
|
||||||
argumentHandler = cfg:
|
definitionsOf = initModules: {...}@args:
|
||||||
applyIfFunction cfg (args // { inherit config; });
|
lib.fix (fixableDefinitionsOf initModules args);
|
||||||
|
|
||||||
preprocess = cfg0:
|
declarationsOf = initModules: {...}@args:
|
||||||
let cfg1 = filenameHandler cfg0;
|
lib.fix (fixableDeclarationsOf initModules args);
|
||||||
cfg2 = argumentHandler cfg1;
|
|
||||||
cfg3 = noImportConditions cfg2;
|
|
||||||
in cfg3;
|
|
||||||
|
|
||||||
getRequire = x: toList (attrByPath ["require"] [] (preprocess x));
|
|
||||||
getRecursiveRequire = x:
|
|
||||||
fold (cfg: l:
|
|
||||||
if isPath cfg then
|
|
||||||
[ cfg ] ++ l
|
|
||||||
else
|
|
||||||
[ cfg ] ++ (getRecursiveRequire cfg) ++ l
|
|
||||||
) [] (getRequire x);
|
|
||||||
|
|
||||||
getRequireSets = x: filter (x: ! isPath x) (getRecursiveRequire x);
|
fixMergeModules = merge: initModules: {...}@args:
|
||||||
getRequirePaths = x: filter isPath (getRecursiveRequire x);
|
lib.fix (fixableMergeModules merge initModules args);
|
||||||
rmRequire = x: removeAttrs (preprocess x) ["require"];
|
|
||||||
|
|
||||||
inlineRequiredSets = cfgs:
|
|
||||||
fold (cfg: l: [ cfg ] ++ (getRequireSets cfg) ++ l) [] cfgs;
|
|
||||||
in
|
|
||||||
merge "" (
|
|
||||||
map rmRequire (
|
|
||||||
inlineRequiredSets ((toList opts) ++ lib.uniqFlatten getRequirePaths [] [] (lib.concatMap getRequirePaths (toList opts)))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
fixOptionSets = merge: args: opts:
|
# old interface.
|
||||||
lib.fix (fixOptionSetsFun merge args opts);
|
fixOptionSetsFun = merge: {...}@args: initModules: config:
|
||||||
|
fixableMergeModules (merge "") initModules args config;
|
||||||
|
|
||||||
|
fixOptionSets = merge: args: initModules:
|
||||||
|
fixMergeModules (merge "") initModules args;
|
||||||
|
|
||||||
|
|
||||||
# Generate documentation template from the list of option declaration like
|
# Generate documentation template from the list of option declaration like
|
||||||
|
|
Loading…
Reference in a new issue