mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-09-29 15:43:00 +00:00
* Refactoring: move the types out of options.nix, which is much too
big. Also, they could be useful beyond option handling. svn path=/nixpkgs/trunk/; revision=16055
This commit is contained in:
parent
dd50af4923
commit
a440fba8e3
@ -7,13 +7,14 @@ let
|
|||||||
attrsets = import ./attrsets.nix;
|
attrsets = import ./attrsets.nix;
|
||||||
sources = import ./sources.nix;
|
sources = import ./sources.nix;
|
||||||
options = import ./options.nix;
|
options = import ./options.nix;
|
||||||
|
types = import ./types.nix;
|
||||||
meta = import ./meta.nix;
|
meta = import ./meta.nix;
|
||||||
debug = import ./debug.nix;
|
debug = import ./debug.nix;
|
||||||
misc = import ./misc.nix;
|
misc = import ./misc.nix;
|
||||||
|
|
||||||
in
|
in
|
||||||
{ inherit trivial lists strings stringsWithDeps attrsets sources options meta debug; }
|
{ inherit trivial lists strings stringsWithDeps attrsets sources options types meta debug; }
|
||||||
# !!! don't include everything at top-level; perhaps only the most
|
# !!! don't include everything at top-level; perhaps only the most
|
||||||
# commonly used functions.
|
# commonly used functions.
|
||||||
// trivial // lists // strings // stringsWithDeps // attrsets // sources
|
// trivial // lists // strings // stringsWithDeps // attrsets // sources
|
||||||
// options // meta // debug // misc
|
// options // types // meta // debug // misc
|
||||||
|
@ -10,9 +10,8 @@ with import ./attrsets.nix;
|
|||||||
|
|
||||||
rec {
|
rec {
|
||||||
|
|
||||||
|
inherit (lib) typeOf;
|
||||||
hasType = x: isAttrs x && x ? _type;
|
|
||||||
typeOf = x: if hasType x then x._type else "";
|
|
||||||
|
|
||||||
isOption = attrs: (typeOf attrs) == "option";
|
isOption = attrs: (typeOf attrs) == "option";
|
||||||
mkOption = attrs: attrs // {
|
mkOption = attrs: attrs // {
|
||||||
@ -131,112 +130,7 @@ rec {
|
|||||||
opt1 // opt2
|
opt1 // opt2
|
||||||
)) {} opts;
|
)) {} opts;
|
||||||
|
|
||||||
|
|
||||||
# name (name of the type)
|
|
||||||
# check (boolean function)
|
|
||||||
# merge (default merge function)
|
|
||||||
# iter (iterate on all elements contained in this type)
|
|
||||||
# fold (fold all elements contained in this type)
|
|
||||||
# hasOptions (boolean: whatever this option contains an option set)
|
|
||||||
# path (path contatenated to the option name contained contained in the option set)
|
|
||||||
isOptionType = attrs: (typeOf attrs) == "option-type";
|
|
||||||
mkOptionType = attrs@{
|
|
||||||
name
|
|
||||||
, check ? (x: true)
|
|
||||||
, merge ? mergeDefaultOption
|
|
||||||
# Handle complex structure types.
|
|
||||||
, iter ? (f: path: v: f path v)
|
|
||||||
, fold ? (op: nul: v: op v nul)
|
|
||||||
, docPath ? lib.id
|
|
||||||
# If the type can contains option sets.
|
|
||||||
, hasOptions ? false
|
|
||||||
}: { _type = "option-type";
|
|
||||||
inherit name check merge iter fold docPath hasOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
types = {
|
|
||||||
|
|
||||||
inferred = mkOptionType {
|
|
||||||
name = "inferred type";
|
|
||||||
};
|
|
||||||
|
|
||||||
bool = mkOptionType {
|
|
||||||
name = "boolean";
|
|
||||||
check = lib.traceValIfNot builtins.isBool;
|
|
||||||
merge = fold lib.or false;
|
|
||||||
};
|
|
||||||
|
|
||||||
int = mkOptionType {
|
|
||||||
name = "integer";
|
|
||||||
check = lib.traceValIfNot builtins.isInt;
|
|
||||||
};
|
|
||||||
|
|
||||||
string = mkOptionType {
|
|
||||||
name = "string";
|
|
||||||
check = lib.traceValIfNot (x: builtins ? isString -> builtins.isString x);
|
|
||||||
merge = lib.concatStrings;
|
|
||||||
};
|
|
||||||
|
|
||||||
attrs = mkOptionType {
|
|
||||||
name = "attribute set";
|
|
||||||
check = lib.traceValIfNot builtins.isAttrs;
|
|
||||||
merge = fold lib.mergeAttrs {};
|
|
||||||
};
|
|
||||||
|
|
||||||
# derivation is a reserved keyword.
|
|
||||||
package = mkOptionType {
|
|
||||||
name = "derivation";
|
|
||||||
check = lib.traceValIfNot isDerivation;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
list = elemType: mkOptionType {
|
|
||||||
name = "list of ${elemType.name}s";
|
|
||||||
check = value: lib.traceValIfNot isList value && all elemType.check value;
|
|
||||||
merge = concatLists;
|
|
||||||
iter = f: path: list: map (elemType.iter f (path + ".*")) list;
|
|
||||||
fold = op: nul: list: lib.fold (e: l: elemType.fold op l e) nul list;
|
|
||||||
docPath = path: elemType.docPath (path + ".*");
|
|
||||||
inherit (elemType) hasOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
attrsOf = elemType: mkOptionType {
|
|
||||||
name = "attribute set of ${elemType}s";
|
|
||||||
check = x: lib.traceValIfNot builtins.isAttrs x
|
|
||||||
&& fold (e: v: v && elemType.check e) true (lib.attrValues x);
|
|
||||||
merge = fold lib.mergeAttrs {};
|
|
||||||
iter = f: path: set: lib.mapAttrs (name: elemType.iter f (path + "." + name)) set;
|
|
||||||
fold = op: nul: set: fold (e: l: elemType.fold op l e) nul (lib.attrValues set);
|
|
||||||
docPath = path: elemType.docPath (path + ".<name>");
|
|
||||||
inherit (elemType) hasOptions;
|
|
||||||
};
|
|
||||||
|
|
||||||
uniq = elemType: mkOptionType {
|
|
||||||
inherit (elemType) name check iter fold docPath hasOptions;
|
|
||||||
merge = list:
|
|
||||||
if tail list == [] then
|
|
||||||
head list
|
|
||||||
else
|
|
||||||
throw "Multiple definitions. Only one is allowed for this option.";
|
|
||||||
};
|
|
||||||
|
|
||||||
nullOr = elemType: mkOptionType {
|
|
||||||
inherit (elemType) name merge docPath hasOptions;
|
|
||||||
check = x: builtins.isNull x || elemType.check x;
|
|
||||||
iter = f: path: v: if v == null then v else elemType.iter f path v;
|
|
||||||
fold = op: nul: v: if v == null then nul else elemType.fold op nul v;
|
|
||||||
};
|
|
||||||
|
|
||||||
optionSet = mkOptionType {
|
|
||||||
name = "option set";
|
|
||||||
check = x: lib.traceValIfNot builtins.isAttrs x;
|
|
||||||
hasOptions = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
# !!! This function will be removed because this can be done with the
|
# !!! This function will be removed because this can be done with the
|
||||||
# multiple option declarations.
|
# multiple option declarations.
|
||||||
addDefaultOptionValues = defs: opts: opts //
|
addDefaultOptionValues = defs: opts: opts //
|
||||||
|
121
pkgs/lib/types.nix
Normal file
121
pkgs/lib/types.nix
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
# Definitions related to run-time type checking. Used in particular
|
||||||
|
# to type-check NixOS configurations.
|
||||||
|
|
||||||
|
let lib = import ./default.nix; in
|
||||||
|
|
||||||
|
with import ./lists.nix;
|
||||||
|
with import ./attrsets.nix;
|
||||||
|
with import ./options.nix;
|
||||||
|
|
||||||
|
rec {
|
||||||
|
|
||||||
|
hasType = x: isAttrs x && x ? _type;
|
||||||
|
typeOf = x: if hasType x then x._type else "";
|
||||||
|
|
||||||
|
|
||||||
|
# name (name of the type)
|
||||||
|
# check (boolean function)
|
||||||
|
# merge (default merge function)
|
||||||
|
# iter (iterate on all elements contained in this type)
|
||||||
|
# fold (fold all elements contained in this type)
|
||||||
|
# hasOptions (boolean: whatever this option contains an option set)
|
||||||
|
# path (path contatenated to the option name contained contained in the option set)
|
||||||
|
isOptionType = attrs: typeOf attrs == "option-type";
|
||||||
|
mkOptionType =
|
||||||
|
{ name
|
||||||
|
, check ? (x: true)
|
||||||
|
, merge ? mergeDefaultOption
|
||||||
|
# Handle complex structure types.
|
||||||
|
, iter ? (f: path: v: f path v)
|
||||||
|
, fold ? (op: nul: v: op v nul)
|
||||||
|
, docPath ? lib.id
|
||||||
|
# If the type can contains option sets.
|
||||||
|
, hasOptions ? false
|
||||||
|
}:
|
||||||
|
|
||||||
|
{ _type = "option-type";
|
||||||
|
inherit name check merge iter fold docPath hasOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
types = {
|
||||||
|
|
||||||
|
inferred = mkOptionType {
|
||||||
|
name = "inferred type";
|
||||||
|
};
|
||||||
|
|
||||||
|
bool = mkOptionType {
|
||||||
|
name = "boolean";
|
||||||
|
check = lib.traceValIfNot builtins.isBool;
|
||||||
|
merge = fold lib.or false;
|
||||||
|
};
|
||||||
|
|
||||||
|
int = mkOptionType {
|
||||||
|
name = "integer";
|
||||||
|
check = lib.traceValIfNot builtins.isInt;
|
||||||
|
};
|
||||||
|
|
||||||
|
string = mkOptionType {
|
||||||
|
name = "string";
|
||||||
|
check = lib.traceValIfNot (x: builtins ? isString -> builtins.isString x);
|
||||||
|
merge = lib.concatStrings;
|
||||||
|
};
|
||||||
|
|
||||||
|
attrs = mkOptionType {
|
||||||
|
name = "attribute set";
|
||||||
|
check = lib.traceValIfNot builtins.isAttrs;
|
||||||
|
merge = fold lib.mergeAttrs {};
|
||||||
|
};
|
||||||
|
|
||||||
|
# derivation is a reserved keyword.
|
||||||
|
package = mkOptionType {
|
||||||
|
name = "derivation";
|
||||||
|
check = lib.traceValIfNot isDerivation;
|
||||||
|
};
|
||||||
|
|
||||||
|
list = elemType: mkOptionType {
|
||||||
|
name = "list of ${elemType.name}s";
|
||||||
|
check = value: lib.traceValIfNot isList value && all elemType.check value;
|
||||||
|
merge = concatLists;
|
||||||
|
iter = f: path: list: map (elemType.iter f (path + ".*")) list;
|
||||||
|
fold = op: nul: list: lib.fold (e: l: elemType.fold op l e) nul list;
|
||||||
|
docPath = path: elemType.docPath (path + ".*");
|
||||||
|
inherit (elemType) hasOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
attrsOf = elemType: mkOptionType {
|
||||||
|
name = "attribute set of ${elemType}s";
|
||||||
|
check = x: lib.traceValIfNot builtins.isAttrs x
|
||||||
|
&& fold (e: v: v && elemType.check e) true (lib.attrValues x);
|
||||||
|
merge = fold lib.mergeAttrs {};
|
||||||
|
iter = f: path: set: lib.mapAttrs (name: elemType.iter f (path + "." + name)) set;
|
||||||
|
fold = op: nul: set: fold (e: l: elemType.fold op l e) nul (lib.attrValues set);
|
||||||
|
docPath = path: elemType.docPath (path + ".<name>");
|
||||||
|
inherit (elemType) hasOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniq = elemType: mkOptionType {
|
||||||
|
inherit (elemType) name check iter fold docPath hasOptions;
|
||||||
|
merge = list:
|
||||||
|
if tail list == [] then
|
||||||
|
head list
|
||||||
|
else
|
||||||
|
throw "Multiple definitions. Only one is allowed for this option.";
|
||||||
|
};
|
||||||
|
|
||||||
|
nullOr = elemType: mkOptionType {
|
||||||
|
inherit (elemType) name merge docPath hasOptions;
|
||||||
|
check = x: builtins.isNull x || elemType.check x;
|
||||||
|
iter = f: path: v: if v == null then v else elemType.iter f path v;
|
||||||
|
fold = op: nul: v: if v == null then nul else elemType.fold op nul v;
|
||||||
|
};
|
||||||
|
|
||||||
|
optionSet = mkOptionType {
|
||||||
|
name = "option set";
|
||||||
|
check = x: lib.traceValIfNot builtins.isAttrs x;
|
||||||
|
hasOptions = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user