From 947a7d33f997d8782ae74e2e76fb7645e86b663e Mon Sep 17 00:00:00 2001 From: zimbatm Date: Sun, 16 Aug 2020 15:39:52 +0200 Subject: lib: add importTOML Complements the `lib.importJSON`. `builtins.readTOML` has been introduced in Nix 2.1. --- lib/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index 43b9ab5930c..44076d29517 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -66,7 +66,7 @@ let stringLength sub substring tail; inherit (trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell min max - importJSON warn info showWarnings nixpkgsVersion version mod compare + importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; inherit (fixedPoints) fix fix' converge extends composeExtensions makeExtensible makeExtensibleWithCustomName; -- cgit 1.4.1 From afa6c51f27fb86fda71f91a51b093a5fc3de797d Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 20 Oct 2020 13:47:24 +0200 Subject: lib: Use Nix's static scope checking, fix error message, optimize Nix can perform static scope checking, but whenever code is inside a `with` expression, the analysis breaks down, because it can't know statically what's in the attribute set whose attributes were brought into scope. In those cases, Nix has to assume that everything works out. Except it doesnt. Removing `with` from lib/ revealed an undefined variable in an error message. If that doesn't convince you that we're better off without `with`, I can tell you that this PR results in a 3% evaluation performance improvement because Nix can look up local variables by index. This adds up with applications like the module system. Furthermore, removing `with` makes the binding site of each variable obvious, which helps with comprehension. --- lib/debug.nix | 32 ++++++++++++++++++------ lib/default.nix | 36 +++++++++++++------------- lib/lists.nix | 2 +- lib/modules.nix | 59 +++++++++++++++++++++++++++++++++++++------ lib/options.nix | 14 +++++++---- lib/sources.nix | 40 ++++++++++++++++++++--------- lib/strings-with-deps.nix | 13 +++++++--- lib/strings.nix | 64 +++++++++++++++++++++++++++++++---------------- lib/types.nix | 60 ++++++++++++++++++++++++++++++++++++++++---- 9 files changed, 238 insertions(+), 82 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/debug.nix b/lib/debug.nix index 2879f72ed2b..ea6aed60ab4 100644 --- a/lib/debug.nix +++ b/lib/debug.nix @@ -14,9 +14,25 @@ */ { lib }: let - inherit (builtins) trace isAttrs isList isInt - head substring attrNames; - inherit (lib) id elem isFunction; + inherit (lib) + isInt + attrNames + isList + isAttrs + substring + addErrorContext + attrValues + concatLists + concatStringsSep + const + elem + generators + head + id + isDerivation + isFunction + mapAttrs + trace; in rec { @@ -94,7 +110,7 @@ rec { trace: { a = { b = {…}; }; } => null */ - traceSeqN = depth: x: y: with lib; + traceSeqN = depth: x: y: let snip = v: if isList v then noQuotes "[…]" v else if isAttrs v then noQuotes "{…}" v else v; @@ -149,7 +165,7 @@ rec { */ runTests = # Tests to run - tests: lib.concatLists (lib.attrValues (lib.mapAttrs (name: test: + tests: concatLists (attrValues (mapAttrs (name: test: let testsToRun = if tests ? tests then tests.tests else []; in if (substring 0 4 name == "test" || elem name testsToRun) && ((testsToRun == []) || elem name tests.tests) @@ -176,9 +192,9 @@ rec { + "and will be removed in the next release. " + "Please use more specific concatenation " + "for your uses (`lib.concat(Map)StringsSep`)." ) - (lib.concatStringsSep "; " (map (x: "${x}=") (attrNames a))); + (concatStringsSep "; " (map (x: "${x}=") (attrNames a))); - showVal = with lib; + showVal = trace ( "Warning: `showVal` is deprecated " + "and will be removed in the next release, " + "please use `traceSeqN`" ) @@ -226,7 +242,7 @@ rec { trace ( "Warning: `addErrorContextToAttrs` is deprecated " + "and will be removed in the next release. " + "Please use `builtins.addErrorContext` directly." ) - (lib.mapAttrs (a: v: lib.addErrorContext "while evaluating ${a}" v) attrs); + (mapAttrs (a: v: addErrorContext "while evaluating ${a}" v) attrs); # example: (traceCallXml "myfun" id 3) will output something like # calling myfun arg 1: 3 result: 3 diff --git a/lib/default.nix b/lib/default.nix index 44076d29517..78566cceae8 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -9,7 +9,7 @@ let lib = makeExtensible (self: let callLibs = file: import file { lib = self; }; - in with self; { + in { # often used, or depending on very little trivial = callLibs ./trivial.nix; @@ -54,7 +54,7 @@ let filesystem = callLibs ./filesystem.nix; # back-compat aliases - platforms = systems.doubles; + platforms = self.systems.doubles; # linux kernel configuration kernel = callLibs ./kernel.nix; @@ -64,13 +64,13 @@ let hasAttr head isAttrs isBool isInt isList isString length lessThan listToAttrs pathExists readFile replaceStrings seq stringLength sub substring tail; - inherit (trivial) id const pipe concat or and bitAnd bitOr bitXor + inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell min max importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; - inherit (fixedPoints) fix fix' converge extends composeExtensions + inherit (self.fixedPoints) fix fix' converge extends composeExtensions makeExtensible makeExtensibleWithCustomName; - inherit (attrsets) attrByPath hasAttrByPath setAttrByPath + inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs mapAttrs' mapAttrsToList mapAttrsRecursive mapAttrsRecursiveCond @@ -79,13 +79,13 @@ let recursiveUpdate matchAttrs overrideExisting getOutput getBin getLib getDev getMan chooseDevOutputs zipWithNames zip recurseIntoAttrs dontRecurseIntoAttrs; - inherit (lists) singleton forEach foldr fold foldl foldl' imap0 imap1 + inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 concatMap flatten remove findSingle findFirst any all count optional optionals toList range partition zipListsWith zipLists reverseList listDfs toposort sort naturalSort compareLists take drop sublist last init crossLists unique intersectLists subtractLists mutuallyExclusive groupBy groupBy'; - inherit (strings) concatStrings concatMapStrings concatImapStrings + inherit (self.strings) concatStrings concatMapStrings concatImapStrings intersperse concatStringsSep concatMapStringsSep concatImapStringsSep makeSearchPath makeSearchPathOutput makeLibraryPath makeBinPath optionalString @@ -97,19 +97,19 @@ let nameFromURL enableFeature enableFeatureAs withFeature withFeatureAs fixedWidthString fixedWidthNumber isStorePath toInt readPathsFromFile fileContents; - inherit (stringsWithDeps) textClosureList textClosureMap + inherit (self.stringsWithDeps) textClosureList textClosureMap noDepEntry fullDepEntry packEntry stringAfter; - inherit (customisation) overrideDerivation makeOverridable + inherit (self.customisation) overrideDerivation makeOverridable callPackageWith callPackagesWith extendDerivation hydraJob makeScope; - inherit (meta) addMetaAttrs dontDistribute setName updateName + inherit (self.meta) addMetaAttrs dontDistribute setName updateName appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio hiPrioSet; - inherit (sources) pathType pathIsDirectory cleanSourceFilter + inherit (self.sources) pathType pathIsDirectory cleanSourceFilter cleanSource sourceByRegex sourceFilesBySuffices commitIdFromGitRepo cleanSourceWith pathHasContext canCleanSource pathIsRegularFile pathIsGitRepo; - inherit (modules) evalModules unifyModuleSyntax + inherit (self.modules) evalModules unifyModuleSyntax applyIfFunction mergeModules mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions pushDownProperties dischargeProperties filterOverrides @@ -119,21 +119,21 @@ let mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule mkAliasOptionModule doRename; - inherit (options) isOption mkEnableOption mkSinkUndeclaredOptions + inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions mergeDefaultOption mergeOneOption mergeEqualOption getValues getFiles optionAttrSetToDocList optionAttrSetToDocList' scrubOptionValue literalExample showOption showFiles unknownModule mkOption; - inherit (types) isType setType defaultTypeMerge defaultFunctor + inherit (self.types) isType setType defaultTypeMerge defaultFunctor isOptionType mkOptionType; - inherit (asserts) + inherit (self.asserts) assertMsg assertOneOf; - inherit (debug) addErrorContextToAttrs traceIf traceVal traceValFn + inherit (self.debug) addErrorContextToAttrs traceIf traceVal traceValFn traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal traceShowValMarked showVal traceCall traceCall2 traceCall3 traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr; - inherit (misc) maybeEnv defaultMergeArg defaultMerge foldArgs + inherit (self.misc) maybeEnv defaultMergeArg defaultMerge foldArgs maybeAttrNullable maybeAttr ifEnable checkFlag getValue checkReqs uniqList uniqListExt condConcat lazyGenericClosure innerModifySumArgs modifySumArgs innerClosePropagation @@ -143,7 +143,7 @@ let mergeAttrsByFuncDefaultsClean mergeAttrBy fakeHash fakeSha256 fakeSha512 nixType imap; - inherit (versions) + inherit (self.versions) splitVersion; }); in lib diff --git a/lib/lists.nix b/lib/lists.nix index f424946c72c..6c97e0686aa 100644 --- a/lib/lists.nix +++ b/lib/lists.nix @@ -1,9 +1,9 @@ # General list operations. { lib }: -with lib.trivial; let inherit (lib.strings) toInt; + inherit (lib.trivial) compare min; in rec { diff --git a/lib/modules.nix b/lib/modules.nix index df3a2ad17e5..37e2e23ec12 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -1,12 +1,55 @@ { lib }: -with lib.lists; -with lib.strings; -with lib.trivial; -with lib.attrsets; -with lib.options; -with lib.debug; -with lib.types; +let + inherit (lib.attrsets) + mapAttrsRecursiveCond + ; + inherit (lib.lists) + any all concatLists concatMap + count filter findFirst foldl foldl' + head imap1 length optional + reverseList sort + ; + inherit (lib.options) + isOption + mkOption + showDefs + showFiles + showOption + unknownModule + ; + inherit (lib.attrsets) + attrByPath + attrNames + catAttrs + getAttrFromPath + mapAttrs + mapAttrsToList + optionalAttrs + recursiveUpdate + setAttrByPath + toList + ; + inherit (lib.types) + types + ; + inherit (lib.trivial) + flip + id + isBool + isFunction + isString + min + warn + ; + inherit (lib.strings) + optionalString + ; + inherit (lib) + elem + isAttrs + ; +in rec { @@ -616,7 +659,7 @@ rec { fixupOptionType = loc: opt: let options = opt.options or - (throw "Option `${showOption loc'}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}."); + (throw "Option `${showOption loc}' has type optionSet but has no option attribute, in ${showFiles opt.declarations}."); f = tp: let optionSetIn = type: (tp.name == type) && (tp.functor.wrapped.name == "optionSet"); in diff --git a/lib/options.nix b/lib/options.nix index 9e0ea010bda..97bb2e77176 100644 --- a/lib/options.nix +++ b/lib/options.nix @@ -1,11 +1,15 @@ # Nixpkgs/NixOS option handling. { lib }: -with lib.trivial; -with lib.lists; -with lib.attrsets; -with lib.strings; - +let + inherit (lib) + isAttrs isBool isDerivation isFunction isInt isList isString + all collect concatMap concatLists elemAt filter foldl' head length mapAttrs optionals optional take + ; + inherit (lib.attrsets) optionalAttrs; + inherit (lib.strings) concatMapStrings concatStringsSep; + inherit (lib.types) mkOptionType; +in rec { /* Returns true when the given argument is an option diff --git a/lib/sources.nix b/lib/sources.nix index 776fcc32052..c7a3a959152 100644 --- a/lib/sources.nix +++ b/lib/sources.nix @@ -1,16 +1,33 @@ # Functions for copying sources to the Nix store. { lib }: +let + inherit (builtins) + hasContext + match + readDir + readFile + storeDir + tryEval + ; + inherit (lib) + filter + getAttr + isString + pathExists + split + ; +in rec { # Returns the type of a path: regular (for file), symlink, or directory - pathType = p: with builtins; getAttr (baseNameOf p) (readDir (dirOf p)); + pathType = p: getAttr (baseNameOf p) (readDir (dirOf p)); # Returns true if the path exists and is a directory, false otherwise - pathIsDirectory = p: if builtins.pathExists p then (pathType p) == "directory" else false; + pathIsDirectory = p: if pathExists p then (pathType p) == "directory" else false; # Returns true if the path exists and is a regular file, false otherwise - pathIsRegularFile = p: if builtins.pathExists p then (pathType p) == "regular" else false; + pathIsRegularFile = p: if pathExists p then (pathType p) == "regular" else false; # Bring in a path as a source, filtering out all Subversion and CVS # directories, as well as backup files (*~). @@ -19,8 +36,8 @@ rec { (baseName == ".git" || type == "directory" && (baseName == ".svn" || baseName == "CVS" || baseName == ".hg")) || # Filter out editor backup / swap files. lib.hasSuffix "~" baseName || - builtins.match "^\\.sw[a-z]$" baseName != null || - builtins.match "^\\..*\\.sw[a-z]$" baseName != null || + match "^\\.sw[a-z]$" baseName != null || + match "^\\..*\\.sw[a-z]$" baseName != null || # Filter out generates files. lib.hasSuffix ".o" baseName || @@ -89,7 +106,7 @@ rec { in lib.cleanSourceWith { filter = (path: type: let relPath = lib.removePrefix (toString origSrc + "/") (toString path); - in lib.any (re: builtins.match re relPath != null) regexes); + in lib.any (re: match re relPath != null) regexes); inherit src; }; @@ -102,13 +119,12 @@ rec { in type == "directory" || lib.any (ext: lib.hasSuffix ext base) exts; in cleanSourceWith { inherit filter; src = path; }; - pathIsGitRepo = path: (builtins.tryEval (commitIdFromGitRepo path)).success; + pathIsGitRepo = path: (tryEval (commitIdFromGitRepo path)).success; # Get the commit id of a git repo # Example: commitIdFromGitRepo commitIdFromGitRepo = let readCommitFromFile = file: path: - with builtins; let fileName = toString path + "/" + file; packedRefsName = toString path + "/packed-refs"; absolutePath = base: path: @@ -145,11 +161,11 @@ rec { # packed-refs file, so we have to grep through it: then let fileContent = readFile packedRefsName; - matchRef = builtins.match "([a-z0-9]+) ${file}"; - isRef = s: builtins.isString s && (matchRef s) != null; + matchRef = match "([a-z0-9]+) ${file}"; + isRef = s: isString s && (matchRef s) != null; # there is a bug in libstdc++ leading to stackoverflow for long strings: # https://github.com/NixOS/nix/issues/2147#issuecomment-659868795 - refs = builtins.filter isRef (builtins.split "\n" fileContent); + refs = filter isRef (split "\n" fileContent); in if refs == [] then throw ("Could not find " + file + " in " + packedRefsName) else lib.head (matchRef (lib.head refs)) @@ -157,7 +173,7 @@ rec { else throw ("Not a .git directory: " + path); in readCommitFromFile "HEAD"; - pathHasContext = builtins.hasContext or (lib.hasPrefix builtins.storeDir); + pathHasContext = builtins.hasContext or (lib.hasPrefix storeDir); canCleanSource = src: src ? _isLibCleanSourceWith || !(pathHasContext (toString src)); } diff --git a/lib/strings-with-deps.nix b/lib/strings-with-deps.nix index e3336983428..7b88b018da5 100644 --- a/lib/strings-with-deps.nix +++ b/lib/strings-with-deps.nix @@ -41,10 +41,15 @@ Usage: [1] maybe this behaviour should be removed to keep things simple (?) */ -with lib.lists; -with lib.attrsets; -with lib.strings; - +let + inherit (lib) + concatStringsSep + head + isAttrs + listToAttrs + tail + ; +in rec { /* !!! The interface of this function is kind of messed up, since diff --git a/lib/strings.nix b/lib/strings.nix index d81e46a1763..f62ff6679ef 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -8,7 +8,29 @@ in rec { - inherit (builtins) stringLength substring head tail isString replaceStrings; + inherit (builtins) + compareVersions + elem + elemAt + filter + fromJSON + head + isInt + isList + isString + match + parseDrvName + readFile + replaceStrings + split + storeDir + stringLength + substring + tail + toJSON + typeOf + unsafeDiscardStringContext + ; /* Concatenate a list of strings. @@ -120,7 +142,7 @@ rec { subDir: # List of base paths paths: - concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) paths)); + concatStringsSep ":" (map (path: path + "/" + subDir) (filter (x: x != null) paths)); /* Construct a Unix-style search path by appending the given `subDir` to the specified `output` of each of the packages. If no @@ -313,7 +335,7 @@ rec { escapeNixString "hello\${}\n" => "\"hello\\\${}\\n\"" */ - escapeNixString = s: escape ["$"] (builtins.toJSON s); + escapeNixString = s: escape ["$"] (toJSON s); /* Turn a string into an exact regular expression @@ -337,7 +359,7 @@ rec { */ escapeNixIdentifier = s: # Regex from https://github.com/NixOS/nix/blob/d048577909e383439c2549e849c5c2f2016c997e/src/libexpr/lexer.l#L91 - if builtins.match "[a-zA-Z_][a-zA-Z0-9_'-]*" s != null + if match "[a-zA-Z_][a-zA-Z0-9_'-]*" s != null then s else escapeNixString s; # Obsolete - use replaceStrings instead. @@ -466,7 +488,7 @@ rec { versionOlder "1.1" "1.1" => false */ - versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1; + versionOlder = v1: v2: compareVersions v2 v1 == 1; /* Return true if string v1 denotes a version equal to or newer than v2. @@ -492,7 +514,7 @@ rec { */ getName = x: let - parse = drv: (builtins.parseDrvName drv).name; + parse = drv: (parseDrvName drv).name; in if isString x then parse x else x.pname or (parse x.name); @@ -509,7 +531,7 @@ rec { */ getVersion = x: let - parse = drv: (builtins.parseDrvName drv).version; + parse = drv: (parseDrvName drv).version; in if isString x then parse x else x.version or (parse x.name); @@ -527,7 +549,7 @@ rec { let components = splitString "/" url; filename = lib.last components; - name = builtins.head (splitString sep filename); + name = head (splitString sep filename); in assert name != filename; name; /* Create an --{enable,disable}- string that can be passed to @@ -617,14 +639,14 @@ rec { */ floatToString = float: let result = toString float; - precise = float == builtins.fromJSON result; + precise = float == fromJSON result; in if precise then result else lib.warn "Imprecise conversion from float to string ${result}" result; /* Check whether a value can be coerced to a string */ isCoercibleToString = x: - builtins.elem (builtins.typeOf x) [ "path" "string" "null" "int" "float" "bool" ] || - (builtins.isList x && lib.all isCoercibleToString x) || + elem (typeOf x) [ "path" "string" "null" "int" "float" "bool" ] || + (isList x && lib.all isCoercibleToString x) || x ? outPath || x ? __toString; @@ -643,8 +665,8 @@ rec { isStorePath = x: if isCoercibleToString x then let str = toString x; in - builtins.substring 0 1 str == "/" - && dirOf str == builtins.storeDir + substring 0 1 str == "/" + && dirOf str == storeDir else false; @@ -662,8 +684,8 @@ rec { */ # Obviously, it is a bit hacky to use fromJSON this way. toInt = str: - let may_be_int = builtins.fromJSON str; in - if builtins.isInt may_be_int + let may_be_int = fromJSON str; in + if isInt may_be_int then may_be_int else throw "Could not convert ${str} to int."; @@ -685,10 +707,10 @@ rec { readPathsFromFile = lib.warn "lib.readPathsFromFile is deprecated, use a list instead" (rootPath: file: let - lines = lib.splitString "\n" (builtins.readFile file); + lines = lib.splitString "\n" (readFile file); removeComments = lib.filter (line: line != "" && !(lib.hasPrefix "#" line)); relativePaths = removeComments lines; - absolutePaths = builtins.map (path: rootPath + "/${path}") relativePaths; + absolutePaths = map (path: rootPath + "/${path}") relativePaths; in absolutePaths); @@ -702,7 +724,7 @@ rec { fileContents ./version => "1.0" */ - fileContents = file: removeSuffix "\n" (builtins.readFile file); + fileContents = file: removeSuffix "\n" (readFile file); /* Creates a valid derivation name from a potentially invalid one. @@ -720,13 +742,13 @@ rec { sanitizeDerivationName = string: lib.pipe string [ # Get rid of string context. This is safe under the assumption that the # resulting string is only used as a derivation name - builtins.unsafeDiscardStringContext + unsafeDiscardStringContext # Strip all leading "." - (x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) + (x: elemAt (match "\\.*(.*)" x) 0) # Split out all invalid characters # https://github.com/NixOS/nix/blob/2.3.2/src/libstore/store-api.cc#L85-L112 # https://github.com/NixOS/nix/blob/2242be83c61788b9c0736a92bb0b5c7bbfc40803/nix-rust/src/store/path.rs#L100-L125 - (builtins.split "[^[:alnum:]+._?=-]+") + (split "[^[:alnum:]+._?=-]+") # Replace invalid character ranges with a "-" (concatMapStrings (s: if lib.isList s then "-" else s)) # Limit to 211 characters (minus 4 chars for ".drv") diff --git a/lib/types.nix b/lib/types.nix index dd287734388..1144c018b26 100644 --- a/lib/types.nix +++ b/lib/types.nix @@ -1,12 +1,62 @@ # Definitions related to run-time type checking. Used in particular # to type-check NixOS configurations. { lib }: -with lib.lists; -with lib.attrsets; -with lib.options; -with lib.trivial; -with lib.strings; + let + inherit (lib) + elem + flip + functionArgs + isAttrs + isBool + isDerivation + isFloat + isFunction + isInt + isList + isString + isStorePath + setFunctionArgs + toDerivation + toList + ; + inherit (lib.lists) + all + concatLists + count + elemAt + filter + foldl' + head + imap1 + last + length + tail + unique + ; + inherit (lib.attrsets) + attrNames + filterAttrs + hasAttr + mapAttrs + optionalAttrs + zipAttrsWith + ; + inherit (lib.options) + getFiles + getValues + mergeDefaultOption + mergeEqualOption + mergeOneOption + showFiles + showOption + ; + inherit (lib.strings) + concatMapStringsSep + concatStringsSep + escapeNixString + isCoercibleToString + ; inherit (lib.modules) mergeDefinitions; outer_types = -- cgit 1.4.1 From 9a4bed1a809b52626b3fa97095e4d96c67ab429e Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 20 Oct 2020 15:24:59 +0200 Subject: lib: Add lib.isFloat for consistency Unlike the other three is* functions in lib.trivial, it was only available as lib.trivial.isFloat --- lib/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index 78566cceae8..956055b70a8 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -65,7 +65,7 @@ let lessThan listToAttrs pathExists readFile replaceStrings seq stringLength sub substring tail; inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor - bitNot boolToString mergeAttrs flip mapNullable inNixShell min max + bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; inherit (self.fixedPoints) fix fix' converge extends composeExtensions -- cgit 1.4.1 From fe4a58eec078489878a3b64aceeaed5118f18f39 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Tue, 20 Oct 2020 16:34:15 +0200 Subject: lib: Add lib.trace for consistency This puts it among the trace* family of functions derived from it. --- lib/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index 956055b70a8..d2239d26ead 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -63,7 +63,7 @@ let deepSeq elem elemAt filter genericClosure genList getAttr hasAttr head isAttrs isBool isInt isList isString length lessThan listToAttrs pathExists readFile replaceStrings seq - stringLength sub substring tail; + stringLength sub substring tail trace; inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare -- cgit 1.4.1 From c3b35f21f78a3d23aaf40b70fe8865598ddc6729 Mon Sep 17 00:00:00 2001 From: Joe Hermaszewski Date: Wed, 11 Nov 2020 10:36:19 +0800 Subject: lib: Add composeManyExtensions --- lib/default.nix | 4 ++-- lib/fixed-points.nix | 11 ++++++++++- lib/tests/misc.nix | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index d2239d26ead..e3c1ed71346 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -5,7 +5,7 @@ */ let - inherit (import ./fixed-points.nix {}) makeExtensible; + inherit (import ./fixed-points.nix { inherit lib; }) makeExtensible; lib = makeExtensible (self: let callLibs = file: import file { lib = self; }; @@ -69,7 +69,7 @@ let importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; inherit (self.fixedPoints) fix fix' converge extends composeExtensions - makeExtensible makeExtensibleWithCustomName; + composeManyExtensions makeExtensible makeExtensibleWithCustomName; inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath getAttrFromPath attrVals attrValues getAttrs catAttrs filterAttrs filterAttrsRecursive foldAttrs collect nameValuePair mapAttrs diff --git a/lib/fixed-points.nix b/lib/fixed-points.nix index 968930526a6..f998bc74e1d 100644 --- a/lib/fixed-points.nix +++ b/lib/fixed-points.nix @@ -1,4 +1,4 @@ -{ ... }: +{ lib, ... }: rec { # Compute the fixed point of the given function `f`, which is usually an # attribute set that expects its final, non-recursive representation as an @@ -77,6 +77,15 @@ rec { super' = super // fApplied; in fApplied // g self super'; + # Compose several extending functions of the type expected by 'extends' into + # one where changes made in preceding functions are made available to + # subsequent ones. + # + # composeManyExtensions : [packageSet -> packageSet -> packageSet] -> packageSet -> packageSet -> packageSet + # ^final ^prev ^overrides ^final ^prev ^overrides + composeManyExtensions = + lib.foldr (x: y: composeExtensions x y) (self: super: {}); + # Create an overridable, recursive attribute set. For example: # # nix-repl> obj = makeExtensible (self: { }) diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 6175f15819a..35a5801c724 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -87,6 +87,26 @@ runTests { expected = true; }; + testComposeManyExtensions0 = { + expr = let obj = makeExtensible (self: { foo = true; }); + emptyComposition = composeManyExtensions []; + composed = obj.extend emptyComposition; + in composed.foo; + expected = true; + }; + + testComposeManyExtensions = + let f = self: super: { bar = false; baz = true; }; + g = self: super: { bar = super.baz or false; }; + h = self: super: { qux = super.bar or false; }; + obj = makeExtensible (self: { foo = self.qux; }); + in { + expr = let composition = composeManyExtensions [f g h]; + composed = obj.extend composition; + in composed.foo; + expected = (obj.extend (composeExtensions f (composeExtensions g h))).foo; + }; + testBitAnd = { expr = (bitAnd 3 10); expected = 2; -- cgit 1.4.1 From a6218c058b3e994779147dd7286606c750be7d73 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Wed, 18 Nov 2020 12:12:34 -0500 Subject: lib: Create `makeScopeWithSplicing` It's ugly as hell, but I suppose it is needed to codify how to make spliced package sets. --- lib/customisation.nix | 27 +++++++++++++++++++++++++++ lib/default.nix | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'lib/default.nix') diff --git a/lib/customisation.nix b/lib/customisation.nix index dc5dd769197..37a7951896b 100644 --- a/lib/customisation.nix +++ b/lib/customisation.nix @@ -217,4 +217,31 @@ rec { }; in self; + /* Like the above, but aims to support cross compilation. It's still ugly, but + hopefully it helps a little bit. */ + makeScopeWithSplicing = splicePackages: newScope: otherSplices: keep: f: + let + spliced = splicePackages { + pkgsBuildBuild = otherSplices.selfBuildBuild; + pkgsBuildHost = otherSplices.selfBuildHost; + pkgsBuildTarget = otherSplices.selfBuildTarget; + pkgsHostHost = otherSplices.selfHostHost; + pkgsHostTarget = self; # Not `otherSplices.selfHostTarget`; + pkgsTargetTarget = otherSplices.selfTargetTarget; + } // keep self; + self = f self // { + newScope = scope: newScope (spliced // scope); + callPackage = newScope spliced; # == self.newScope {}; + # N.B. the other stages of the package set spliced in are *not* + # overridden. + overrideScope = g: makeScopeWithSplicing + splicePackages + newScope + otherSplices + keep + (lib.fixedPoints.extends g f); + packages = f; + }; + in self; + } diff --git a/lib/default.nix b/lib/default.nix index e3c1ed71346..f985266ed93 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -101,7 +101,7 @@ let noDepEntry fullDepEntry packEntry stringAfter; inherit (self.customisation) overrideDerivation makeOverridable callPackageWith callPackagesWith extendDerivation hydraJob - makeScope; + makeScope makeScopeWithSplicing; inherit (self.meta) addMetaAttrs dontDistribute setName updateName appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio hiPrioSet; -- cgit 1.4.1 From 41e13149f72bf1a5ef6a0f9b1da7c1c31cbc108a Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Sun, 24 Jan 2021 11:33:41 +0100 Subject: lib/debug: add traceFnSeqN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Immensely helpful when you want to see the changes a function makes to its value as it passes through. Example: ``` $ nix-instantiate --strict --eval -E '(with import ./lib; traceFnSeqN 2 "id" (x: x) { a.b.c = 3; })' trace: { fn = "id"; from = { a = { b = {…}; }; }; to = { a = { b = {…}; }; }; } { a = { b = { c = 3; }; }; } ``` --- lib/debug.nix | 22 ++++++++++++++++++++++ lib/default.nix | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'lib/default.nix') diff --git a/lib/debug.nix b/lib/debug.nix index ea6aed60ab4..e3ca3352397 100644 --- a/lib/debug.nix +++ b/lib/debug.nix @@ -148,6 +148,28 @@ rec { /* A combination of `traceVal` and `traceSeqN`. */ traceValSeqN = traceValSeqNFn id; + /* Trace the input and output of a function `f` named `name`, + both down to `depth`. + + This is useful for adding around a function call, + to see the before/after of values as they are transformed. + + Example: + traceFnSeqN 2 "id" (x: x) { a.b.c = 3; } + trace: { fn = "id"; from = { a.b = {…}; }; to = { a.b = {…}; }; } + => { a.b.c = 3; } + */ + traceFnSeqN = depth: name: f: v: + let res = f v; + in lib.traceSeqN + (depth + 1) + { + fn = name; + from = v; + to = res; + } + res; + # -- TESTING -- diff --git a/lib/default.nix b/lib/default.nix index f985266ed93..803f1f76564 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -130,7 +130,7 @@ let assertMsg assertOneOf; inherit (self.debug) addErrorContextToAttrs traceIf traceVal traceValFn traceXMLVal traceXMLValMarked traceSeq traceSeqN traceValSeq - traceValSeqFn traceValSeqN traceValSeqNFn traceShowVal + traceValSeqFn traceValSeqN traceValSeqNFn traceFnSeqN traceShowVal traceShowValMarked showVal traceCall traceCall2 traceCall3 traceValIfNot runTests testAllTrue traceCallXml attrNamesToStr; inherit (self.misc) maybeEnv defaultMergeArg defaultMerge foldArgs -- cgit 1.4.1 From 123045a57056b997165be4963cbf62120a967fec Mon Sep 17 00:00:00 2001 From: Jacek Galowicz Date: Mon, 25 Jan 2021 16:59:46 +0100 Subject: lib/attrsets: add cartesianProductOfSets function --- doc/functions/library/attrsets.xml | 39 ++++++++++++++++++++++ lib/attrsets.nix | 19 ++++++++++- lib/default.nix | 2 +- lib/tests/misc.nix | 67 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 125 insertions(+), 2 deletions(-) (limited to 'lib/default.nix') diff --git a/doc/functions/library/attrsets.xml b/doc/functions/library/attrsets.xml index 3c5823c2589..7ef0d16624c 100644 --- a/doc/functions/library/attrsets.xml +++ b/doc/functions/library/attrsets.xml @@ -1711,4 +1711,43 @@ recursiveUpdate +
+ <function>lib.attrsets.cartesianProductOfSets</function> + + cartesianProductOfSets :: AttrSet -> [ AttrSet ] + + + + + + Return the cartesian product of attribute set value combinations. + + + + + + set + + + + An attribute set with attributes that carry lists of values. + + + + + + + Creating the cartesian product of a list of attribute values + [ + { a = 1; b = 10; } + { a = 1; b = 20; } + { a = 2; b = 10; } + { a = 2; b = 20; } + ] +]]> + +
+ diff --git a/lib/attrsets.nix b/lib/attrsets.nix index d91d7a0cd47..0ce3aaeca45 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -183,6 +183,24 @@ rec { else []; + /* Return the cartesian product of attribute set value combinations. + + Example: + cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; } + => [ + { a = 1; b = 10; } + { a = 1; b = 20; } + { a = 2; b = 10; } + { a = 2; b = 20; } + ] + */ + cartesianProductOfSets = attrsOfLists: + lib.foldl' (listOfAttrs: attrName: + concatMap (attrs: + map (listValue: attrs // { ${attrName} = listValue; }) attrsOfLists.${attrName} + ) listOfAttrs + ) [{}] (attrNames attrsOfLists); + /* Utility function that creates a {name, value} pair as expected by builtins.listToAttrs. @@ -493,5 +511,4 @@ rec { zipWithNames = zipAttrsWithNames; zip = builtins.trace "lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith; - } diff --git a/lib/default.nix b/lib/default.nix index 803f1f76564..50320669e28 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -78,7 +78,7 @@ let zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil recursiveUpdate matchAttrs overrideExisting getOutput getBin getLib getDev getMan chooseDevOutputs zipWithNames zip - recurseIntoAttrs dontRecurseIntoAttrs; + recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets; inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1 concatMap flatten remove findSingle findFirst any all count optional optionals toList range partition zipListsWith zipLists diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 35a5801c724..0d249968402 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -660,4 +660,71 @@ runTests { expected = [ [ "foo" ] [ "foo" "" "bar" ] [ "foo" "bar" ] ]; }; + testCartesianProductOfEmptySet = { + expr = cartesianProductOfSets {}; + expected = [ {} ]; + }; + + testCartesianProductOfOneSet = { + expr = cartesianProductOfSets { a = [ 1 2 3 ]; }; + expected = [ { a = 1; } { a = 2; } { a = 3; } ]; + }; + + testCartesianProductOfTwoSets = { + expr = cartesianProductOfSets { a = [ 1 ]; b = [ 10 20 ]; }; + expected = [ + { a = 1; b = 10; } + { a = 1; b = 20; } + ]; + }; + + testCartesianProductOfTwoSetsWithOneEmpty = { + expr = cartesianProductOfSets { a = [ ]; b = [ 10 20 ]; }; + expected = [ ]; + }; + + testCartesianProductOfThreeSets = { + expr = cartesianProductOfSets { + a = [ 1 2 3 ]; + b = [ 10 20 30 ]; + c = [ 100 200 300 ]; + }; + expected = [ + { a = 1; b = 10; c = 100; } + { a = 1; b = 10; c = 200; } + { a = 1; b = 10; c = 300; } + + { a = 1; b = 20; c = 100; } + { a = 1; b = 20; c = 200; } + { a = 1; b = 20; c = 300; } + + { a = 1; b = 30; c = 100; } + { a = 1; b = 30; c = 200; } + { a = 1; b = 30; c = 300; } + + { a = 2; b = 10; c = 100; } + { a = 2; b = 10; c = 200; } + { a = 2; b = 10; c = 300; } + + { a = 2; b = 20; c = 100; } + { a = 2; b = 20; c = 200; } + { a = 2; b = 20; c = 300; } + + { a = 2; b = 30; c = 100; } + { a = 2; b = 30; c = 200; } + { a = 2; b = 30; c = 300; } + + { a = 3; b = 10; c = 100; } + { a = 3; b = 10; c = 200; } + { a = 3; b = 10; c = 300; } + + { a = 3; b = 20; c = 100; } + { a = 3; b = 20; c = 200; } + { a = 3; b = 20; c = 300; } + + { a = 3; b = 30; c = 100; } + { a = 3; b = 30; c = 200; } + { a = 3; b = 30; c = 300; } + ]; + }; } -- cgit 1.4.1 From 81e1e68eaf6c765147da964d356f704030734dd2 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Tue, 27 Apr 2021 10:56:51 +0000 Subject: lib.trivial.warnIf: init It's a common pattern in Nixpkgs to want to emit a warning in certain cases, but not actually change behaviours. This is often expressed as either if cond then lib.warn "Don't do that thing" x else x Or (if cond then lib.warn "Don't do that thing" else lib.id) x Neither of which really expresses the intent here, because it looks like 'x' is being chosen conditionally. To make this clearer, I introduce a "warnIf" function, which makes it clear that the only thing being affected by the condition is whether the warning is generated, not the value being returned. --- lib/default.nix | 5 +++-- lib/trivial.nix | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index 50320669e28..ccae0bbc3ab 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -66,8 +66,9 @@ let stringLength sub substring tail trace; inherit (self.trivial) id const pipe concat or and bitAnd bitOr bitXor bitNot boolToString mergeAttrs flip mapNullable inNixShell isFloat min max - importJSON importTOML warn info showWarnings nixpkgsVersion version mod compare - splitByAndCompare functionArgs setFunctionArgs isFunction toHexString toBaseDigits; + importJSON importTOML warn warnIf info showWarnings nixpkgsVersion version + mod compare splitByAndCompare functionArgs setFunctionArgs isFunction + toHexString toBaseDigits; inherit (self.fixedPoints) fix fix' converge extends composeExtensions composeManyExtensions makeExtensible makeExtensibleWithCustomName; inherit (self.attrsets) attrByPath hasAttrByPath setAttrByPath diff --git a/lib/trivial.nix b/lib/trivial.nix index be6d0115f5b..f6f5da5998f 100644 --- a/lib/trivial.nix +++ b/lib/trivial.nix @@ -297,12 +297,15 @@ rec { # Usage: # { # foo = lib.warn "foo is deprecated" oldFoo; + # bar = lib.warnIf (bar == "") "Empty bar is deprecated" bar; # } # # TODO: figure out a clever way to integrate location information from # something like __unsafeGetAttrPos. warn = msg: builtins.trace "warning: ${msg}"; + warnIf = cond: msg: if cond then warn msg else id; + info = msg: builtins.trace "INFO: ${msg}"; showWarnings = warnings: res: lib.fold (w: x: warn w x) res warnings; -- cgit 1.4.1 From 8fb9984690c878fcd768e967190957441de05d11 Mon Sep 17 00:00:00 2001 From: Janne Heß Date: Sun, 6 Jun 2021 20:41:37 +0200 Subject: lib/modules: Drop mkStrict and mkFixStrictness This was deprecated in 2014 and is not used anywhere in the tree. --- lib/default.nix | 4 ++-- lib/modules.nix | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index ccae0bbc3ab..ccfee2ebe30 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -115,8 +115,8 @@ let mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions pushDownProperties dischargeProperties filterOverrides sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride - mkOptionDefault mkDefault mkForce mkVMOverride mkStrict - mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions + mkOptionDefault mkDefault mkForce mkVMOverride + mkOrder mkBefore mkAfter mkAliasDefinitions mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule mkAliasOptionModule doRename; diff --git a/lib/modules.nix b/lib/modules.nix index 99b9a8a31ea..58c6cda58e4 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -713,10 +713,6 @@ rec { mkForce = mkOverride 50; mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’ - mkStrict = builtins.trace "`mkStrict' is obsolete; use `mkOverride 0' instead." (mkOverride 0); - - mkFixStrictness = id; # obsolete, no-op - mkOrder = priority: content: { _type = "order"; inherit priority content; -- cgit 1.4.1 From 99bc203025a0ff1265eedc6ff3d6c7aa1f320c09 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Mon, 12 Jul 2021 07:23:45 +0200 Subject: Partially revert "lib/modules: Drop mkStrict and mkFixStrictness" mkFixStrictness was never properly deprecated and should only be removed after warning for some time. This partially reverts commit 8fb9984690c878fcd768e967190957441de05d11. --- lib/default.nix | 4 ++-- lib/modules.nix | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index ccfee2ebe30..ccae0bbc3ab 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -115,8 +115,8 @@ let mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions pushDownProperties dischargeProperties filterOverrides sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride - mkOptionDefault mkDefault mkForce mkVMOverride - mkOrder mkBefore mkAfter mkAliasDefinitions + mkOptionDefault mkDefault mkForce mkVMOverride mkStrict + mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule mkAliasOptionModule doRename; diff --git a/lib/modules.nix b/lib/modules.nix index 58c6cda58e4..99b9a8a31ea 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -713,6 +713,10 @@ rec { mkForce = mkOverride 50; mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’ + mkStrict = builtins.trace "`mkStrict' is obsolete; use `mkOverride 0' instead." (mkOverride 0); + + mkFixStrictness = id; # obsolete, no-op + mkOrder = priority: content: { _type = "order"; inherit priority content; -- cgit 1.4.1 From cad20d8983a547c19e914ec5a2a6093b0c8e5a16 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Mon, 12 Jul 2021 07:31:20 +0200 Subject: lib.mkFixStrictness: Deprecate --- lib/default.nix | 2 +- lib/modules.nix | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index ccae0bbc3ab..8e29ef5c420 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -115,7 +115,7 @@ let mergeModules' mergeOptionDecls evalOptionValue mergeDefinitions pushDownProperties dischargeProperties filterOverrides sortProperties fixupOptionType mkIf mkAssert mkMerge mkOverride - mkOptionDefault mkDefault mkForce mkVMOverride mkStrict + mkOptionDefault mkDefault mkForce mkVMOverride mkFixStrictness mkOrder mkBefore mkAfter mkAliasDefinitions mkAliasAndWrapDefinitions fixMergeModules mkRemovedOptionModule mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule diff --git a/lib/modules.nix b/lib/modules.nix index 99b9a8a31ea..ab2bc4f7f8e 100644 --- a/lib/modules.nix +++ b/lib/modules.nix @@ -713,9 +713,7 @@ rec { mkForce = mkOverride 50; mkVMOverride = mkOverride 10; # used by ‘nixos-rebuild build-vm’ - mkStrict = builtins.trace "`mkStrict' is obsolete; use `mkOverride 0' instead." (mkOverride 0); - - mkFixStrictness = id; # obsolete, no-op + mkFixStrictness = lib.warn "lib.mkFixStrictness has no effect and will be removed. It returns its argument unmodified, so you can just remove any calls." id; mkOrder = priority: content: { _type = "order"; -- cgit 1.4.1